JungHulk / Hulk-Engineering

1 stars 0 forks source link

BASIC CODE #14

Open JungHulk opened 6 months ago

JungHulk commented 6 months ago

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.bestparams)

<하이퍼파라미터 튜닝은 어떻게 하는가> 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.bestparams) # 로지스틱 회귀 모델 생성 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)