상세 컨텐츠

본문 제목

[머신러닝] pima 데이터를 사용한 분류: Random Forest

멋사 AISCOOL 7기 Python/INPUT

by dundunee 2022. 11. 17. 17:16

본문

3️⃣Random Forest

✏️ 다수의 결정크리들을 학습하는 앙상블 방법이다.

✏️ 머신러닝에서 랜덤 포레스트는 분류, 회귀 분석 등에 사용되는 앙상블 학습 방법의 일종으로, 훈련 과정에서 구성한 다수의 결정트리로 부터 분류 또는 평균 예측치를 출력함으로써 동작한다.

  • sklearn.ensemble 모듈에 무작위 결정트리를 기반으로 하는 두가지 평균 알고리즘 중 하나로 분류기 구성에 임의성을 도입하여 다양한 분류기 집합이 생성된다.
  • 랜덤 포레스트는 다양한 트리를 결합하며 분산을 줄이며, 전반적으로 더 나은 모델을 생성할 수 있다.
    • 실제로 개별 의사결정트리는 일반적으로 높은 분산을 나타내며 과적합되는 경향이 있다.
    • 따라서 랜덤 포레스트의 무작위성은 예측 오류가 다소 분리된 의사결정트리를 생성하며, 이러한 예측의 평균을 취하면 일부 오류가 상쇄될 수 있다.

배깅(bagging)을 이용한 포레스트 구성

  • bootstrap aggregating의 약자로, 부트스트랩(boorstrap)을 통해 조금씩 다른 훈련 데이터에 대해 훈련된 기초 분류기(base learner)들을 결합(aggregating)시키는 방법
    • **부트스트랩**이란 주어진 훈련 데이터에서 중복을 허용하여 원 데이터셋과 같은 크기의 데이터셋을 만드는 과정을 말한다.
  • 배깅은 서로 다른 데이터셋들에 대해 훈련시킴으로써 트리들을 비상관화 시키는 과정이다.
  • 배깅을 통해 랜덤포레스트를 훈련시키는 과정은 아래와 같다.
    1. 부트스트랩 방법을 통해 T개의 훈련 데이터셋을 생성한다.
    2. T개의 기초 분류기(트리)들을 훈련시킨다.
    3. 기초 분류기(트리)들을 하나의 분류기(랜덤 포레스트)로 결합한다(평균 또는 과반수투표 방식 이용).
  • 이는 결정트리의 과적합(overfitting) 문제를 예방할 수 있다. 부트스트랩과정은 트리들의 편향은 그대로 유지하면서 분산을 감소시키기 때문에 포레스트의 성능을 향상시킨다.
  • 즉 한개의 결정 트리의 경우 훈련 데이터에 있는 노이즈에 대해 매우 민감하지만, 트리들이 서로 상관화 되어있지않다면(비상관화) 여러 트리들의 평균은 노이즈에 대해 강해진다.

중요 매개변수

1️⃣n_estimators: 트리의 개수

  • 총 포레스트를 몇개의 트리로 구성할지를 결정하는 매개변수
  • 포레스트가 작으면 트리들을 구성하고 테스트하는데 시간이 짧은 대신 일반화 능력이 떨어진다.
  • 포레스트 크기가 크다면 훈련과 테스트 시간은 증가하지만결과값이 상대적으로 연속적이며 일반화 능력이 뛰어나다.

2️⃣ max_depth

  • 하나의 트리에서 루드노트부터 종단 노드까지 최대 몇개의 노드를 거칠 것인지를 정하는 매개변수
  • 최대 허용 깊이가 작으면 과소적합이 일어나고, 최대 허용 깊이가 크면 과대 적합이 일어난다.

3️⃣ max_features

  • 노드를 분할할 때 고려해야할 기능의 임의의 하위집합 크기이다.
  • 낮을 수록 분산의 감소가 크지만 치우짐의 증가도 커진다.
RandomForestClassifier(
    n_estimators=100, 
    criterion='gini',
    max_depth=None, 
    min_samples_split=2, 
    min_samples_leaf=1,
    min_weight_fraction_leaf=0.0, 
    max_features='sqrt',
    max_leaf_nodes=None,
    min_impurity_decrease=0.0,
    bootstrap=True,
    oob_score=False,
    n_jobs=None,
    random_state=None,
    verbose=0,
    warm_start=False,
    class_weight=None,
    ccp_alpha=0.0,
    max_samples=None,
)

Best nodes are defined as relative reduction in impurity

주요파라미터

모델링

#feature engineering
# 수치형 변수의 범주화
df["Pregnancies_high"] = df["Pregnancies"] > 6

#결측치처리
#결측치가 있는 데이터는 학습시킬 수 없다
df["Insulin_nan"] = df["Insulin"].replace(0, np.nan)
Insulin_mean = df.groupby("Outcome")["Insulin_nan"].mean()
df["Insulin_fill"] = df["Insulin_nan"]
df.loc[(df["Insulin_nan"].isnull())&(df["Outcome"]==1), "Insulin_fill"] = Insulin_mean[1]
df.loc[(df["Insulin_nan"].isnull())&(df["Outcome"]==0), "Insulin_fill"] = Insulin_mean[0]

#이상치
desc = df["Insulin_nan"].describe()
IQR = desc['75%'] - desc['25%']
max_out = desc['75%'] + (1.5*IQR)
df = df[df["Insulin_fill"] < max_out]
df.shape
>>> #(744, 12)
#모델링
split_count = int(df.shape[0] * 0.8)
train = df[:split_count]
test = df[split_count:]
train.shape, test.shape
>>> #(595, 11), (149, 11)

label_name = "Outcome"
feature_names = df.columns.tolist()
feature_names.remove("Outcome")
feature_names.remove("Insulin")
feature_names.remove("Insulin_nan")

X_train = train[feature_names]
y_train = train[label_name]
X_test = test[feature_names]
y_test = test[label_name]
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(n_estimators=1000, 
                               max_depth=6, 
                               n_jobs=-1, 
															 random_state=42)

model.fit(X_train, y_train)
y_predict = model.predict(X_test)

(y_test == y_predict).mean()
>>> #0.8926174496644296

sns.barplot(x = model.feature_importances_, y = model.feature_names_in_)

관련글 더보기