Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BASIC CODE #14

Open
JungHulk opened this issue May 7, 2024 · 0 comments
Open

BASIC CODE #14

JungHulk opened this issue May 7, 2024 · 0 comments

Comments

@JungHulk
Copy link
Owner

JungHulk commented May 7, 2024

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier

from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score

import warnings
warnings.filterwarnings('ignore')
warnings.simplefilter(action='ignore',catagory=FutureWarning)

train_test_split에서 생각해야할 점

x 데이터 셋에는 종속 변수 제거 후 저장. 즉, 우리가 예측할 값이 있을때 그 열을 제외한 것만 저장
y 데이터 셋에는 종속변수만 저장. 즉, 우리가 예측해야 할 값
최종적으로 x_train, x_test, y_train, y_test 의 학습셋과 시험셋을 분리
train_test_split(x, y, test_size=0.2, random_state=100), test set을 train 의 20퍼로 하겠다는 뜻. 보통은 validation 으로 사용하지요?

  1. 불러오기
    train=pd.read_csv('./train.csv').drop(columns=['ID'])
    train_x=train.drop(columns=['Class'])
    train_y=train['Class']

test_x=pd.read_csv('./test.csv').drop(columns=['ID'])

  1. EDA

2-1) 데이터 분석 이전 데이터 형태 살펴보기 (데이터 자료형과 통계량 확인)

데이터 형태 살펴보기,int(정수형), float(실수형), object(범주형)

trian_x_info()

각 변수들의 데이터 통계량 살펴보기

train_describe()

#2-2) 데이터 시각화 - 상관관계 보여주는 pairplot, 연속형 변수 보여주는 distplot, 그리고 범주형 변수 빈도 보여주는 countplot
plt.figure(figsize=(15,15))
sns.pairplot(train)
plt.show()

#위의 그래프를 뽑았을때 범주형 변수는 한줄로 뚜두ㅜㄷ두 될거임

distplot과 countplot을 통해 데이터의 분포도를 보여준다

범주형과 연속형 변수 잘 보고 plot 하기

fig,axes =plt.subplots(4, 3, figsize=(20,20))
sns.displot(x=train_x['CT'], ax=axes[0][0]).set_title('CT')
sns.countplot(x=train_x['E_status'], ax=axes[2][0]).set_title('E_status')

plt.show()

이를 통해 분포가 가운데에 쏠리는 친구는 나중에 Minmaxscalar, 한쪽에 몰려있으면 Standardscalar

2-3) 다중공선성과 상관관계 확인

분산팽창계수(vif) 구하고, 히트맵 사용하여 각 변수간의 상관계수 시각적으로 확인

vif >10 인 경우 다중공선성 있다고 간주, 상관계수 높은 변수 하나 제거 or 주성분분석(PCA) 와 같은 차원 축소 기법 활용

from statsmodels.stats.outliners_influence import variance_inflation_facotr
feature=train_x.drop(columns=['Inhibit']) #inhibit은 범주형이라 vif 계산에 들어가면 안됨.

