랜덤 포레스트(Random Forest)

※ 결정 트리를 모른다면?(아래 클릭 시 링크로 이동)
결정 트리(Decision Tree)

랜덤 포레스트가 뭐지?

기계 학습에서의 랜덤 포레스트(영어: random forest)는 분류, 회귀 분석 등에 사용되는 앙상블 학습 방법$^*$$^1$의 일종으로, 훈련 과정에서 구성한 다수의 결정 트리로부터 분류 또는 평균 예측치(회귀 분석)를 출력함으로써 동작한다.
- 위키백과

랜덤 포레스트는 단순하게 말하면 결정 트리 여러 개를 모아 놓은 것이다.
이름 그대로 나무(Tree)가 모여 있으니 숲(Forest)이 되는 것이다.

랜덤(Random, 무작위)이라는 말은 왜 붙어 있을까? 이는 아래 내용을 참고하면 이해 가능할 것이다.

초기 랜덤 포레스트는 단일 트리를 확장할 때 가능한 결정(available decisions)중 임의의 부분집합(random subset)에서 검색하는 아이디어를 도입한 얄리 아미트(Yali Amit)와 도널드 게먼(Donald Geman)의 연구에 영향을 받았다. 또한 임의의 부분공간(random subspace)을 선택하는 틴 캄 호(Tin Kam Ho)의 아이디어 역시 랜덤 포레스트의 디자인에 영향을 미쳤다. - 위키백과(랜덤 포레스트 - 1 도입 - 1.2 역사 中)

랜덤 포레스트는 왜 만들어졌을까?
랜덤 포레스트는 결정 트리로부터 나온 것이다. 결정 트리는 한 개의 트리만을 사용하기에 한 노드에서의 에러가 그의 하부 노드까지 계속해서 영향을 주기도 하고, 트리의 깊이에 따라 과적합되는 문제 등이 있다. 이러한 이유로 새로운 데이터의 분류에 유연하게 대응하지 못하는데, 이를 보완하기 위해 나온 것이 랜덤 포레스트다.


랜덤 포레스트는 어떻게 하는거지?

랜덤 포레스트는 아래와 같은 순서로 진행된다.

  1. 초기 데이터셋(Original Dataset)으로부터 파생된 여러 개의 데이터셋을 만든다. 이 과정은 부트스트랩 샘플링$^*$$^2$을 통해 이루어진다.
  2. 1번에서 만들어진 각각의 데이터셋에 대한 결정 트리를 만든다. 여기서 주의할 점은 트리를 만들 때 트리의 각 분기마다 해당 데이터셋의 특성 중 일부를 무작위로 가져온다는 것이다.

이렇게 해서 만들어진 결정 트리들을 모아놓은 것이 바로 랜덤 포레스트이다.

그럼 랜덤 포레스트는 타겟을 어떻게 예측할까?

만약 어떤 특성을 가진 데이터의 타겟을 예측하기 위해 랜덤 포레스트에 넣는다고 하자.
이 랜덤 포레스트 안에는 여러 개의 결정 트리가 있고, 각각의 결정 트리는 이 데이터에 대한 타겟 예측을 내놓는다. 그 후 이들의 예측 모두를 종합하여 최종 타겟 예측 값을 결정하는데, 이를 배깅(Bagging, Bootstrap Aggregating)이라고 한다.

회귀 문제에서는 예측을 종합한 값의 평균이, 분류 문제에서는 다수결로 선택된 클래스가 최종 예측 값이 된다.

잠깐, 예측하기 전에 검증은 어떻게 하지?

랜덤 포레스트를 만들 때 필요한 여러 데이터셋을 만드는 과정에서 부트스트랩 샘플링을 사용한다고 하였다. 여기서 샘플링 과정에 포함되지 않는 데이터가 생기는데, 이를 Out-Of-Bag(OOB) 데이터라고 한다.
랜덤 포레스트의 검증은 이 OOB 데이터를 통해 이루어진다. 이를 통해 OOB 데이터에 대한 예측 결과와 실제 값의 오차, 즉 OOB 오차(Out-Of-Bag Error)를 얻을 수 있다.

이후 검증 결과를 바탕으로 랜덤 포레스트의 하이퍼 파라미터(개별 트리의 최대 깊이, 노드 분기를 위한 최소한의 샘플 수 등)를 조절하여 OOB 오차를 최소화시킨다.

