yangwonsuck / PROJECT_CODE

0 stars 0 forks source link

타이타닉 생존자 예측-중급과정 #2

Open yangwonsuck opened 3 years ago

yangwonsuck commented 3 years ago

import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn import preprocessing from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score from sklearn.model_selection import GridSearchCV %matplotlib inline

titanic_df=pd.read_csv('titanic_train.csv') titanic_df.head(3) print('\n ### 학습 데이터 정보 ### \n') print(titanic_df.info())

NULL값이 있는 컬럼을 평균 또는 고정 값으로 변경

titanic_df['Age'].fillna(titanic_df['Age'].mean(),inplace=True) titanic_df['Cabin'].fillna('N',inplace=True) titanic_df['Embarked'].fillna('N',inplace=True) print('데이터 세트 Null 값 개수 ',titanic_df.isnull().sum().sum())

현재 남아있는 문자열 피처 Sex,Cabin,Embarked

print(' Sex 값 분포 :\n',titanic_df['Sex'].value_counts()) print('\n Cabin 값 분포 :\n',titanic_df['Cabin'].value_counts()) #문자열 값이 불명확하게 나뉨 print('\n Embarkded 값 분포 :\n',titanic_df['Embarked'].value_counts())

titanic_df['Cabin']=titanic_df['Cabin'].str[:1] print(titanic_df['Cabin'].head(3)) titanic_df.groupby(['Sex','Survived'])['Survived'].count() #남녀간 살아남은 총 카운트 출력

남녀간 살아남은 값 그래프로 출력

sns.barplot(x='Sex',y='Survived',data=titanic_df)

부자와 가난한 사람간의 생존 확률

sns.barplot(x='Pclass',y='Survived',hue='Sex',data=titanic_df)

나이에 따라 상태를 알려주는 함수

def get_category(age): cat='' if age <= -1: cat='Unknown' elif age <=5: cat='Baby' elif age <=12: cat='Child' elif age <=18: cat='Teenager' elif age <=25: cat='Student' elif age <=35: cat='Young Adult' elif age <=60: cat='Adult' else: cat='Elderly'

return cat

문자열 카테고리 피처를 숫자형 카테고리 피처로 변환하는 함수

def encode_features(dataDF): features=['Cabin','Sex','Embarked'] for feature in features: le=preprocessing.LabelEncoder() le=le.fit(dataDF[feature]) dataDF[feature]=le.transform(dataDF[feature])

return dataDF

Null 처리 함수

def fillna(df): df['Age'].fillna(df['Age'].mean(),inplace=True) df['Cabin'].fillna('N',inplace=True) df['Embarked'].fillna('N',inplace=True) df['Fare'].fillna(0,inplace=True) return df

머신러닝 알고리즘에 불필요한 속성 제거

def drop_features(df): df.drop(['PassengerId','Name','Ticket'],axis=1,inplace=True) return df

레이블 인코딩 수행

def format_features(df): df['Cabin']=df['Cabin'].str[:1] features=['Cabin','Sex','Embarked'] for feature in features: le=LabelEncoder() le=le.fit(df[feature]) df[feature]=le.transform(df[feature]) return df

앞에서 설정한 데이터 전처리 함수 호출

def transform_features(df): df=fillna(df) df=drop_features(df) df=format_features(df) return df

교차 검증으로 결정 트리 모델을 평가하기 위한 함수

def exec_kfold(clf,folds=5):

폴드 세트를 5개인 KFold 객체를 생성,폴드 수만큼 예측결과 저장을 위한 리스트 객체 생성.

kfold=KFold(n_splits=folds)
scores=[]

#KFold 교차 검증 수행
for iter_count, (train_index, test_index) in enumerate(kfold.split(X_titanic_df)):
    #X_titanic_df 데이터에서 교차 검증별로 학습과 검증 데이터를 가리키는 index생성
    X_train,X_test=X_titanic_df.values[train_index],X_titanic_df.values[test_index]
    y_train,y_test=y_titanic_df.values[train_index],y_titanic_df.values[test_index]
    #Classifier 학습,예측,정확도 계산
    clf.fit(X_train,y_train)
    predictions=clf.predict(X_test)
    accuracy=accuracy_score(y_test,predictions)
    scores.append(accuracy)
    print("교차 검증 {0} 정확도: {1:.4f}".format(iter_count,accuracy))

