ML) HAR - DecisionTreeClassifier / RandomForestClassifier

Like Sunnysideup·2024년 11월 18일
post-thumbnail

데이터 불러오기

url ='.../dataset/HAR_dataset/features.txt'
feature_name_df = pd.read_csv(url, sep='\s+', header=None, names=['column_index', 'columns_name'])

feature_name = feature_name_df.iloc[:,1].tolist()

X_train_url = '.../train/X_train.txt'
X_test_url = '.../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)

X_train.columns = feature_name
X_test.columns = feature_name

y_train_url = '.../train/y_train.txt'
y_test_url = '.../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'])

X_train.shape, y_train.shape, X_test.shape, y_test.shape
# 결과 
((7352, 561), (7352, 1), (2947, 561), (2947, 1))

y_train['action'].value_counts()
# 결과 
action
6    1407
5    1374
4    1286
1    1226
2    1073
3     986
Name: count, dtype: int64

Encoding

from sklearn.preprocessing import LabelEncoder

# LabelEncoder는 문자형 또는 범주형 데이터를 숫자형 레이블로 변환해주는 도구
le = LabelEncoder()

# Pandas의 Series는 numpy 배열 위에 여러 메타데이터(인덱스, 이름 등)를 추가로 포함하는 구조
# LabelEncoder는 이러한 메타데이터 없이 순수 데이터만 필요
# LabelEncoder는 기본적으로 1차원 리스트나 numpy 배열을 입력값으로 처리
# to_numpy : Pandas Series나 DataFrame 데이터를 numpy 배열로 변환
# ravel()은 2차원 배열을 1차원으로 평탄화(flatten)
y_train = le.fit_transform(y_train.to_numpy().ravel())

#y_test에 있는 데이터는 y_train에서 학습한 범주에 따라 변환
y_test = le.transform(y_test.to_numpy().ravel())

DecisionTreeClassifier - Fit / Predict / Score

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

dt_clf = DecisionTreeClassifier(random_state=4, max_depth=4)

dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
accuracy_score(y_test, pred)
# 결과 
0.8096369189005769

DecisionTreeClassifier - CV 적용 X

  • 본 모델 선택 이유
    1) 빠른 속도 필요할 때
    2) CV가 필요 없을 때
    : 데이터셋이 매우 크고, 훈련/테스트 분할이 이미 잘 되어 있는 경우.
    : 교차 검증의 추가적 안정성을 굳이 필요로 하지 않는 경우.
    3) 단순한 하이퍼파라미터 조합
    : 하이퍼파라미터가 많지 않고, 단일 또는 소수의 파라미터만 조정
max_depths = [6,8,10,12,16,20,24]

for depth in max_depths:
    dt_clf = DecisionTreeClassifier(max_depth=depth, random_state=4)
    dt_clf.fit(X_train, y_train)
    pred = dt_clf.predict(X_test)
    accuracy = accuracy_score(y_test, pred)
    print('max_depth={0} 정확도: {1:.4f}'.format(depth, accuracy))
# 결과 
max_depth=6 정확도: 0.8561
max_depth=8 정확도: 0.8728
max_depth=10 정확도: 0.8629
max_depth=12 정확도: 0.8687
max_depth=16 정확도: 0.8599
max_depth=20 정확도: 0.8619
max_depth=24 정확도: 0.8619

DecisionTreeClassifier - GridSearch CV

  • scoring 매개변수 : accuracy/ precision/ recall/ f1/ roc_auc 등 설정 가능
from sklearn.model_selection import GridSearchCV

# 하이퍼파라미터 범위 설정
params= {'max_depth':[6,8,10,12,16,20,24]}

# GridSearchCV 설정 및 실행
grid_cv = GridSearchCV(dt_clf, param_grid=params, scoring='accuracy', cv=5, return_train_score=True)
grid_cv.fit(X_train, y_train)

grid_cv.best_score_, grid_cv.best_params_
# 결과 
(0.853926201343896, {'max_depth': 8})

# grid_cv.cv_results_ : 엄청난 결과 줄글 
cv_results_df = pd.DataFrame(grid_cv.cv_results_)
cv_results_df[['param_max_depth', 'mean_test_score', 'mean_train_score']]
# 결과 : 아래 테이블 이미지 

# GridSearchCV를 통해 최적의 하이퍼파라미터로 학습된 모델을 사용해 테스트 데이터를 평가하고, 정확도를 계산
best_df_clf = grid_cv.best_estimator_
# 결과 : 
RandomForestClassifier(max_depth=8, n_estimators=50, n_jobs=-1, random_state=4)

pred1 = best_df_clf.predict(X_test)

accuracy = accuracy_score(y_test, pred1)
accuracy
# 결과 : 0.8727519511367492

RandomForestClassifier - Fit / Predict / Score

from sklearn.ensemble import RandomForestClassifier

params = {'max_depth':[6,8,10], 'n_estimators':[50,100,200]}

# n_jobs=-1: 시스템의 모든 가용 코어를 사용
rf_clf = RandomForestClassifier(random_state=4, n_jobs=-1)
grid_cv = GridSearchCV(rf_clf, param_grid=params, cv=2, n_jobs=-1)
grid_cv.fit(X_train, y_train)

# grid_cv.cv_results_ : 엄청난 결과 줄글 
cv_results_df = pd.DataFrame(grid_cv.cv_results_)
cv_results_df[['rank_test_score', 'param_max_depth', 'param_n_estimators','mean_test_score']]
# 결과 : 아래 테이블 이미지

rf_clf_best = grid_cv.best_estimator_ 
rf_clf_best.fit(X_train, y_train)
# 결과 : RandomForestClassifier(max_depth=8, n_estimators=50, n_jobs=-1, random_state=4)

# 561개의 모든 feature들의 중요도  
best_cols_values = rf_clf_best.feature_importances_
best_cols = pd.Series(best_cols_values, index=X_train.columns)
top20_cols = best_cols.sort_values(ascending=False)[:20]
top20_cols
# 결과 
angle(X,gravityMean)         0.041061
tGravityAcc-mean()-X         0.038795
tGravityAcc-energy()-X       0.031639
tGravityAcc-mean()-Y         0.023769
angle(Y,gravityMean)         0.023297
tGravityAcc-min()-Y          0.022470
tGravityAcc-max()-Y          0.019928
tGravityAcc-arCoeff()-Z,1    0.018162
tGravityAcc-max()-X          0.018097
tGravityAcc-min()-X          0.016831
tGravityAcc-energy()-Y       0.014184
angle(Z,gravityMean)         0.013737
tBodyGyroJerk-iqr()-Z        0.013609
tGravityAcc-energy()-Z       0.013443
fBodyAccMag-mad()            0.012547
tGravityAcc-entropy()-Y      0.012483
fBodyAccMag-energy()         0.012477
tBodyAcc-max()-X             0.011813
fBodyAcc-mean()-X            0.011055
tGravityAcc-arCoeff()-Z,2    0.010944
dtype: float64

Top 20 features 중요도 시각화

import seaborn as sns

plt.figure(figsize=(8,4))
sns.barplot(x=top20_cols.values, y=top20_cols.index)
plt.show()

Top 20 features로 모델 실행

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)

pred_re = rf_clf_best_re.predict(X_test_re)
accuracy = accuracy_score(y_test, pred_re)
accuracy
# 결과 : 
0.8204954190702409
profile
Perfect timing to be a Newbie

0개의 댓글