Python 데이터 분석
Python 데이터분석 기초 61 - Random forest
코딩탕탕
2022. 11. 22. 12:23
Random forest는 ensemble(앙상블) machine learning 모델입니다.
여러개의 decision tree를 형성하고 새로운 데이터 포인트를 각 트리에 동시에 통과시키며,
각 트리가 분류한 결과에서 투표를 실시하여 가장 많이 득표한 결과를 최종 분류 결과로 선택합니다.
Bagging 방식을 사용
Titanic dataset을 사용
# Random forest는 ensemble(앙상블) machine learning 모델입니다.
# 여러개의 decision tree를 형성하고 새로운 데이터 포인트를 각 트리에 동시에 통과시키며,
# 각 트리가 분류한 결과에서 투표를 실시하여 가장 많이 득표한 결과를 최종 분류 결과로 선택합니다.
# Bagging 방식을 사용
# Titanic dataset을 사용
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, cross_val_score
import pandas as pd
import numpy as np
df = pd.read_csv('../testdata/titanic_data.csv')
print(df.head(3))
print(df.columns)
print(df.info())
print(df.isnull().any()) # 결측치가 있는지 확인
df = df.dropna(subset=['Pclass', 'Age', 'Sex'])
print(df.shape) # (714, 12)
df_x = df[['Pclass', 'Age', 'Sex']] # feature
print(df_x.head(2))
# scaling
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
# Sex column은 dummy화
df_x.loc[:, 'Sex'] = LabelEncoder().fit_transform(df_x['Sex'])
print(df_x.head(5))
# LabelEncoder() 함수는 male, female을 0, 1로 바꿔준다. 사전순
# df_x['Sex'] = df_x['Sex'].apply(lambda x:1 if x == 'male' else 0)
print(df_x.head(2))
# print(set(df_x['Pclass'])) # {1, 2, 3}
df_y = df['Survived']
print(df_y.head(2))
# Pclass 열에 대한 원 핫 인코딩
# (해당 열, 범주의 종류 만큼 벡터의 크기를 설정하고, 범주에 해당하는 index에 1을 주고 나머지 요소 모두에는 0으로 채우기
df_x2 = pd.DataFrame(OneHotEncoder().fit_transform(df_x['Pclass'].values[:, np.newaxis]).toarray(),
columns=['f_class', 's_class', 't_class'], index=df_x.index)
print(df_x2.head(2))
df_x = pd.concat([df_x, df_x2], axis=1)
print(df_x.head(10))
# train / test split
train_x, test_x, train_y, test_y = train_test_split(df_x, df_y, test_size = 0.25, random_state=12)
print(train_x.shape, test_x.shape, train_y.shape, test_y.shape) # (535, 6) (179, 6) (535,) (179,)
# model
model = RandomForestClassifier(n_estimators=500, criterion='entropy')
model.fit(train_x, train_y)
pred = model.predict(test_x)
print('예측값 :', pred[:5])
print('실제값 :', np.array(test_y[:5]))
# 정확도
print('acc :', sum(test_y == pred) / len(test_y)) # acc : 0.8156424581005587
from sklearn.metrics import accuracy_score
print('acc :', accuracy_score(test_y, pred))
# 교차검증
cross_vali = cross_val_score(model, df_x, df_y, cv = 5)
print(cross_vali)
print(np.mean(cross_vali))
# 중요변수
print('특성(변수) 중요도 :',model.feature_importances_)
import matplotlib.pyplot as plt
def plot_importance(model):
n_features = df_x.shape[1]
plt.barh(range(n_features), model.feature_importances_, align = 'center')
plt.yticks(np.arange(n_features), df_x.columns)
plt.xlabel('feature_importances_')
plt.ylabel('feature')
plt.show()
plot_importance(model)
<console>
PassengerId Survived Pclass ... Fare Cabin Embarked
0 1 0 3 ... 7.2500 NaN S
1 2 1 1 ... 71.2833 C85 C
2 3 1 3 ... 7.9250 NaN S
[3 rows x 12 columns]
Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
dtype='object')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
None
PassengerId False
Survived False
Pclass False
Name False
Sex False
Age True
SibSp False
Parch False
Ticket False
Fare False
Cabin True
Embarked True
dtype: bool
(714, 12)
Pclass Age Sex
0 3 22.0 male
1 1 38.0 female
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
df_x.loc[:, 'Sex'] = LabelEncoder().fit_transform(df_x['Sex'])
Pclass Age Sex
0 3 22.0 1
1 1 38.0 0
2 3 26.0 0
3 1 35.0 0
4 3 35.0 1
Pclass Age Sex
0 3 22.0 1
1 1 38.0 0
0 0
1 1
Name: Survived, dtype: int64
f_class s_class t_class
0 0.0 0.0 1.0
1 1.0 0.0 0.0
Pclass Age Sex f_class s_class t_class
0 3 22.0 1 0.0 0.0 1.0
1 1 38.0 0 1.0 0.0 0.0
2 3 26.0 0 0.0 0.0 1.0
3 1 35.0 0 1.0 0.0 0.0
4 3 35.0 1 0.0 0.0 1.0
6 1 54.0 1 1.0 0.0 0.0
7 3 2.0 1 0.0 0.0 1.0
8 3 27.0 0 0.0 0.0 1.0
9 2 14.0 0 0.0 1.0 0.0
10 3 4.0 0 0.0 0.0 1.0
(535, 6) (179, 6) (535,) (179,)
예측값 : [1 0 0 0 0]
실제값 : [1 0 0 0 1]
acc : 0.8212290502793296
acc : 0.8212290502793296
[0.76223776 0.83216783 0.82517483 0.83216783 0.83098592]
0.816546833448242
특성(변수) 중요도 : [0.0561767 0.55458455 0.302526 0.03068822 0.0131424 0.04288215]