#5개 fold에서의 평균 정확도 계산.
mean_score=np.mean(scores)
print("평균 정확도: {0:.4f}".format(mean_score))

exec_kfold 호출

exec_kfold(dt_clf,folds=5)

막대그래프의 크기 figure를 더 크게 설정

plt.figure(figsize=(10,6))

X축의 값을 순차적으로 표시하기 위한 설정

group_names=['Unknown','Baby','Child','Teenager','Student','Young Adult','Adult','Elderly']

lambda 식에 위에서 생성한 get_category() 함수를 반환값으로 지정

get_category(X)는 입력값으로 'Age' 컬럼 값을 받아서 해당하는 cat 반환

titanic_df['Age_cat']=titanic_df['Age'].apply(lambda x:get_category(x)) sns.barplot(x='Age_cat',y='Survived',hue='Sex',data=titanic_df,order=group_names) titanic_df.drop('Age_cat',axis=1,inplace=True)

titanic_df=encode_features(titanic_df) titanic_df.head()

원본 데이터를 재로딩하고, 피처 데이터 세트와 레이블 데이터 세트 추출

titanic_df=pd.read_csv('titanic_train.csv') y_titanic_df=titanic_df['Survived'] X_titanic_df=titanic_df.drop('Survived',axis=1)

X_titanic_df=transform_features(X_titanic_df)

X_train,X_test,y_train,y_test=train_test_split(X_titanic_df,y_titanic_df,test_size=0.2,random_state=11)

결정트리, Random Forest, 로지스틱 회귀를 위한 사이킷런 Classifier 클래스 생성

dt_clf=DecisionTreeClassifier(random_state=11) rf_clf=RandomForestClassifier(random_state=11) lr_clf=LogisticRegression()

DecisionTreelassifier 학습/예측/평가

dt_clf.fit(X_train,y_train) dt_pred=dt_clf.predict(X_test) print('DecisionTreeClassifier 정확도:{0:.4f}'.format(accuracy_score(y_test,dt_pred)))

RandomForestClassifier 학습/예측/평가

rf_clf.fit(X_train,y_train) rf_pred=rf_clf.predict(X_test) print('RandomForestClassifier 정확도:{0:.4f}'.format(accuracy_score(y_test,rf_pred)))

LogisticRegression 학습/예측/평가

lr_clf.fit(X_train,y_train) lr_pred=lr_clf.predict(X_test) print('LogisticRegression 정확도: {0:.4f}'.format(accuracy_score(y_test,lr_pred)))

교차 검증을 cross_val_score() API를 이용

scores=cross_val_score(dt_clf,X_titanic_df,y_titanic_df,cv=5) for iter_count,accuracy in enumerate(scores): print("교차 검증 {0} 정확도:{1:.4f}".format(iter_count,accuracy))

print("평균 정확도: {0:.4f}".format(np.mean(scores)))

GridSearchCV를 이용해 DecisionTreeClassifier의 최적 하이퍼 파라미터를 찾고 예측성능 측정

parameters={'max_depth':[2,3,5,10],'min_samples_split':[2,3,5],'min_samples_leaf':[1,5,8]}

grid_dclf=GridSearchCV(dt_clf,param_grid=parameters,scoring='accuracy',cv=5) grid_dclf.fit(X_train,y_train)

print('GridSearchCV 최적 하이퍼 파라미터 :',grid_dclf.bestparams) print('GridSearchCV 최고 정확도: {0:.4f}'.format(grid_dclf.bestscore)) best_dclf=grid_dclf.bestestimator

GridSearchCV의 최적 하이퍼 파라미터로 학습된 Estimator로 예측 및 평가 수행

dpredictions=best_dclf.predict(X_test) accuracy=accuracy_score(y_test,dpredictions) print('테스트 세트에서의 DecisionTreeClassifier 정확도:{0:.4f}'.format(accuracy))

yangwonsuck commented 3 years ago

from sklearn.base import BaseEstimator import pandas as pd from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.datasets import load_digits import numpy as np from sklearn.metrics import confusion_matrix from sklearn.metrics import accuracy_score,precision_score,recall_score,confusion_matrix from sklearn.linear_model import LogisticRegression from sklearn.preprocessing import Binarizer

class MyFakeClassifier(BaseEstimator): def fit(self,X,y): pass