vif=pd.DataFrame()
vif['VIF Factor']=[variacne_inflation_factor(feature.values, i) for i in range(feature.shape[1])]
vif['features']=feature.columns
picked=list(vif[cif['VIF Facor']>10.features)
print(picked)
vif

#히트맵 그리기
temp=train.corr()
fig, ax=plt.subplots(figsize=(20,20))

mask=np.zeros_like(tempt)
mask[np.triu_indices_from(mask)]=True

sns.heatmap(temps,
cmap='RbYlBu-r',
annot=True,
mask=mask,
linewidths=5,
sbar_kws=("shrink":.5),
vmin=-1, vmax=1)
plt.show()

  1. 데이터 전처리

학습데이터에 결측치가 있는지 확인한다.

for col in train_x.columns:
col_by_null=train_x[col].isnull().sum()
print(f'Columns:[{col}] 결측치 개수: [{col_by_null}]')
if col_by_null>0:
#학습 데이터의 해당 column 에 결측치가 1개 이상 존재하는경우
#학습 데이터의 해당 column의 평균으로 결측치 대체 -> why? 변수들의 분포가 중앙으로 몰려있기 때문, -> 만약 중앙으로 안몰려있으면?
train_x[col]=train_x[col].fillna(train_x[col].mean())
# 테스트 데이터 역시 결측값이 있을수 있기 때문에 평균값으로 대체하되, 학습데이터의 통계량을 사용해 Data leakage를 prevent
test_x[col]=test_x[col].fillna(train_x[col].mean())
print('결측치 대체 완료')

else:
    print('결측치 없음')

3. 데이터 전처리, 범주형->숫자형으로 바꾸기

from sklearn.preprocessing import LabelEncoder

qual_col=['Inhibit']
for i in qual_col:
le=LabelEncoder()
le-le.fit(train_x[i])
train_x[i]=le.transform(train_x[i)

for label in np.unique(test_x[i]):
    if label not in le.classes_:
        le.classes=np.append(le.classes_, label)
# 단, 테스트 데이터로 label encoder를 fit한 후 transform을 수행하는 것은 data leakage에 해당하므로 무조건 학습 데이터로 fit 해야한다.
test_x[i]=le.transform(test_x[i])

#인사이트: 변수선택 -> vif 높은 변수 제거하기, using drop(), 따라서 이제 범주형은 inhibit만 남음
train_x=train_x.drop(columns=['Long_Accel'])
test_x=test_x.drop(columns=['Long_Accel'])

#원핫인코딩: 범주형 변수간 순서를 인코딩 했을때 생기는 순서 문제를 해결, by get_dummies

from sklearn.preprocessing import OneHotEncoder
ohe=OneHotEncoder()

위의 방법보다 pandas을 통해 데이터 프레임 형식으로 반환 받는것이 더 좋음

train_x=pd.get_dummies(train_x, columns=['Inhibit', 'E_status'])
test_x=pd.get_dummies(test_x, columns=['Inhibit', 'E_status'])

#train_x.columns, test_x.columns 으로 제대로 인코딩 되었는지 확인

#스케일링: 다차원의 값들을 비교분석하기 쉽게 만들어 자료의 오버플로우/언더플로우 방지
#MinMaxscaler: 최솟값을 0, 최댓값을 1로 변환 (중앙으로 몰려있을때), Standard: 평균과 표준편차 이용(한쪽으로 쏠려있을때)
from sklearn.preprocessing import MinMaxScaler, StandardScaler

minmax_scaler=MinMaxScaler()
standard_scaler=StandardScaler()

scaled_train_x=train_x.copy()
scaled_train_x['a','b','c']=minmax_scaler.fit_transform(train_x[['a','b','c']])
scaled_train_x['e','f','g']=standard_scaler.fit_transform(train_x[['e','f','g']])

scaled_test_x=test_x_copy()
scaled_test_x['a','b','c']=minmax_scaler.fit_transform(test_x[['a','b','c']])
scaled_test_x['e','f','g']=standard_scaler.fit_transform(test_x[['e','f','g']])

  1. 분석모델 설계
    [예시] X=data.drop('Survived', axis=1) Y=data['Survived'] X_train, X_test, Y_train, Y_test=train_test_split(X,Y, test_size=0.2, random_state=100) #학습셋, 시험셋 준비 model=LogisticRegression() # 모델 생성 model.fit(X_train,Y_train) # 학습 pred=model.predict(X_test) # 에측 accuracy_score(y_test, pred) # 정확도 계산

lr=LinearRegression()
rf=RandomForestRegressor()
et=ExtraTreeRegressor()
xgb=XGBregressor()
lgbm=LGBMRegressor()

#성능 평가를 위해 train의 20퍼센트를 validation set 으로 만든다.
train_x_splited, val_x, train_y_splited, val_y=train_test_split(scaled_train_x, test_size=0.2, random_state=0)

lr.fit(train_x_splited, train_y_splited)
lr_pred=lr.predicted(val_x)
print('Linear Regression 모델의 MAE: mean_absolute_error[val_y, lr_pred])

이걸 lr, rf, et, wgb, lgbm 에 적용하여 각각의 mae를 계산한다. 가장 높은 값이 나온 모델을 선정하여, 하이퍼파라미터를 튜닝한다.

accuracy_score(val_y, rf_pred) 사용하면 정확도를 구할 수 있다.

#GridSearchCv
#일반적으로 모델의 성능에 직접적인 영향을 주는 파라미터는 n_estimators, 100에서 2000사이로 변경하면서 모델의 성능을 측정

#param_grid는 적용하고 싶은 파라미터를 적으면 된다.
param_grid=[
{'n_estimators':[100], #여러개로 비교하고 싶다면 [100,200,100,2000]
'min_samples_leaf':[1],
'ramdom_state':[0,23,37,42]}

grid_search=GridSearchCV(et,
param_grid,
cv=3, #주어진 데이터셋을 몇개로 나눌 것인가. cv 검증을 위한 분할 검증 횟수
scoring='neg_mean_absolute_error', #neg_root_mean_squared_error 써도 됨
return_train_score=True,
n_jobs=1)
grid_search.fit(scaled_train_x, train_y)
print('최적의 하이퍼 파라미터:', grid_search.best_params_)

<하이퍼파라미터 튜닝은 어떻게 하는가> n_estimators=[100] num_leaves:[100] learning_rate-:[0.01,0.05,0.1] max_depth:[-1,5,15] -> scoring을 accuracy로 했을때 최적의 파라미터가 0.05, -1, 100,100 이 나왔다고 했을때 learning rate과 max_depth 고정 후 n_estimators 랑 num_leaves 을 탐색한다.

먼저 넓은 값을 탐색
n_estimator:[100,200,300,400], num_leaves:[100,200,300,400] 어디 사이에서 값이 나오는지 확인. 이후 범위를 더 좁힌다. (25씩 5개 앞뒤로)
세번만 하면 완성시킬 수 있을듯.

  1. 모델 학습
    et=ExtraTreeRegression(**grid_search.best_params_) # 로지스틱 회귀 모델 생성
    et.fit(scaled_train_x, train_y) # 모델 학습

  2. 예측값 생성
    pred=et.predict(scaled_test_x)

#이때 앙상블을 할 수 있음. 앙상블 기법 중 하나인 하드보팅은 모델의 예측결과(et, rf)를 더한 값을 나눠 평균 취함
#mean=(et_pred+rf_pred)/2

  1. 제출파일 생성
    submission=pd.read_csv('./sample_submission.csv')
    submission.head(5)

submission('HR')=rf_clf_pred/4
submisison.head(5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant