• Pima Indians Diabetes Database | Kaggle
Pima Indians Diabetes Database
Predict the onset of diabetes based on diagnostic measures
www.kaggle.com
: 의사결정나무 분류
DecisionTreeClassifier(
*,
criterion='gini', # 분할방법 {"gini", "entropy"}, default="gini"
splitter='best',
max_depth=None, # The maximum depth of the tree
min_samples_split=2, # The minimum number of samples required to split an internal node
min_samples_leaf=1, # The minimum number of samples required to be at a leaf node.
min_weight_fraction_leaf=0.0, # The minimum weighted fraction of the sum total of weights
max_features=None, # The number of features to consider when looking for the best split
random_state=None,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
class_weight=None,
ccp_alpha=0.0,
)
# train: test = 8:2로 나누기
split_count = int(df.shape[0] * 0.8)
train = df[:split_count] #(614, 9)
test = df[split_count:] #(154, 9)
# 학습, 예측에 사용할 컬럼
feature_names = df.columns.tolist()
# 정답컬럼제거
feature_names.remove("Outcome")
#정답값이자 예측할 값
label_name = "Outcome"
X_train = train[feature_names]
y_train = train[label_name]
X_test = test[feature_names]
y_test = test[label_name]
# X, y를 만들어 줍니다.
X = df[feature_names]
y = df[label_name]
# train_test_split 으로 무작위로 데이터셋을 train 과 test 로 나눕니다.
# 분류문제에서는 stratify를 기본값으로 사용하는 것을 추천
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42)
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(max_depth=3, max_features=0.98, random_state=42)
model.fit(X_train, y_train)
y_predict = model.predict(X_test)
# 방법1.
(y_test == y_predict).mean()
#방법2.
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_predict)
#방법3.
model.score(X_test, y_test)
>>> #0.7532467532467533
from sklearn.tree import plot_tree
plt.figure(figsize=(20,20))
plot_tree(model,
feature_names=feature_names,
filled=True,
fontsize=14)
plt.show()
Decision Tree의 장점 중 하나는 피처 중요도를 추출할 수 있다는 점이다.
sns.barplot(x=model.feature_imporances_, y=model.feature_names_in_)
# 새 컬럼 만들기
df["Insulin_nan"] = df["Insulin"].replace(0, np.nan)
# 발병여부에 따른 평균, 중앙값 구하기
# 0 값을 결측치로 만들지 않고 구할 때와 결측치로 만들고 구할때가 차이가 남
# 반드시 결측치형태로 만들고 구해줄 것
Insulin_mean = df.groupby("Outcome")["Insulin_nan"].mean()
>>>Outcome
0 130.287879
1 206.846154
# 결측치 채우기
df["Insulin_fill"] = df["Insulin_nan"]
df.loc[(df["Insulin_nan"].isnull())&(df["Outcome"]==0), "Insulin_fill"] = Insulin_mean[0]
df.loc[(df["Insulin_nan"].isnull())&(df["Outcome"]==1), "Insulin_fill"] = Insulin_mean[1]
desc = df["Insulin_nan"].describe()
desc
>>>
#count 394.000000
#mean 155.548223
#std 118.775855
#min 14.000000
#25% 76.250000
#50% 125.000000
#75% 190.000000
#max 846.000000
IQR = desc['75%'] - desc['25%']
max_out = desc['75%'] + (1.5*IQR)
max_out
>>> #360.625
df = df[df["Insulin_fill"] < max_out]
df.shape
>>> #(744, 12)
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(max_depth=6, min_samples_leaf=6, random_state=42)
model.fit(X_train, y_train)
y_predict = model.predict(X_test)
(y_test == y_predict).mean()
>>> #0.9261744966442953
sns.barplot(x = model.feature_importances_, y = model.feature_names_in_)
결론
하이퍼파라미터 : 머신러닝 모델을 생성할 때 사용자가 직접 설정하는 값으로, 이를 어떻게 설정하느냐에 따라 모델의 성능이 달라진다.
수동튜닝 : 만족할 만한 하이퍼파라미터들의 조합을 찾을 때 까지 수동으로 조절
GridSearhCV() : 시도할 하이퍼파라미터들을 지정하면 모든 조합에 대해 교차검증 후 가장 좋은 성능을 내는 하이퍼파라미터 조합을 찾음
RandomizedSearchCV() : GridSearch와 동일한 방식으로 사용하지만 모든 조합을 다 시도하지 않고, 각 반복마다 임의의 값만 대입해 지정한 횟수만큼 평가
# 파라미터 후보 설정
parameters = {"max_depth":list(range(3, 18, 2)),
"max_features":[0.3, 0.5, 0.7, 0.8, 0.9]}
from sklearn.model_selection import GridSearchCV
clf = GridSearchCV(model,
parameters,
n_jobs=-1,
cv=5) # train을 5조각으로 나눠서 validation함
clf.fit(X_train, y_train)
>>> GridSearchCV(estimator=DecisionTreeClassifier(random_state=42),
param_grid={'max_depth': [3, 5, 7, 9, 11, 13, 15, 17],
'max_features': [0.3, 0.5, 0.7, 0.8, 0.9]})
clf.best_estimator_
>>> DecisionTreeClassifier(max_depth=9, max_features=0.5, random_state=42)
clf.best_score_
>>> 0.8566839930694389
pd.DataFrame(clf.cv_results_).sort_values("rank_test_score").head()
param_distributions = {"max_depth":np.random.randint(3, 20, 10),
"max_features":np.random.uniform(0.5, 1, 10)}
clfr = RandomizedSearchCV(model,
param_distributions=param_distributions,
n_iter=10,
cv=5,
scoring="accuracy",
n_jobs=-1,
random_state=42, verbose=3)
clfr.fit(X_train, y_train)
clfr.best_estimator_
>>> DecisionTreeClassifier(max_depth=5, max_features=0.8176444614633067,
random_state=42)
clfr.best_params_
>>> {'max_features': 0.8176444614633067, 'max_depth': 5}
clfr.best_score_
>>> 0.8485405837664934
pd.DataFrame(clfr.cv_results_).nsmallest(5, "rank_test_score")
💡 parameters 설정 → 모델링 → .fit(X_train, y_train) → .best_estimator_ → .best_params_ → .best_score_ → pd.DataFrame(.cv_results_).nsmallest(5, "rank_test_score")
# 베스트모델로 학습하기
best_model = clfr.best_estimator_
best_model.fit(X_train, y_train)
>>> DecisionTreeClassifier(max_depth=5, max_features=0.8176444614633067,
random_state=42)
# 예측하기
y_predict = best_model.predict(X_test)
#모델 평가
accuracy_score(y_test, y_predict)
>>> 0.9090909090909091
# 리포트 출력
from sklearn.metrics import classification_report
print(classification_report(y_test, y_predict))
sns.barplot(x = best_model.feature_importances_, y = best_model.feature_names_in_ )
💡 머신러닝 모델링 순서
데이터 → EDA → Feature Engineering → 모델생성 → 하이퍼파라미터튜닝 → 정확도평가
[머신러닝] Titanic 데이터를 사용한 분류: Decision Tree, Binary Encoding, Entropy (0) | 2022.11.17 |
---|---|
[머신러닝] pima 데이터를 사용한 분류: Random Forest (0) | 2022.11.17 |
[머신러닝] INTRO. 머신러닝프로젝트 주요단계(전처리, EDA, Feature Engineering, 교차검증, 하이퍼파라미터튜닝) (0) | 2022.11.17 |
[머신러닝] INTRO. Definition, Tool, 알고리즘 유형 (0) | 2022.11.17 |
시각화 총정리: plotly (1) | 2022.10.28 |