#입력값으로 들어오는 X 데이터 세트의 크기만큼 모두 0값으로 만들어서 반환
def predict(self,X):
    return np.zeros((len(X),1),dtype=bool)

class MyDummyClassifier(BaseEstimator):

fit() 메서드는 아무것도 학습하지 않음

def fit(self,X,y=None):
    pass
# predict () 메서드는 단순히 Sex 피처가 1이면 0, 그렇지 않으면 1로 예측함.
def predict(self,X):
    pred=np.zeros((X.shape[0],1))
    for i in range(X.shape[0]):
        if X['Sex'].iloc[i]==1:
            pred[i]=0
        else:
            pred[i]=1

    return pred

def get_clf_eval(y_test,pred): confusion=confusion_matrix(y_test,pred) accuracy=accuracy_score(y_test,pred) precision=precision_score(y_test,pred) recall=recall_score(y_test,pred) print('오차 행렬') print(confusion) print('정확도:{0:.4f},정밀도:{1:.4f},재현율:{2:.4f}'.format(accuracy,precision,recall))

원본 데이터를 재로딩, 데이터 가공, 학습 데이터/테스트 데이터 분할

titanic_df=pd.read_csv('titanic_train.csv') y_titanic_df=titanic_df['Survived'] X_titanic_df=titanic_df.drop('Survived',axis=1) X_titanic_df=transform_features(X_titanic_df) X_train,X_test,y_train,y_test=train_test_split(X_titanic_df,y_titanic_df,test_size=0.2,random_state=0)

위애서 생성한 Dummy Classifier를 이용해 학습/예측/평가 수행

myclf=MyDummyClassifier() myclf.fit(X_train,y_train)

mypredictions=myclf.predict(X_test) print('Dummy Classifier의 정확도는: {0:.4f}'.format(accuracy_score(y_test,mypredictions)))

사이킷런의 내장 데이터 세트인 load_digits()를 이용해 MNIST 데이터 로딩

digits=load_digits()

digits 번호가 7번이면 True이고 이를 astype(int)로 1로 변환,7번이 아니면 False이고 0으로 변환.

y=(digits.target==7).astype(int) X_train,X_test,y_train,y_test=train_test_split(digits.data,y,random_state=11)

불균형한 레이블 데이터 분포도 확인

print('레이블 테스트 세트 크기:',y_test.shape) print('테스트 세트 레이블 0과 1의 분포도') print(pd.Series(y_test).value_counts())

Dummy Classifier로 학습/예측/정확도 평가

fakeclf=MyFakeClassifier() fakeclf.fit(X_train,y_train) fakepred=fakeclf.predict(X_test) print('모든 예측을 0으로 하여도 정확도는:{:.3f}'.format(accuracy_score(y_test,fakepred)))

오차행렬을 구하는 값

confusion_matrix(y_test,fakepred)

원본 데이터를 재로딩, 데이터 가공,학습 데이터/테스트 데이터 분할

titanic_df=pd.read_csv('titanic_train.csv') y_titanic_df=titanic_df['Survived'] X_titanic_df=titanic_df.drop('Survived',axis=1) X_titanic_df=transform_features(X_titanic_df)

X_train,X_test,y_train,y_test=train_test_split(X_titanic_df,y_titanic_df,test_size=0.2,random_state=11)

lr_clf=LogisticRegression()

lr_clf.fit(X_train,y_train) pred=lr_clf.predict(X_test) get_clf_eval(y_test,pred)

pred_proba=lr_clf.predict_proba(X_test) pred=lr_clf.predict(X_test) print('pred_proba()결과 Shape: {0}'.format(pred_proba.shape)) print('pred_proba array에서 앞 3개만 샘플로 추출 \n:',pred_proba[:3])

예측 확률 array와 예측 결괏값 array를 병합(concatenate) 해 예측 확률과 결괏값을 한눈에 확인

pred_proba_result=np.concatenate([pred_proba,pred.reshape(-1,1)],axis=1) print('두 개의 class 중에서 더 큰 확률을 클래스 값으로 예측 \n',pred_proba_result[:3])

X=[[1,-1,2],[2,0,0],[0,1.1,1.2]]

X의 개별 원소들이 threshold값보다 같거나 작으면 0을, 크면 1을 반환

binarizer=Binarizer(threshold=1.1) print(binarizer.fit_transform(X))