랜덤포레스트에서는 특성 n개 중 일부분 k개의 특성을 선택(sampling) 하고 이 k개에서 최적의 특성을 찾아내어 분할한다. 이때 k개는 일반적으로 를 사용.
from sklearn.ensemble import RandomForestClassifier
RandomForestClassifier(random_state=10, n_jobs=-1, oob_score=True)
순서형 인코딩은 범주에 숫자를 맵핑
트리구조에서는 중요한 특성이 상위노드에서 먼저 분할이 일어난다. 그래서 범주 종류가 많은(high cardinality) 특성은 원핫인코딩으로 인해 상위노드에서 선택될 기회가 적어진다.
원핫인코딩 영향을 안 받는 수치형 특성이 상위노드를 차지할 기회가 높아지고 전체적인 성능 저하가 생길 수 있다.
from category_encoders import OrdinalEncoder
enc = OrdinalEncoder()
X = [['Male', 1, 'Yes'], ['Female', 3, 'No'], ['Female', 2, 'None']]
enc.fit(X)
#NaN도 매핑해줌
#%%time 사용하면 학습시간 계산가능
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from category_encoders import OrdinalEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.metrics import f1_score, accuracy_score
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import LabelEncoder
import warnings
warnings.filterwarnings('ignore')
behavioral_antiviral_meds - 항바이러스제를 복용했습니다. (이진)
behavioral_avoidance - 독감 같은 증상을 가진 다른 사람들과의 긴밀한 접촉을 피했습니다. (이진)
behavioral_face_mask - 페이스 마스크를 구입했습니다. (이진)
behavioral_wash_hands - 손을 자주 씻거나 손 세정제를 사용했습니다. (이진)
behavalion_large_garings - 큰 모임에서 시간이 단축되었습니다. (이진)
behavioral_outside_home - 자신의 가정 이외의 사람들과의 접촉이 감소하였다. (이진)
bevehaval_touch_face - 눈, 코, 입의 접촉을 피했습니다. (이진)
doctor_recc_h1n1 - H1N1 독감백신은 의사가 권장하였다. (이진)
doctor_recc_seasonal - 계절 독감 백신은 의사가 권장하였다. (이진)
chronic_med_condition - 천식 또는 다른 폐 질환, 당뇨병, 심장 질환, 신장 질환, 겸상적혈구 빈혈 또는 기타 빈혈, 신경성 또는 신경근육 질환, 간 질환 또는 만성 질환 또는 만성 질환에 의해 복용된 약화된 면역 체계를 가지고 있다. 병. (병)
child_under_6_months - 생후 6개월 미만 아동과 정기적으로 밀접하게 접촉합니다. (이진)
health_insurance - 건강보험이 있습니다. (이진)
health_worker - 의료 종사자입니다. (이진)
opinion_h1n1_vacc_effective - H1N1 백신 효과에 대한 응답자의 의견. 전혀 효과적이지 않다; 매우 효과적이지 않다; 잘 모른다; 다소 효과적이다; 매우 효과적이다.
opinion_h1n1_risk - 백신 없이 H1N1 독감에 걸릴 위험에 대한 응답자의 의견. 매우 낮음, 다소 낮음, 잘모름, 다소 높음, 매우 높음
opinion_h1n1_sick_from_vacc - H1N1 백신을 복용하여 병에 걸리는 것에 대한 응답자의 걱정. 전혀 걱정 안 해. 별로 걱정 안 해. 몰라. 어느 정도 걱정해. 아주 걱정해.
opinion_seas_vacc_effective - 계절 독감 백신 효과에 대한 응답자의 의견. 전혀 효과적이지 않다; 매우 효과적이지 않다; 잘 모른다; 다소 효과적이다; 매우 효과적이다.
opinion_sea_risk - 백신 없이 계절성 독감에 걸릴 위험에 대한 응답자의 의견. 매우 낮음, 다소 낮음, 잘모름, 다소 높음, 매우 높음
opinion_sea_sick_from_vacc - 계절성 독감 백신을 복용하여 병에 걸리는 것에 대한 응답자들의 걱정. 전혀 걱정 안 해. 별로 걱정 안 해. 몰라. 어느 정도 걱정해. 아주 걱정해.
agegrp - 응답자 연령 그룹. 6개월 - 9년, 10 - 17년, 18 - 34년, 35 - 44년, 45 - 54년, 55 - 64년, 65년 이상
education_comp - 자체 보고된 교육 수준입니다. 1 = = 12년, 2 = 12년, 3 = 일부 대학, 4 = 대학 졸업
raceeth4_i - 응답자 레이스 1 = 히스패닉, 2 = 비히스패닉, 흑인 전용, 3 = 비히스패닉, 백인 전용, 4 = 비히스패닉, 기타 또는 다중 인종
sex_i - 응답자의 성별. 1 = 남성, 2 = 여성 2
inc_pov - 2008년 인구조사 빈곤 문턱에 대한 응답자의 가구 연간 소득. 1 = = 75,000달러, 2 = = 75,000달러, 3 = 빈곤 이하, 4 = 미상
marital - 응답자의 혼인 여부. 1 = 결혼, 2 = 결혼하지 않음
rent_own_r - 응답자의 주거 상황. 1 = 자택 소유, 2 = 자택 임대 또는 기타 약정
employment_status - 응답자의 고용상태입니다. 고용; 노동력이 아님; 실업자
census_region - 거주 지역의 참 인구 조사 지역(1=178; 2=198; 3=남쪽, 4=서쪽)
census_msa - 미국 인구조사에 의해 정의된 대로 응답자가 대도시 통계 지역(MSA) 내에 거주하는 경우.
n_adult_r - 가구의 기타 성인 수.
household_children - 가구의 자녀 수입니다.
n_people_r - 가구의 성인 수.
employment_industry - 산업 응답자 유형을 에 고용합니다.
employment_occupation - 응답자 직업 유형. 값은 짧은 임의 문자열로 표시됩니다.
hhs_region - HHS 감시 지역 번호
Region 1: CT,ME,MA,NH,RI,VT
Region 2: NJ,NY
Region 3: DE, DC, MD, PA, VA,WV
Region 4: AL, FL, GA, KY, MS, NC, SC,TN
Region 5: IL, IN, MI, MN, OH,WI
Region 6: AR, LA, NM, OK, TX
Region 7: IA,KS,MO,NE
Region 8: CO, MT, ND, SD, UT, WY
Region 9: AZ, CA, HI, NV
Region 10: AK, ID, OR, WA
state - 거주 상태
#데이터 생성
target = ['vacc_h1n1_f']
train = pd.merge(pd.read_csv('train.csv'), pd.read_csv('train_labels.csv')[target], left_index = True, right_index = True)
test = pd.read_csv('test.csv')
#train, validation 분리
train, val = train_test_split(train, test_size = 0.2, stratify = train[target], random_state = 2) #stratify : 원래 class의 비율을 유지시켜줌
train.shape, val.shape, test.shape
# feature engineering
def engineer(df):
#높은 카디널리티 제거
# labels = df.nunique()
# selected_features = labels[labels < 20].index.tolist()
# df = df[selected_features]
cols = list(df.columns)
behavioral = []
for col in cols:
if 'behavioral' in col:
behavioral.append(col)
#예방 행위
df['behavioral'] = df[behavioral].sum(axis = 1)
#의사소견
df['doctor'] = df['doctor_recc_h1n1'] + df['doctor_recc_seasonal']
#경각심
df['mind'] = df['health_worker'] + df['h1n1_knowledge'] + df['h1n1_concern']
return df
train = engineer(train)
val = engineer(val)
#중복제거
train.drop_duplicates(inplace = True)
val.drop_duplicates(inplace = True)
test = engineer(test)
list(train.columns)
# class 분리
features = train.drop(target, axis = 1).columns
X_train = train[features]
y_train = train[target]
X_val = val[features]
y_val = val[target]
X_train_val = pd.concat([X_train, X_val])
y_train_val = pd.concat([y_train, y_val])
X_test = test[features]
#파라미터 튜닝
pipe_temp = make_pipeline(
OrdinalEncoder(),
SimpleImputer()
)
X_train_val2 = pipe_temp.fit_transform(X_train_val)
#best parameter 찾기
param_grid = {
'max_features' : ['sqrt', 'log'],
'n_estimators' : [10, 50, 100, 200, 300],
# 'min_samples_split' : [10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
# 'max_depth' :[10, 30, 50]
}
grid = GridSearchCV(RandomForestClassifier(n_jobs = -1), param_grid, cv = 5)
grid.fit(X_train_val2, y_train_val)
print('best parameters : \n', grid.best_params_)
best parameters :
{'max_features': 'sqrt', 'n_estimators': 200}
%%time
pipe = make_pipeline(
OrdinalEncoder(),
SimpleImputer(),
RandomForestClassifier(n_jobs = -1, random_state = 10, n_estimators = 200, max_features = 'sqrt', oob_score = True)
)
pipe.fit(X_train_val, y_train_val)
print('Training accuracy : ', pipe.score(X_train, y_train))
print('Validation accuracy : ', pipe.score(X_val,y_val))
y_pred = pipe.predict(X_val)
print('Validation F1 score : ', f1_score(y_val, y_pred))
Training accuracy : 0.9969282156810116
Validation accuracy : 0.9965545918973506
Validation F1 score : 0.9927734861699476
#test class 예측
y_pred = pipe.predict(X_test)
#submission
result = pd.DataFrame(y_pred, columns = ['vacc_h1n1_f'])
result.reset_index(drop = False, inplace = True)
result.rename(columns = {
'index' : 'id'
}, inplace = True)
result.set_index('id', inplace = True)
#submission 생성
result.to_csv('submission5_0413.csv')