scikit-learn을 통해 랜덤 포레스트 사용하기

  1. 데이터 불러오기 및 전처리
# 데이터 불러오기
import pandas as pd

target = 'vacc_h1n1_f'
train = pd.merge(pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/train.csv'),
pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/train_labels.csv')[target], left_index=True, right_index=True)
test = pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/test.csv')
sample_submission = pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/submission.csv')
# 데이터를 훈련 / 검증 세트로 분리
from sklearn.model_selection import train_test_split

train, val = train_test_split(train, train_size=0.80, test_size=0.20,
stratify=train[target], random_state=2)

train.shape, val.shape, test.shape

((33723, 39), (8431, 39), (28104, 38))

# 데이터 전처리
def  engineer(df):
    """특성을 엔지니어링 하는 함수입니다."""
    # 새로운 특성을 생성합니다.
    behaviorals = [col for col in df.columns if  'behavioral'  in col]
    df['behaviorals'] = df[behaviorals].sum(axis=1)

    dels = [col for col in df.columns if  ('employment'  in col or  'seas'  in col)]
    df.drop(columns=dels, inplace=True)

    return df

train = engineer(train)
val = engineer(val)
test = engineer(test)
# 데이터를 특성과 타겟으로 분리
features = train.drop(columns=[target]).columns  

X_train = train[features]
y_train = train[target]
X_val = val[features]
y_val = val[target]
X_test = test[features]
  1. 랜덤 포레스트 사용하기
from category_encoders import OrdinalEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline  

# 범주형 특성들의 값을 숫자로 대체하기 위하여 OrdinalEncoder 사용
# handle_missing="return_nan"은 범주형 특성에 있는 NaN을 항상 -2로 대체시킴
# 만약 handle_missing="value"(기본값)인 경우 NaN이 -2가 아닌 일반적인 범주 종류로 인식되어 값이 대체될 수도 있다.
pipe = make_pipeline(
    OrdinalEncoder(handle_missing="return_nan"),
    SimpleImputer(),
    RandomForestClassifier(max_depth=13, n_estimators=120, random_state=10, n_jobs=-1, oob_score=True)
)  
# RandomForestClassifier의 n_estimators는 랜덤 포레스트 내의 결정 트리 개수를 의미함
# 그 외 결정 트리의 과적합을 줄이기 위해 사용하는 max_depth, min_samples_split, min_samples_leaf도 설정 가능

pipe.fit(X_train, y_train)
print('훈련 정확도', pipe.score(X_train, y_train))
print('검증 정확도', pipe.score(X_val, y_val))
print('f1 score', f1_score(y_val, pipe.predict(X_val)))

훈련 정확도 0.8894523025828069
검증 정확도 0.8315739532677026
f1 score 0.5520504731861199

# OOB 스코어(OOB 오차의 반대 개념) 확인
pipe.named_steps['randomforestclassifier'].oob_score_

0.821516472437209


*1 앙상블 학습 방법?

앙상블(프랑스어: ensemble)은 전체적인 어울림이나 통일. ‘조화’로 순화한다는 의미의 프랑스어이며 음악에서 2인 이상이 하는 노래나 연주를 말한다.
- 위키백과(앙상블)

보통 우리가 아는 '앙상블'이라는 말의 의미는 위와 같다.

앙상블 방법은 한 종류의 데이터로 여러 머신러닝 학습 모델(weak base learner, 기본 모델)을 만들어 그 모델들의 예측 결과를 다수결이나 평균을 내어 예측하는 방법이다.
랜덤 포레스트는 결정 트리를 기본 모델로 사용하는 앙상블 방법이다.


*2 부트스트랩 샘플링?


부트스트랩 샘플링이란 어떠한 데이터셋에 대하여 샘플링을 할 때 복원 추출, 즉 뽑았던 것을 또 뽑을 수 있도록 한 것이다. 이렇게 샘플링을 반복하여 만들어지는 것이 부트스트랩 세트(Bootstrap Set)이다. 복원 추출을 했기 때문에 각각의 부트스트랩 세트 안에는 같은 샘플이 중복되어 나타날 수 있다.

부트스트랩 세트의 크기가 n이라 할 때 한 번의 추출 과정에서 어떤 한 샘플이 추출되지 않을 확률은 다음과 같다.

$\displaystyle \frac {n-1}{n}$

n회 복원 추출을 진행했을 때 그 샘플이 추출되지 않을 확률은 다음과 같다.

$\displaystyle \left({\frac {n-1}{n}}\right)^{n}$

n을 무한히 크게 했을 때 이 식은 다음과 같다.

$\displaystyle \lim _{{n\to \infty }}\left({1 - \frac {1}{n}}\right)^{n} = e^{-1} = 0.368$
※ 참고 : $\displaystyle e = \lim _{{n\to \infty }}\left(1+{\frac {1}{n}}\right)^{n}$

즉, 데이터가 충분히 크다고 가정했을 때 한 부트스트랩 세트는 표본의 63.2% 에 해당하는 샘플을 가진다.
여기서 추출되지 않는 36.8%의 샘플이 Out-Of-Bag 샘플이며 이것을 사용해 모델을 검증한다.


<참고 자료>

'Machine Learning > Trees' 카테고리의 다른 글

[ML] 결정 트리(Decision Tree)  (0) 2021.10.26

결정 트리(Decision Tree)

결정 트리가 뭐지?

결정 트리(decision tree)는 의사 결정 규칙과 그 결과들을 트리 구조로 도식화한 의사 결정 지원 도구의 일종이다.
- 위키백과 (결정 트리)

결정 트리 학습법(decision tree learning)은 어떤 항목에 대한 관측값과 목표값을 연결시켜주는 예측 모델로서 결정 트리를 사용한다. 이는 통계학과 데이터 마이닝, 기계 학습에서 사용하는 예측 모델링 방법 중 하나이다. 트리 모델 중 목표 변수가 유한한 수의 값을 가지는 것을 분류 트리라 한다. 이 트리 구조에서 잎(리프 노드)은 클래스 라벨을 나타내고 가지는 클래스 라벨과 관련있는 특징들의 논리곱을 나타낸다. 결정 트리 중 목표 변수가 연속하는 값, 일반적으로 실수를 가지는 것은 회귀 트리라 한다.
- 위키백과 (결정 트리 학습법)

결정 트리는 스무고개 같은 것으로 생각하면 간단하다. 어떠한 대상(표본의 특성)에 대하여 첫 질문(뿌리 노드)을 시작으로 여러 질문들(중간 노드, internal node)을 거쳐 마지막 질문(말단 노드, terminal node, leaf)을 끝으로 최종 답(타겟 예측 값)을 낸다.

다만 스무고개는 질문 횟수 20번으로 규칙이 정해져 있지만, 결정 트리는 사용자가 설정하기에 따라 20번보다 더 많을 수도, 적을 수도 있다. 여기서 이 질문 횟수를 결정 트리의 깊이(depth)라고 한다.

이름이 트리(Tree)인 이유는 말 그대로 나무처럼 생겨서 그렇다. 아래와 같이 생겼다.

출처 : 결정 트리 학습법 - 위키백과

위 예시에서 맨 위 '남자인가?'가 결정 트리의 시작점인 뿌리 노드(root node)이다.
빨강('사망')과 초록('생존')색에 아래로 더 이어진 것이 없는 것들은 말단 노드(external node, terminal node, leaf)라고 한다.
그리고 뿌리 노드와 말단 노드 사이에 있는 노드가 중간 노드(internal node)이다.
노드와 노드 사이를 연결하는 선들은 엣지(edge)라고 한다.

결정 트리 학습 알고리즘

선형 모델에서는 MSE, MAE 등을 비용 함수(Cost function)로 하여 이를 최소화한 모델을 만드는 것이 목적이었다.
결정 트리에서도 비용 함수 역할을 하는 것이 있는데, 바로 지니 불순도(Gini impurity)와 엔트로피(Entropy)이다.

  • 지니 불순도
    • '불순도'라는 이름 그대로 불순물이 얼마나 섞여 있는지를 나타낸다. 여기서 불순물과 불순물이 아닌 것의 기준은 그곳에 무엇이 더 많이 있는가이다. 즉, 더 많은 것이 주인이고 적은 쪽이 불순물이다.
    • 지니 불순도를 계산하는 식은 다음과 같다.
      • 지니불순도(Gini Impurity or Gini Index):
        $$I_G(p)=\sum_{i=1}^{J} p_i(1-p_i)=1-\sum _{i=1}^{J}{p_i}^2$$
        여기서 p는 주인이 차지한 영역의 비율(달리 말하면 확률)이다.
    • 만약 불순물이 최대, 즉 반반 치킨처럼 반반이라면 지니 불순도는 0.5이다. 반대로 모든 것이 같은, 즉 순수한 후라이드 또는 양념 치킨이라면 지니 불순도는 0이다.
    • 조금 더 구체적인 예를 들어보겠다. 결정 트리의 어느 노드에 와서 보니 빨간 휴지가 50개, 파란 휴지가 30개라고 한다. 이때 이 노드에서의 지니 불순도는
      $$1 - ( (\frac{50}{50+30})^2 + (\frac{30}{50+30})^2 ) = 0.46875$$ 이다.
  • 엔트로피
    • 엔트로피도 지니 불순도처럼 높으면 불순물이 많고 낮으면 적은 것이다.
    • 지니 불순도와의 차이점으로 엔트로피는 최대 1(반반), 최소 0(순수)이다.
    • 정보 획득(Information Gain) : 결정 트리에서 어떤 특성을 사용해 분할을 했을 때 엔트로피가 감소하는 양을 뜻한다. 예시는 아래와 같다.
      자식 노드의 가중 평균 엔트로피 = $\frac{17}{30}*0.787 + \frac{13}{30}*0.391 = 0.615$
      ∴ IG = 부모 엔트로피 - 자식 노드의 가중 평균 엔트로피 = 0.996 - 0.615 = 0.38

특성 중요도

선형 모델에서는 각 특성별로 타겟에 얼마나 영향을 주는지를 회귀 계수(Coefficient)로 표현하였다. 결정 트리에도 이와 비슷한 역할로 특성 중요도(Feature importance)가 있다.

이름 그대로 타겟 값을 구하는 과정에서 각 특성이 얼마나 중요한지를 나타낸 것으로, 구체적으로는 해당 특성이 얼마나 일찍 그리고 자주 트리의 분기에 사용되는지 결정한다.

회귀 계수와 다른 점으로 특성 중요도는 항상 양수값이다.

결정 트리의 특징

  1. 결정 트리는 회귀 문제와 분류 문제 모두에 대하여 사용 가능하다.
  2. 결정 트리는 분류 과정을 직관적으로 확인이 가능하다.
  3. 선형 모델과 달리 비선형, 비단조$^*$$^1$, 특성 상호 작용$^*$$^2$ 특징을 가진 데이터 분석이 가능하다.

결정 트리는 위와 같은 장점들이 있다.
그러나 훈련 데이터의 일반화가 제대로 되지 않으면 너무 복잡한 결정 트리가 되는 문제가 있는데, 한 마디로 과적합(Overfitting) 문제가 있다.

결정 트리 과적합 문제

scikit-learn의 DecisionTreeClassifier 또는 DecisionTreeRegressor를 이용하면 결정 트리 모델을 만들 수 있다. 이 둘에는 결정 트리의 과적합을 줄일 수 있는 파라미터들로 다음과 같은 것들이 있다.

  • max_depth : 결정 트리의 최대 깊이를 제한한다. 만약 제한을 하지 않을 경우 트리는 모든 말단 노드가 순수(불순도가 0)해질 때가지 분기를 만들 것이고, 이는 과적합 문제를 발생시킬 수 있다.
  • min_samples_split : 노드가 분할하기 위해서 필요한 최소한의 표본 데이터 수를 설정한다. 이를 통해 아주 적은 데이터만 있어도 노드가 분할하는 것을 막아 과적합을 줄일 수 있다. 만약 설정하지 않으면 작은 분기가 많이 만들어져 과적합 문제가 발생할 수도 있다.
  • min_samples_leaf : 말단 노드가 되기 위해서 필요한 최소한의 표본 데이터 수를 설정한다. 설정한 숫자보다 적은 데이터 수를 가진 노드가 생성되는 것을 막아 과적합 문제를 줄인다. 이를 설정하지 않으면 아주 적은 데이터로도 말단 노드가 생성되어 과적합 문제가 생길 수 있다.

결정 트리는 어떻게 하는거지?

위에서 언급한 scikit-learn의 DecisionTreeClassifier를 통해서 결정 트리를 만들어보겠다.

1) 데이터 불러오기 및 전처리

