앙상블 ?
IMU 센서를 활용해서 사람의 행동을 인식하는 실험
폰에 있는 가속도/자이로 센서 사용
데이터 소개
1) 데이터 읽기
import pandas as pd
import matplotlib.pyplot as plt
# txt 파일
url = 'https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/features.txt'
# '\s+' 공백, header 그대로, 컬럼 이름 names
feature_name_df = pd.read_csv(url, sep='\s+', header=None, names=['columns_index','columns_name'])
feature_name_df.head()
2) 특성(feature) 갯수 확인
len(feature_name_df)
3) 데이터 확인
# 밸류만 가지고 feature_name 추출 -> 즉, 앞으로 561개의 이름만 저장하게 됨
feature_name = feature_name_df.iloc[:, 1].values.tolist()
feature_name[:10]
4) 일단 X데이터만
X_train_url = 'https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/train/X_train.txt'
X_test_url = 'https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/test/X_test.txt'
X_train = pd.read_csv(X_train_url, sep='\s+', header=None)
X_test = pd.read_csv(X_test_url, sep='\s+', header=None)
5) 대용량 데이터 컬럼 확인
X_train.columns = feature_name
X_test.columns = feature_name
X_train.head()
6) y 데이터 읽어오기
y_train_url = 'https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/train/y_train.txt'
y_test_url = 'https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/HAR_dataset/test/y_test.txt'
y_train = pd.read_csv(y_train_url, sep='\s+', header=None, names=['action'])
y_test = pd.read_csv(y_test_url, sep='\s+', header=None, names=['action'])
7) shape - 개수 확인
X_train.shape, X_test.shape, y_train.shape, y_test.shape
8) 각 action 별 데이터 수
y_train['action'].value_counts()
9) DecisionTree 결정나무
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
dt_clf = DecisionTreeClassifier(random_state=13, max_depth=4)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
accuracy_score(y_test, pred)
10) Train - GridSearchCV (max_depth를 다양하게 하기 위해)
from sklearn.model_selection import GridSearchCV
params = {
'max_depth' : [6,8,10,12,16,20,24]
}
# scoring='accuracy': accuracy 계열은 기록해주세요
# cv=5 :KFold는 5개
grid_cv = GridSearchCV(dt_clf, param_grid=params, scoring='accuracy', cv=5, return_train_score=True)
grid_cv.fit(X_train, y_train)
11) Train 밸리데이션한 값의 best score & params 확인
grid_cv.best_score_, grid_cv.best_params_
(0.8543335321892183, {'max_depth': 8})
12) Train max_depth별로 표로 성능을 정리
cv_result_df = pd.DataFrame(grid_cv.cv_results_)
cv_result_df[['param_max_depth', 'mean_test_score', 'mean_train_score']]
13) Test 데이터에서의 결과
max_depth = [6,8,10,12,16,20,24]
for depth in max_depth:
dt_clf = DecisionTreeClassifier(max_depth=depth, random_state=156)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
accuracy = accuracy_score(y_test, pred)
print('Max_Depth =', depth, ', Accuracy =', accuracy)
14) Test - 베스트 모델의 결과는
best_dt_clf = grid_cv.best_estimator_
pred1 = best_dt_clf.predict(X_test)
accuracy_score(y_test, pred1)
0.8734306073973532
15) 랜덤포레스트 적용
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
params = {
'max_depth' : [6,8,10], # DecisionTree에 적용할 파라미터
'n_estimators' : [50,100,200], # DecisionTree에 tree 몇개
'min_samples_leaf' : [8,12], # DecisionTree에 맨끝 데이터(leaf) 최소 몇개
'min_samples_split' : [8,12] # 분할 기준에서 최소한으로 남는 데이터 수 (큰영향 X)
}
rf_clf = RandomForestClassifier(random_state=13, n_jobs=-1) # n_jobs=-1 : cpu core 다 써서
grid_cv = GridSearchCV(rf_clf, param_grid=params, cv=2, n_jobs=-1)
grid_cv.fit(X_train, y_train)
16) 결과 정리
cv_results_df = pd.DataFrame(grid_cv.cv_results_)
cv_result_df.columns
17) target_cols 지정 & 순위 메기기
# mean_test_score : train 데이터의 validation score (아까는 85% 였는데, randomforest하니까 90% 이상)
# param_n_estimators : 몇개의 나무
target_cols = ['rank_test_score', 'mean_test_score', 'param_n_estimators', 'param_max_depth']
cv_results_df[target_cols].sort_values('rank_test_score').head()
18) best 찾기
grid_cv.best_params_, grid_cv.best_score_
19) Test 데이터에 적용
rf_clf_best = grid_cv.best_estimator_
rf_clf_best.fit(X_train, y_train)
pred1 = rf_clf_best.predict(X_test)
accuracy_score(y_test, pred1)
0.9205972175093315
20) 중요특성 확인
# 베스트 모델에서 랜덤포레스트를 반환(feature_importances_) 받아서
best_cols_values = rf_clf_best.feature_importances_
# 영향력이 높은(best_cols_values) feature만 추려서
best_cols = pd.Series(best_cols_values, index=X_train.columns)
# 정렬(sort_values) 한 다음에 20개만 출력
top20_cols = best_cols.sort_values(ascending=False)[:20]
top20_cols
21) 주요 특성 확인
import seaborn as sns
plt.figure(figsize=(8, 8))
sns.barplot(x=top20_cols, y=top20_cols.index)
plt.show()
22) 주요 특성 20 가지
top20_cols.index
23) 20개 특성으로 다시 확인
X_train_re = X_train[top20_cols.index]
X_test_re = X_test[top20_cols.index]
rf_clf_best_re = grid_cv.best_estimator_
rf_clf_best_re.fit(X_train_re, y_train.values.reshape(-1, ))
pred1_re = rf_clf_best_re.predict(X_test_re)
accuracy_score(y_test, pred1_re)
0.8177807940278249