버섯분류 데이터 셋

버섯분류 데이터 셋

df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/mushroom/main/mushpre.csv')
df = pd.read_csv('mushpre.csv')
df.head(3)
class cap-shape cap-surface cap-color gill-attachment stalk-color-above-ring stalk-color-below-ring veil-type veil-color ring-number habitat
0 p x s n f w w p w o u
1 e x s y f w w p w o g
2 e b s w f w w p w o m

Question 1

데이터를 df변수에 입력받고 각 열의 중복되지않는 원소의 수로 구성된 데이터 프레임을 형성하라. uniqueDf 변수에 저장하고 개수에 따른 내림차순 정렬 후 상위 3개 데이터를 출력하라

lst=[]
for col in df.columns:
    lst.append([col,len(df[col].unique())])

uniqueDf = pd.DataFrame(lst).rename(columns={0:'className',1:'Counts'}).sort_values('Counts',ascending=False)
uniqueDf.head(3)
className Counts
3 cap-color 10
5 stalk-color-above-ring 9
6 stalk-color-below-ring 9

Question 2

종속변수를 y (class)와 독립변수를 x 의 변수에 저장하여라. 변수타입 중 ‘veil-color’는 value 값이 1가지밖에 없으므로 제거하고 사용한다

y = df['class'].map(lambda x : 0 if x =='p' else 1 )
x = df.drop(['class','veil-type'],axis=1)
y.head(3)
0    0
1    1
2    1
Name: class, dtype: int64
x.head(3)
cap-shape cap-surface cap-color gill-attachment stalk-color-above-ring stalk-color-below-ring veil-color ring-number habitat
0 x s n f w w w o u
1 x s y f w w w o g
2 b s w f w w w o m

Question 2

독립변수 x를 LabelEncode하여 x_label변수에 저장하라

from sklearn import preprocessing
le = preprocessing.LabelEncoder()

x_label = x.copy()
for v in x_label.columns:
    x_label[v] = le.fit_transform(x_label[v])
x_label.head(3)
cap-shape cap-surface cap-color gill-attachment stalk-color-above-ring stalk-color-below-ring veil-color ring-number habitat
0 5 2 4 1 7 7 2 1 5
1 5 2 9 1 7 7 2 1 1
2 0 2 8 1 7 7 2 1 3

Question 3

훈련 데이터셋과 테스트 데이터를 7:3으로 나누고 층화추출하여라

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(x_label, y, test_size=0.3, random_state=60,stratify=y)
X_train.shape  ,X_test.shape ,y_train.shape ,y_test.shape
((5686, 9), (2438, 9), (5686,), (2438,))
y_train.value_counts()
1    2945
0    2741
Name: class, dtype: int64

Question 4

SMOTE 방식을 이용하여 훈련 데이터의 부족한 종속변수 class를 over sampling 하라

from imblearn.over_sampling import SMOTE

smote = SMOTE(random_state=0)
#X_train_over,y_train_over = smote.fit_sample(X_train,y_train)
X_train_over,y_train_over = smote.fit_resample(X_train,y_train)
y_train_over.value_counts()
1    2945
0    2945
Name: class, dtype: int64

Question 5

랜덤포레스트 방식을 이용하여 분류모델을 만들고 학습하라. 모델평가를 테스트셋으로 진행하고 accuracy, precision, recall 값을 구하여라

from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier(max_depth=2, random_state=0)
clf.fit(X_train_over, y_train_over)

from sklearn.metrics import classification_report

y_pred = clf.predict(X_test)
report =classification_report(y_test, y_pred, target_names=['class 0', 'class 1'])
print(report)
              precision    recall  f1-score   support

     class 0       0.82      0.61      0.70      1175
     class 1       0.71      0.87      0.78      1263

    accuracy                           0.75      2438
   macro avg       0.76      0.74      0.74      2438
weighted avg       0.76      0.75      0.74      2438

Question 6

테스트셋에 대해 ROC커브를 그리고 auc 값을 측정하라

lr_probs = clf.predict_proba(X_test)

lr_probs = lr_probs[:, 1]

ns_probs = [0 for _ in range(len(y_test))]

from sklearn.metrics import roc_auc_score ,roc_curve