import pandas as pd
from sklearn.model_selection import train_test_split

target = 'vacc_h1n1_f'
train = pd.merge(pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/train.csv'),
pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/train_labels.csv')[target], left_index=True, right_index=True)
test = pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/test.csv')
sample_submission = pd.read_csv('https://ds-lecture-data.s3.ap-northeast-2.amazonaws.com/vacc_flu/submission.csv')
train, val = train_test_split(train, train_size=0.80, test_size=0.20,
stratify=train[target], random_state=2)

train.shape, val.shape, test.shape

((33723, 39), (8431, 39), (28104, 38))

import numpy as np

def  engineer(df):
    """특성을 엔지니어링 하는 함수입니다."""
    # 높은 카디널리티를 가지는 특성을 제거
    selected_cols = df.select_dtypes(include=['number',  'object'])
    labels = selected_cols.nunique()  # 특성별 카디널리티 리스트
    selected_features = labels[labels <= 30].index.tolist()  # 카디널리티가 30보다 작은 특성만 선택합니다.
    df = df[selected_features]

    # 새로운 특성 생성
    behaviorals = [col for col in df.columns if  'behavioral'  in col]
    df['behaviorals'] = df[behaviorals].sum(axis=1)
    dels = [col for col in df.columns if  ('employment'  in col or  'seas'  in col)]
    df.drop(columns=dels, inplace=True)
    return df

train = engineer(train)
val = engineer(val)
test = engineer(test)
features = train.drop(columns=[target]).columns

# 훈련/검증/테스트 데이터를 특성과 타겟으로 분리합니다
X_train = train[features]
y_train = train[target]
X_val = val[features]
y_val = val[target]
X_test = test[features]

2) 결정 트리 구현

