본문 바로가기
  • 데이터에 가치를 더하다, 서영석입니다.
연구 활동/폐암 예측 프로젝트

[2022 동계인턴십] 암 예측

by 꿀먹은데이터 2022. 1. 10.

 

import pandas as pd
data=pd.read_csv('C:/Users/dudtj/OneDrive - 숭실대학교 - Soongsil University/Desktop/CL/python/동계인턴십_Data_1000/phenotype_1000.txt',engine="python",sep=" ")
print(data.info())

위 그림과 같이 null값이 데이터의 절반 이상을 차지하는 변수들이 있다. 데이터 보존을 위해 non-null값이 900 이상인 데이터들만 가져와 다시 df로 저장하였다. (1000개의 데이터이므로 90%만 뽑았다.)

이렇게 할 수 있는 이유는 drop시킨 변수들은 암 예측에 중요하지 않다고 판단한 변수들이었기 때문이다.

data.columns

 

df=data.loc[:,['AGE_B','SMOK_B','ALCO_B','ALCO_AMOUNT_B','EXER_B','HT_B','WT_B','WAIST_B','SBP_B','DBP_B','CHO_B','LDL_B','TG_B','HDL_B','FBS_B','GOT_B','GPT_B','GGT_B','URIC_B','BIL','WBC','CREAT','STOMA','COLON','LIVER','LUNG','PROST','THROI','BREAC','RECTM','SCOLON','SRECTM','SPROST','STHROI','SBREAC','SLUNG','SSTOMA','SLIVER','SEX1','CRC','SCRC']]
print(df.info())

이와 같이 null값이 많지 않은 변수들을 df에 저장한 뒤 dropna()함수를 통해 그 데이터를 날리고 검정을 하였다. 그 이유는 제거를 한 뒤 데이터의 양은 747개로 충분하다고 생각하여 이를 test와 train set으로 분리하여 진행하였다.

df.dropna(inplace=True)
print(df.isnull().sum())

from sklearn.preprocessing import LabelEncoder
def format_features(df):
    features=['STOMA','COLON','LIVER','LUNG','PROST','THROI','BREAC','RECTM']
    for feature in features:
        le=LabelEncoder()
        le=le.fit(df[feature])
        df[feature]=le.transform(df[feature])
    return df

features를 암종류로 놓고 y를 'LUNG'암으로 두고 X를 이 features를 제거한 변수로 둔 뒤 진행하였다.

features=['STOMA','COLON','LIVER','LUNG','PROST','THROI','BREAC','RECTM']
y_df =df['LUNG']
X_df =df.drop(features, axis=1)

train set과 test set의 비율은 8:2 비율로 진행하였다.

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X_df,y_df,test_size=0.2)
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
dt_clf = DecisionTreeClassifier()
rf_clf = RandomForestClassifier()
lr_clf = LogisticRegression()
#DecisionTreeClassifier 학습/예측/평가
dt_clf.fit(X_train,y_train)
dt_pred = dt_clf.predict(X_test)
print("DecisionTreeClassifier 정확도 :",accuracy_score(y_test,dt_pred))

#RandomForestClassifier 학습/예측/평가
rf_clf.fit(X_train,y_train)
rf_pred = rf_clf.predict(X_test)

print("RandomForestClassifier 정확도 :",accuracy_score(y_test,rf_pred))
#LogisticRegression 학습/예측/평가
lr_clf.fit(X_train,y_train)
lr_pred = lr_clf.predict(X_test)
print("LogisticRegression 정확도 :",accuracy_score(y_test,lr_pred))

위와 같이 DecisionTree나 RandomForest, LogisticRegression이 모두 95%보다 높은 정확도를 볼 수 있었다.

import numpy as np
from sklearn.model_selection import KFold
def exec_kfold(clf,folds=5):
    kfold=KFold(n_splits=folds)
    scores=[]

    for iter_count, (train_index, test_index) in enumerate(kfold.split(X_df)):
        X_train,X_test = X_df.values[train_index],X_df.values[test_index]
        y_train,y_test = y_df.values[train_index],y_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("교차 검증 정확도:",iter_count,accuracy)
    
    mean_score=np.mean(scores)
    print("평균 정확도:",mean_score)
exec_kfold(dt_clf,folds=5)

교차 검증을 통한 정확도 또한 95%를 넘는 정확도로 상당히 높은 수치다.

from sklearn.model_selection import cross_val_score

scores=cross_val_score(dt_clf,X_df,y_df,cv=5)
for iter_count,accuracy in enumerate(scores):
    print("교차 검증 정확도:",iter_count,accuracy)

print("평균 정확도:",np.mean(scores))

from sklearn.model_selection import GridSearchCV
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.best_params_)
print("GridSearchCV 최고 정확도:",grid_dclf.best_score_)
best_dclf = grid_dclf.best_estimator_

dpredictions = best_dclf.predict(X_test)
accuracy = accuracy_score(y_test,dpredictions)
print("테스트 세트에서의 DecisionTreeClassifier 정확도 :",accuracy)

최적 하이퍼 파라미터는 max_depth가 2 ,min_samples_leaf가 1, min_samples_split이 2가 나왔고, 이에 대한 최고 정확도는 98.49%가 나왔다.