ns_auc = roc_auc_score(y_test, ns_probs)
lr_auc = roc_auc_score(y_test, lr_probs)

ns_fpr, ns_tpr, _ = roc_curve(y_test, ns_probs)
lr_fpr, lr_tpr, _ = roc_curve(y_test, lr_probs)
plt.plot(ns_fpr, ns_tpr, linestyle='--', label='base line')
plt.plot(lr_fpr, lr_tpr, marker='.', label='Logistic')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('label-encoding',fontsize=15)
plt.legend()
plt.show()
print('base line: ROC AUC=%.3f' % (ns_auc))
print('pred: ROC AUC=%.3f' % (lr_auc))
../../_images/main_25_0.png
base line: ROC AUC=0.500
pred: ROC AUC=0.856

Question 7

학습한 모델의 변수 중요도를 아래의 그래프 처럼 출력하라

importance = clf.feature_importances_

importanceDf = pd.DataFrame({'name':x.columns,'impor':importance}).sort_values('impor',ascending=False)

plt.figure(figsize=(14,5))
plt.bar(importanceDf.name,importanceDf.impor)
plt.xticks(rotation=14)
plt.title('Feature importance',fontsize=15)
plt.show()
../../_images/main_27_0.png

Question 8

독립변수를 Label encoding 방식이 아닌 one-hot encoding 방식으로 데이터를 변환 하여 x_dum 변수에 저장하라

x_dum = pd.get_dummies(x)
x_dum.head(3)
cap-shape_b cap-shape_c cap-shape_f cap-shape_k cap-shape_s cap-shape_x cap-surface_f cap-surface_g cap-surface_s cap-surface_y ... ring-number_n ring-number_o ring-number_t habitat_d habitat_g habitat_l habitat_m habitat_p habitat_u habitat_w
0 0 0 0 0 0 1 0 0 1 0 ... 0 1 0 0 0 0 0 0 1 0
1 0 0 0 0 0 1 0 0 1 0 ... 0 1 0 0 1 0 0 0 0 0
2 1 0 0 0 0 0 0 0 1 0 ... 0 1 0 0 0 0 1 0 0 0

3 rows × 54 columns

Question 9

위의 학습 과정을 반복한다. 기존에 사용한 random_state값은 고정한다 smote 층화추출, randomforest 학습, 모델 평가 ,roc 커브 , auc값 추출

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(x_dum, y, test_size=0.3, random_state=60,stratify=y)

smote = SMOTE(random_state=0)
#X_train_over,y_train_over = smote.fit_sample(X_train,y_train)
X_train_over,y_train_over = smote.fit_resample(X_train,y_train)

clf = RandomForestClassifier(max_depth=2, random_state=0)
clf.fit(X_train_over, y_train_over)

y_pred = clf.predict(X_test)

report= classification_report(y_test, y_pred, target_names=['class 0', 'class 1'])
print(report)
              precision    recall  f1-score   support

     class 0       0.81      0.73      0.77      1175
     class 1       0.77      0.84      0.80      1263

    accuracy                           0.79      2438
   macro avg       0.79      0.78      0.78      2438
weighted avg       0.79      0.79      0.79      2438
lr_probs = clf.predict_proba(X_test)

lr_probs = lr_probs[:, 1]

ns_probs = [0 for _ in range(len(y_test))]

from sklearn.metrics import roc_auc_score ,roc_curve

ns_auc = roc_auc_score(y_test, ns_probs)
lr_auc = roc_auc_score(y_test, lr_probs)

ns_fpr, ns_tpr, _ = roc_curve(y_test, ns_probs)
lr_fpr, lr_tpr, _ = roc_curve(y_test, lr_probs)
plt.plot(ns_fpr, ns_tpr, linestyle='--', label='base line')
plt.plot(lr_fpr, lr_tpr, marker='.', label='Logistic')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.legend()
plt.title('one-hot-encoding',fontsize=15)
plt.show()
print('base line: ROC AUC=%.3f' % (ns_auc))
print('pred: ROC AUC=%.3f' % (lr_auc))
../../_images/main_34_0.png
base line: ROC AUC=0.500
pred: ROC AUC=0.910