from sklearn.tree import DecisionTreeClassifier  

pipe = make_pipeline(
    OneHotEncoder(use_cat_names=True),
    SimpleImputer(),
    DecisionTreeClassifier(random_state=1, criterion='entropy')
)  

pipe.fit(X_train, y_train)
print('훈련 정확도: ', pipe.score(X_train, y_train))
print('검증 정확도: ', pipe.score(X_val, y_val))

훈련 정확도: 0.9908667674880646
검증 정확도: 0.7572055509429486

y_val.value_counts(normalize=True)

0 0.761001
1 0.238999
Name: vacc_h1n1_f, dtype: float64

∴ 결정 트리의 훈련 정확도는 99가 넘는데 검증 정확도는 타겟의 다수 범주(0) 비율과 거의 똑같다. 즉, 과적합 상태이다.

3) 과적합 해결하기

# max_depth 설정을 통해 과적합 줄이기
pipe = make_pipeline(
    OneHotEncoder(use_cat_names=True),
    SimpleImputer(),
    DecisionTreeClassifier(max_depth=6, random_state=2)
)  

pipe.fit(X_train, y_train)
print('훈련 정확도', pipe.score(X_train, y_train))
print('검증 정확도', pipe.score(X_val, y_val))

훈련 정확도 0.8283367434688491
검증 정확도 0.8269481674771676

