[파이썬 머신러닝 완벽 가이드] 4장. 분류 - 1
# 22.01.15 머신러닝 스터디 4장. 분류 - 1
< 파이썬 머신러닝 완벽가이드 >¶
04. 분류 1 ( p183 ~ p222)¶
1. 분류¶
분류 방법을 지니는 다양한 머신러닝 알고리즘
- 나이브 베이즈(Naive Bayes) : 베이즈 통게와 생성 모델에 기반한 나이브 베이즈
- 로지스틱 회귀(Logistic Regression) : 독립변수와 종속변수의 선형 관계성에 기반한 로지스틱 회귀
- 결정 트리(Decision Tree) : 데이터 균일도에 따른 규칙 기반의 결정 트리
- 서포트 벡터 머신(Support Vector Machine) : 개별 클래스 간의 최대 분류 마진을 효과적으로 찾아주는 서포트 벡터 머신
- 최소 근접 알고리즘(Nearest Neighbor) : 근접 거리를 기준으로 하는 최소 근접 알고리즘
- 신경망(Neural Network) : 심층 연결 기반의 신경망
- 앙상블(Ensemble) : 서로 다른 머신러닝 알고리즘을 결합한 앙상블
배깅 ( 랜덤 포레스트 등 ), 부스팅 ( 그래디언트 부스팅 등 )
2. 결정 트리¶
루트 노드 - 규칙 노드 - 리프 노드 구조로 루트 노드에서 시작되어 규칙 노드의 규칙 조건에 따라 분할 되어 리프 노드로 나뉜다.
이 때 결정(규칙) 노드는 정보 균일도가 높은 데이터 세트를 먼저 선택할 수 있도록 규칙 조건을 만든다.
- 균일도 측정
엔트로피를 이용한 정보 이득 : 엔트로피는 주어진 데이터 집합의 혼잡도를 의미하는데 서로 다른 값이 섞여 있으면 엔트로피가 높고, 같은 값이 섞여 있으면 엔트로피가 낮다. 정보 이득 지수는 1에서 엔트로피 지수를 뺀 값(1 - 엔트로피지수)이다. 결정 트리는 이 정보 이득 지수가 높은 속성을 기준으로 분할한다.
지니 계수 : 원래 경제학에서 불평등 지수를 나타낼 때 사용하는 계수로 0이 가장 평등하고 1로 갈수록 불평등하다. 머신러닝에서는 지니 계수가 낮을수록 데이터 균일도가 높은 것으로 해석해 지니 계수가 낮은 속성을 기준으로 분할한다.
결정 트리는 균일도라는 룰을 기반으로 하고 있어서 알고리즘이 쉽고 직관적이다. 하지만 트리의 깊이가 커지고 복잡해지면서 과적합이 될 수 있다는 단점 또한 지닌다.
결정 트리(Decision Tree) 파라미터
- min_samples_split : 노드를 분할하기 위한 최소한의 샘플 데이터 , default = 2 ( 작게 설정할 수록 과적합 가능성 증가 )
- min_samples_leaf : 말단 노드가 되기 위한 최소한의 샘플 데이터 수, 비대칭적 데이터의 경우 특정 클래스의 데이터가 극도로 작을 수 있기 때문에 작게 설정해 주어야 한다. ( 과적합 제어 용도 )
- max_features : 최적의 분할을 위해 고려할 최대 피처 개수, default = None ( 모든 피처를 사용해 분할 수행 ) ( int, float, sqrt = auto, log )
- max_depth : 트리의 최대 깊이를 규정 , default = None ( 완벽하게 클래스 결정 값이 될 때까지 깊이를 계속 키움 or 노드가 가지는 데이터 개수가 min_samples_split보다 작아질 때까지 계속 깊이를 증가시킴 )
- max_leaf_nodes : 말단 노드의 최대 개수
# 붓꽃 데이터를 이용한 결정 트리 모델의 학습과 예측
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')
# DecisionTree Classifier 생성
dt_clf = DecisionTreeClassifier(random_state=156)
iris_data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size = 0.2, random_state = 11)
dt_clf.fit(X_train, y_train)
DecisionTreeClassifier(random_state=156)
# Graphiz 사용
from sklearn.tree import export_graphviz
# export_graphviz()의 호출 결과로 out_file로 지정된 tree.dot 파일을 생성함
export_graphviz(dt_clf, out_file = "tree.dot", class_names = iris_data.target_names, \
feature_names = iris_data.feature_names, impurity = True, filled = True)
import graphviz
# 위에서 생성된 tree.dot 파일을 Graphviz가 읽어서 주피터 노트북상에서 시각화
with open("tree.dot") as f:
dot_graph = f.read()
graphviz.Source(dot_graph)
# 피처별 중요도값 확인
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# feature importance 추출
print("Feature importances:\n{0}".format(np.round(dt_clf.feature_importances_, 3)))
# feature별 importance 매핑
for name, value in zip(iris_data.feature_names, dt_clf.feature_importances_):
print('{0} : {1:.3f}'.format(name, value))
# feature importance를 column 별로 시각화하기
sns.barplot(x = dt_clf.feature_importances_, y = iris_data.feature_names)
plt.show()
Feature importances: [0.025 0. 0.555 0.42 ] sepal length (cm) : 0.025 sepal width (cm) : 0.000 petal length (cm) : 0.555 petal width (cm) : 0.420
결정 트리 과적합
결정 트리가 어떻게 학습 데이터를 분할해 예측을 수행하는지, 과적합 문제를 시각화해 확인
make_classification¶
- n_samples : 표본 데이터의 수
- n_features : 독립변수의 수 ( 전체 피처의 수 )
- n_formative : 독립변수 중 종속변수와 상관관계가 있는 성분의 수
- n_redundant : 독립변수 중 다른 독립변수의 선형조합으로 나타나는 성분의 수
- n_repeated : 독립변수 중 단순 중복된 성분의 수
- n_classes : 종속변수의 클래스 수
- n_clusters_per_class : 클래스 당 클러스터의 수
- weights : 각 클래스에 할당 된 표본 수 ( 클래스 별 데이터의 갯수에 차이를 주고 싶을 때 "비대칭 데이터" )
- flip_y : 클래스가 임의로 교환되는 샘플의 일부, 라벨에 노이즈를 생성하여 분류를 어렵게 만든다
n_classes x n_clusters_per_class <= 2^n_informative
클래스당 클러스터 갯수를 늘리면 클래스끼리 잘 분리되어 있지 않은 가상데이터를 얻을 수 있다.
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
%matplotlib inline
plt.title("3 Class values with 2 Features Sample data creation")
# 2차원 시각화를 위해서 피처는 2개, 클래스는 3가지 유형의 분류 샘플 데이터 생성.
X_features, y_labels = make_classification(n_features = 2, n_redundant = 0, n_informative = 2,
n_classes = 3, n_clusters_per_class=1, random_state = 0)
# 그래프 형태로 2개의 피처를 2차원 좌표 시각화, 각 클래스 값은 다른 색깔로 표시됨.
plt.scatter(X_features[:, 0], X_features[:,1], marker='o', c=y_labels, s=25, edgecolor = 'k')
plt.show()
import numpy as np
# Classifier의 Decision Boundary를 시각화 하는 함수
def visualize_boundary(model, X, y):
fig,ax = plt.subplots()
# 학습 데이타 scatter plot으로 나타내기
ax.scatter(X[:, 0], X[:, 1], c=y, s=25, cmap='rainbow', edgecolor='k',
clim=(y.min(), y.max()), zorder=3)
ax.axis('tight')
ax.axis('off')
xlim_start , xlim_end = ax.get_xlim()
ylim_start , ylim_end = ax.get_ylim()
# 호출 파라미터로 들어온 training 데이타로 model 학습 .
model.fit(X, y)
# meshgrid 형태인 모든 좌표값으로 예측 수행.
xx, yy = np.meshgrid(np.linspace(xlim_start,xlim_end, num=200),np.linspace(ylim_start,ylim_end, num=200))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
# contourf() 를 이용하여 class boundary 를 visualization 수행.
n_classes = len(np.unique(y))
contours = ax.contourf(xx, yy, Z, alpha=0.3,
levels=np.arange(n_classes + 1) - 0.5,
cmap='rainbow', clim=(y.min(), y.max()),
zorder=1)
from sklearn.tree import DecisionTreeClassifier
# 특정한 트리 생성 제약 없는 결정 트리의 학습과 결정 경계 시각화
dt_clf = DecisionTreeClassifier().fit(X_features, y_labels)
visualize_boundary(dt_clf, X_features, y_labels)
# 일부 이상치 데이터까지 분류하기 위한 분할이 자주 일어나서 결정 기준 경계가 너무 많아졌다.
# min_samples_leaf = 6으로 트리 생성 조건을 제약
dt_clf = DecisionTreeClassifier(min_samples_leaf = 6).fit(X_features, y_labels)
visualize_boundary(dt_clf, X_features, y_labels)
결정 트리 실습 - 사용자 행동 인식 데이터 세트¶
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
feature_name_df = pd.read_csv('./UCI_HAR_Dataset/features.txt', sep ='\s+', header = None, names=['column_index', 'column_name'])
feature_name = feature_name_df.iloc[:,1].values.tolist()
print('전체 피처명에서 10개만 추출 :', feature_name[:10])
전체 피처명에서 10개만 추출 : ['tBodyAcc-mean()-X', 'tBodyAcc-mean()-Y', 'tBodyAcc-mean()-Z', 'tBodyAcc-std()-X', 'tBodyAcc-std()-Y', 'tBodyAcc-std()-Z', 'tBodyAcc-mad()-X', 'tBodyAcc-mad()-Y', 'tBodyAcc-mad()-Z', 'tBodyAcc-max()-X']
# 중복된 피처명이 얼마나 있는지 확인
feature_dup_df = feature_name_df.groupby('column_name').count()
print(feature_dup_df[feature_dup_df['column_index'] > 1].count())
feature_dup_df[feature_dup_df['column_index'] > 1].head()
# 총 42개의 column이 중복되어 있음
column_index 42 dtype: int64
column_index | |
---|---|
column_name | |
fBodyAcc-bandsEnergy()-1,16 | 3 |
fBodyAcc-bandsEnergy()-1,24 | 3 |
fBodyAcc-bandsEnergy()-1,8 | 3 |
fBodyAcc-bandsEnergy()-17,24 | 3 |
fBodyAcc-bandsEnergy()-17,32 | 3 |
# 원본 피처명에 _1 or _2를 추가로 부여해 새로운 피처명을 가지는 DataFrame을 반환하는 함수
def get_new_feature_name_df(old_feature_name_df):
feature_dup_df = pd.DataFrame(data=old_feature_name_df.groupby('column_name').cumcount(), columns=['dup_cnt'])
feature_dup_df = feature_dup_df.reset_index()
new_feature_name_df = pd.merge(old_feature_name_df.reset_index(), feature_dup_df, how='outer')
new_feature_name_df['column_name'] = new_feature_name_df[['column_name', 'dup_cnt']].apply(lambda x : x[0]+'_'+str(x[1])
if x[1] > 0 else x[0], axis=1)
new_feature_name_df = new_feature_name_df.drop(['index'], axis=1)
return new_feature_name_df
import pandas as pd
def get_human_dataset( ):
# 공백으로 분리 -> sep인자를 \s+
feature_name_df = pd.read_csv('./UCI_HAR_Dataset/features.txt', sep ='\s+', header = None, names=['column_index', 'column_name'])
# 중복된 피처명을 수정
new_feature_name_df = get_new_feature_name_df(feature_name_df)
# DataFrame에 피처명을 column으로 부여하기 위해
feature_name = new_feature_name_df.iloc[:, 1].values.tolist()
# 학습 핓 데이터 세트, 테스트 피처 데이터
X_train = pd.read_csv('./UCI_HAR_Dataset/train/X_train.txt', sep ='\s+', names=feature_name)
X_test = pd.read_csv('./UCI_HAR_Dataset/test/X_test.txt', sep ='\s+', names=feature_name)
# 학습 레이블, 테스트 레이블
y_train = pd.read_csv('./UCI_HAR_Dataset/train/y_train.txt', sep ='\s+', header = None, names=['action'])
y_test = pd.read_csv('./UCI_HAR_Dataset/test/y_test.txt', sep ='\s+', header = None, names=['action'])
return X_train, X_test, y_train, y_test
X_train, X_test, y_train, y_test = get_human_dataset()
print('## 학습 피처 데이터셋 info() ##')
print(X_train.info())
# 7352개의 레코드로 561개의 피처를 지닌다.
## 학습 피처 데이터셋 info() ## <class 'pandas.core.frame.DataFrame'> RangeIndex: 7352 entries, 0 to 7351 Columns: 561 entries, tBodyAcc-mean()-X to angle(Z,gravityMean) dtypes: float64(561) memory usage: 31.5 MB None
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
dt_clf = DecisionTreeClassifier(random_state = 156)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
accuracy = accuracy_score(y_test, pred)
print('결정 트리 예측 정확도: {0:.4f}'.format(accuracy))
print('DecisionTreeClassifier 기본 하이퍼 파라미터 : ', dt_clf.get_params())
결정 트리 예측 정확도: 0.8548 DecisionTreeClassifier 기본 하이퍼 파라미터 : {'ccp_alpha': 0.0, 'class_weight': None, 'criterion': 'gini', 'max_depth': None, 'max_features': None, 'max_leaf_nodes': None, 'min_impurity_decrease': 0.0, 'min_impurity_split': None, 'min_samples_leaf': 1, 'min_samples_split': 2, 'min_weight_fraction_leaf': 0.0, 'random_state': 156, 'splitter': 'best'}
from sklearn.model_selection import GridSearchCV
params = { 'max_depth' : [6, 8, 10, 12, 16, 20, 24] }
grid_cv = GridSearchCV(dt_clf, param_grid = params, scoring = 'accuracy', cv=5, verbose =1)
grid_cv.fit(X_train, y_train)
print('최고 평균 정확도 수치' ,grid_cv.best_score_)
print('최적 하이퍼 파라미터', grid_cv.best_params_)
Fitting 5 folds for each of 7 candidates, totalling 35 fits 최고 평균 정확도 수치 0.8513444970102249 최적 하이퍼 파라미터 {'max_depth': 16}
# GridSearchCV 객체의 cv_results_ 속성을 DataFrame으로 생성
cv_results_df = pd.DataFrame(grid_cv.cv_results_)
# max_depth 파라미터 값과 그때의 테스트 세트, 학습 데이터 세트의 정확도 수치 추출
cv_results_df
mean_fit_time | std_fit_time | mean_score_time | std_score_time | param_max_depth | params | split0_test_score | split1_test_score | split2_test_score | split3_test_score | split4_test_score | mean_test_score | std_test_score | rank_test_score | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1.382399 | 0.012562 | 0.005201 | 0.000401 | 6 | {'max_depth': 6} | 0.813732 | 0.872876 | 0.819728 | 0.865986 | 0.881633 | 0.850791 | 0.028313 | 5 |
1 | 1.762599 | 0.039601 | 0.005402 | 0.001020 | 8 | {'max_depth': 8} | 0.820530 | 0.819850 | 0.855102 | 0.868707 | 0.891156 | 0.851069 | 0.027719 | 3 |
2 | 2.082199 | 0.043650 | 0.004800 | 0.000400 | 10 | {'max_depth': 10} | 0.799456 | 0.814412 | 0.863265 | 0.891156 | 0.887755 | 0.851209 | 0.037707 | 2 |
3 | 2.322333 | 0.105956 | 0.005001 | 0.000634 | 12 | {'max_depth': 12} | 0.794697 | 0.813052 | 0.848980 | 0.877551 | 0.886395 | 0.844135 | 0.035598 | 7 |
4 | 2.600614 | 0.181947 | 0.005399 | 0.001019 | 16 | {'max_depth': 16} | 0.799456 | 0.818491 | 0.853061 | 0.887755 | 0.897959 | 0.851344 | 0.038140 | 1 |
5 | 2.616774 | 0.220271 | 0.004800 | 0.000399 | 20 | {'max_depth': 20} | 0.802855 | 0.818491 | 0.856463 | 0.877551 | 0.898639 | 0.850800 | 0.035718 | 4 |
6 | 2.591795 | 0.224662 | 0.005400 | 0.001019 | 24 | {'max_depth': 24} | 0.796057 | 0.818491 | 0.856463 | 0.877551 | 0.898639 | 0.849440 | 0.037597 | 6 |
cv_results_df[['param_max_depth', 'mean_test_score']]
param_max_depth | mean_test_score | |
---|---|---|
0 | 6 | 0.850791 |
1 | 8 | 0.851069 |
2 | 10 | 0.851209 |
3 | 12 | 0.844135 |
4 | 16 | 0.851344 |
5 | 20 | 0.850800 |
6 | 24 | 0.849440 |
# max_depth 변화에 따른 값 측정
max_depths = [6,8,10,12,16,20,24]
# max_depth 값을 변화시키면서 그때마다 학습과 테스트 세트에서의 예측 성능 측정
for depth in max_depths:
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 = {0}, accuracy = {1:.4f}'.format(depth, accuracy))
max_depth = 6, accuracy = 0.8558 max_depth = 8, accuracy = 0.8707 max_depth = 10, accuracy = 0.8673 max_depth = 12, accuracy = 0.8646 max_depth = 16, accuracy = 0.8575 max_depth = 20, accuracy = 0.8548 max_depth = 24, accuracy = 0.8548
min_samples_split을 활용한 grid search 생략
grid search 후 .bestestimator 에 최적의 하이퍼 파라미터가 적용된 모델이 저장된다는 것을 알면된다.
best_df_clf = grid_cv.best_estimator_ ; best_df_clf
DecisionTreeClassifier(max_depth=16, random_state=156)
# 피처 중요도 시각화
import seaborn as sns
ftr_importances_values = best_df_clf.feature_importances_
# Top 중요도로 정렬을 쉽게 하고, Seaborn의 막대그래프로 표현하기 위한 Series변환
ftr_importances = pd.Series(ftr_importances_values, index = X_train.columns)
# 중요도값 순으로 Series를 정렬
ftr_top10 = ftr_importances.sort_values(ascending = False)[:10]
plt.figure(figsize=(8,6))
plt.title('Feature importances Top10')
sns.barplot(x=ftr_top10, y = ftr_top10.index)
plt.show()
3. 앙상블 학습¶
앙상블 학습을 통한 분류는 여러 개의 분류기를 생성하고 그 예측을 결합함으로써 보다 정확한 최종 예측을 도출하는 기법을 말한다.
- 보팅 (Voting)
여러 개의 분류기가 투표를 통해 최종 예측 결과를 결정하는 방식 ( 일반적으로 서로 다른 알고리즘을 결합 )
- 배깅 (Bagging) Bootstrap + Aggregating
데이터 샘플링을 통해 모델을 학습시키고 결과를 집계하는 방법 ( 분류기가 같은 유형의 알고리즘 But 데이터 샘플링을 서로 다르게 한다 )
- 부스팅 (Boosting)
여러 개의 분류기가 순차적으로 학습을 수행하되, 앞에서 학습한 분류기가 예측이 틀린 데이터에 대해서는 올바르게 예측할 수 있도록 다음 분류기에게는 가중치를 부여하면서 학습과 예측을 진행하는 것
하드 보팅과 소프트 보팅¶
- 하드 보팅
다수결 원칙과 비슷, 예측한 결괏값들중 다수의 분류기가 결정한 예측값을 최종 보팅 결괏값으로 선정
- 소프트 보팅 ( 일반적으로 사용 )
분류기들의 레이블 값 결정 확률을 모두 더하고 이를 평균해서 이들 중 확률이 가장 높은 레이블 값을 최종 보팅 결괏값으로 선정
보팅 분류기¶
import pandas as pd
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
cancer = load_breast_cancer()
data_df = pd.DataFrame(cancer.data, columns=cancer.feature_names)
data_df.head(5)
mean radius | mean texture | mean perimeter | mean area | mean smoothness | mean compactness | mean concavity | mean concave points | mean symmetry | mean fractal dimension | ... | worst radius | worst texture | worst perimeter | worst area | worst smoothness | worst compactness | worst concavity | worst concave points | worst symmetry | worst fractal dimension | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 17.99 | 10.38 | 122.80 | 1001.0 | 0.11840 | 0.27760 | 0.3001 | 0.14710 | 0.2419 | 0.07871 | ... | 25.38 | 17.33 | 184.60 | 2019.0 | 0.1622 | 0.6656 | 0.7119 | 0.2654 | 0.4601 | 0.11890 |
1 | 20.57 | 17.77 | 132.90 | 1326.0 | 0.08474 | 0.07864 | 0.0869 | 0.07017 | 0.1812 | 0.05667 | ... | 24.99 | 23.41 | 158.80 | 1956.0 | 0.1238 | 0.1866 | 0.2416 | 0.1860 | 0.2750 | 0.08902 |
2 | 19.69 | 21.25 | 130.00 | 1203.0 | 0.10960 | 0.15990 | 0.1974 | 0.12790 | 0.2069 | 0.05999 | ... | 23.57 | 25.53 | 152.50 | 1709.0 | 0.1444 | 0.4245 | 0.4504 | 0.2430 | 0.3613 | 0.08758 |
3 | 11.42 | 20.38 | 77.58 | 386.1 | 0.14250 | 0.28390 | 0.2414 | 0.10520 | 0.2597 | 0.09744 | ... | 14.91 | 26.50 | 98.87 | 567.7 | 0.2098 | 0.8663 | 0.6869 | 0.2575 | 0.6638 | 0.17300 |
4 | 20.29 | 14.34 | 135.10 | 1297.0 | 0.10030 | 0.13280 | 0.1980 | 0.10430 | 0.1809 | 0.05883 | ... | 22.54 | 16.67 | 152.20 | 1575.0 | 0.1374 | 0.2050 | 0.4000 | 0.1625 | 0.2364 | 0.07678 |
5 rows × 30 columns
# 개별 모델은 로지스틱, KNN
lr_clf = LogisticRegression(max_iter = 2000) # 2000으로 설정해야 오류가 안뜬다
# default값인 max_iter = 100으로는 수렴하지 못해 에러가 발생하는것!
knn_clf = KNeighborsClassifier(n_neighbors=8)
# 개별 모델을 소프트 보팅 기반의 앙상블 모델로 구현한 분류기
vo_clf = VotingClassifier( estimators = [('LR', lr_clf), ('KNN', knn_clf)], voting = 'soft')
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size=0.2, random_state = 156)
# Voting Classifier 학습, 예측, 평가
vo_clf.fit(X_train, y_train)
pred = vo_clf.predict(X_test)
print('Voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test, pred)))
# 개별 모델의 학습/예측/평가
classifiers = [lr_clf, knn_clf]
for classifier in classifiers:
classifier.fit(X_train, y_train)
pred = classifier.predict(X_test)
class_name = classifier.__class__.__name__
print('{0} 정확도 : {1:.4f}'.format(class_name, accuracy_score(y_test, pred)))
Voting 분류기 정확도: 0.9474 LogisticRegression 정확도 : 0.9561 KNeighborsClassifier 정확도 : 0.9386
4. 랜덤 포레스트¶
배깅의 대표적인 알고리즘으로 앙상블 알고리즘 중 비교적 빠른 수행 속도를 가지고 있다. 기반 알고리즘은 결정 트리로서, 결정 트리의 쉽고 직관적인 장점을 그대로 가지고 있다. 여러 개의 결정 트리 분류기가 전체 데이터에서 배깅 방식으로 각자의 데이터를 샘플링해 개별적으로 학습을 수행한 뒤 최종적으로 모든 분류기가 보팅을 통해 예측 결정을 하게 된다.
랜덤 포레스트 하이퍼 파라미터
- n_estimators : 결정 트리의 개수, default = 10
- max_features : 결정 트리에 사용된 max_features와 같다, default = 'auto'
- max_depth, min_samples_leaf와 같이 결정 트리에서 과적합을 개선하기 위해 사용되는 파라미터가 rf에도 똑같이 적용될 수 있다.
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
X_train, X_test, y_train, y_test = get_human_dataset()
rf_clf = RandomForestClassifier(random_state=0)
rf_clf.fit(X_train, y_train)
pred = rf_clf.predict(X_test)
accuracy = accuracy_score(y_test, pred)
print('랜덤 포레스트 정확도 :', accuracy)
랜덤 포레스트 정확도 : 0.9253478113335596
랜덤 포레스트 그리드 서치 예제는 생략
# feature importance 시각화
ftr_importances_values = rf_clf.feature_importances_
# Top 중요도로 정렬을 쉽게 하고, Seaborn의 막대그래프로 표현하기 위한 Series변환
ftr_importances = pd.Series(ftr_importances_values, index = X_train.columns)
# 중요도값 순으로 Series를 정렬
ftr_top10 = ftr_importances.sort_values(ascending = False)[:10]
plt.figure(figsize=(8,6))
plt.title('Feature importances Top10')
sns.barplot(x=ftr_top10, y = ftr_top10.index)
plt.show()
# 업로드용 창 맞추기
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important; }</style>"))