# min_samples_leaf 설정을 통해 과적합 줄이기
pipe = make_pipeline(
OneHotEncoder(use_cat_names=True),
SimpleImputer(),
DecisionTreeClassifier(min_samples_leaf=10, random_state=2)
)  

pipe.fit(X_train, y_train)
print('훈련 정확도', pipe.score(X_train, y_train))
print('검증 정확도', pipe.score(X_val, y_val))

훈련 정확도 0.8577528689618361
검증 정확도 0.8029889692800379

∴ 과적합을 줄이기 위한 파라미터를 넣지 않았을 때와 비교하면 훈련 정확도는 낮아졌지만 검증 정확도는 높아졌다. 이전보다 과적합이 줄어들었다.
위 예시에는 담지 않았지만, min_samples_split 또한 비슷한 결과를 얻을 수 있다.

4) 특성 중요도 구하기

# 특성 중요도가 높은 순서대로 그래프에 표시하기
model_dt = pipe.named_steps['decisiontreeclassifier']
enc = pipe.named_steps['onehotencoder']
encoded_columns = enc.transform(X_val).columns

# DecisionTreeClassifier의 feature_importances_ 속성을 통해 특성 중요도를 알 수 있음
importances = pd.Series(model_dt.feature_importances_, encoded_columns)
plt.figure(figsize=(10,30))
importances.sort_values().plot.barh();

지면 관계상 일부 생략

*1 비단조(non-monotonic)란?

'단조(monotonic)'라는 말의 뜻을 알면 비단조는 바로 알 수 있다.
보통 일상 생활에서 '단조(單調)롭다'라는 말에서의 '단조'와 같은 '단조(單調)'이다.

수학적인 의미의 '단조'는 간단하게 말하면 계속해서 증가 혹은 감소하는 상태를 말한다. 중간에 올라가다가 내려가거나, 내려가다가 올라가지 않고 그냥 꾸준히 계속해서 상승 또는 하강하는 것이다.

*2 특성 상호 작용?
특성 상호 작용이란 특성 둘 이상이 만나면 타겟에 각자가 갖고 있던 영향만 끼치는 것이 아니라 여기에 추가적인 영향이 생기는 것으로 이해할 수 있다.
선형 회귀 모델의 경우 이러한 특성 상호 작용이 있으면 모델 성능이 떨어질 수 있으나, 결정 트리는 그렇지 않다.
구체적인 예시를 보겠다.

  • 기본가격 150,000

Location

  • good: +50,000
  • bad: 0

Size

  • big: +100,000
  • small: 0
# 예시 데이터 준비
> cols = ['location','size','price']
# location: 1:good, 0:bad
# size: 1:big, 0:small
# big은 small보다 100,000 비싸고, good은 bad보다 50,000 가격이 더 나갑니다.

features = [[1,  1],
[1,  0],
[0,  1],
[0,  0]]

price = [[300000],
[200000],
[250000],
[150000]]

X_house = pd.DataFrame(columns=cols[:2], data=features)
y_house = pd.DataFrame(columns=[cols[2]], data=price)
# 선형 회귀 모델
from sklearn.linear_model import LinearRegression

linear = LinearRegression()
linear.fit(X_house, y_house)
print('R2: ', linear.score(X_house, y_house))
print('Intercept: ', linear.intercept_[0])
print('Coefficients')
pd.DataFrame(columns=cols[:2], data=linear.coef_)

R2: 1.0
Intercept: 150000.0
Coefficients

  location size
0 50000.0 100000.0
# 회귀 트리 모델
import graphviz
## jupyterlab 사용시: jupyter labextension install @jupyter-widgets/jupyterlab-manager
from ipywidgets import interact
from sklearn.tree import DecisionTreeRegressor, export_graphviz

# 트리구조 그리는 함수
def  show_tree(tree, colnames):
    dot = export_graphviz(tree, feature_names=colnames, filled=True, rounded=True)
    return graphviz.Source(dot)
from sklearn.tree import DecisionTreeRegressor

tree = DecisionTreeRegressor(criterion="mae")
tree.fit(X_house, y_house)
print('R2', tree.score(X_house, y_house))
show_tree(tree, colnames=X_house.columns)

R2 1.0

good and big 인 경우 +100,000 규칙 추가(특성상호작용)

y_house.loc[0,  'price'] = 400000
y_house
  price
0 400000
1 200000
2 250000
3 150000
# 선형 회귀 모델
# 특성 상호 작용이 있는 경우 $R^2$ 점수가 떨어짐(성능 감소)
linear = LinearRegression()
linear.fit(X_house, y_house)
print('R2: ', linear.score(X_house, y_house))
print('Intercept: ', linear.intercept_[0])
print('Coefficients')
pd.DataFrame(columns=cols[:2], data=linear.coef_)

R2: 0.9285714285714286
Intercept: 125000.00000000003
Coefficients

  location size
0 100000.0 150000.0
# 회귀 트리 모델
# 특성 상호 작용이 있어도 트리 모델의 성능은 그대로임
tree = DecisionTreeRegressor(criterion="mae")
tree.fit(X_house, y_house)
print('R2', tree.score(X_house, y_house))
show_tree(tree, colnames=X_house.columns)

R2 1.0


<참고 자료>

'Machine Learning > Trees' 카테고리의 다른 글

[ML] 랜덤 포레스트(Random Forest)  (0) 2021.10.26

+ Recent posts