<jupyter_start><jupyter_text>Load Data<jupyter_code>print(df.shape)
df.head()
df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 1091 entries, 0 to 1090
Data columns (total 18 columns):
label             1091 non-null int64
artist            1091 non-null object
album             1091 non-null object
genre             1091 non-null object
single_count      1091 non-null int64
freq_billboard    1091 non-null int64
freq_genius       1091 non-null int64
freq_theSource    1091 non-null int64
freq_xxl          1091 non-null int64
rating_AOTY       61 non-null float64
rating_meta       324 non-null float64
rating_pitch      220 non-null float64
twitter           1091 non-null int64
instagram         1091 non-null int64
facebook          1091 non-null int64
spotify           1091 non-null int64
soundcloud        1091 non-null int64
youtube           1091 non-null int64
dtypes: float64(3), int64(12), object(3)
memory usage: 153.5+ KB<jupyter_text>**Note**- 온라인매체 기사의 양, 평론가 평점은 Null Value가 있기 때문에, 당장 Decision Tree를 통해 학습을 시킬 수 없어, Feature에서 제외를 한다.  Data Preparation for Modeling  장르 `hiphop`, `R&B`, `Soul`, `Funk`, `Pop`<jupyter_code>df = pd.get_dummies(df, columns=['genre'])
df.columns<jupyter_output><empty_output><jupyter_text>Split train & test data<jupyter_code>feature_names = ['single_count', 
                 'freq_billboard', 'freq_genius', 'freq_theSource', 'freq_xxl',
                 'twitter', 'instagram', 'facebook',
                 'spotify', 'soundcloud', 'youtube',
                 'genre_funk', 'genre_hiphop', 'genre_pop', 'genre_rnb', 'genre_soul']
dfX = df[feature_names].copy()
dfy = df['label'].copy()
dfX.tail()
dfy.tail()
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(dfX, dfy, test_size=0.25, random_state=0)<jupyter_output><empty_output><jupyter_text>Decision Tree<jupyter_code>from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(criterion='entropy', max_depth=10, min_samples_leaf=7).fit(X_train, y_train)
import io
import pydot
from IPython.core.display import Image 
from sklearn.tree import export_graphviz

def draw_decision_tree(model):
    dot_buf = io.StringIO() 
    export_graphviz(model, out_file=dot_buf, feature_names=dfX.columns)
    graph = pydot.graph_from_dot_data(dot_buf.getvalue())[0] 
    image = graph.create_png()
    return Image(image)


def plot_decision_regions(X, y, model, title):
    resolution = 0.01
    markers = ('s', '^', 'o')
    colors = ('red', 'blue', 'lightgreen')
    cmap = mpl.colors.ListedColormap(colors[:len(np.unique(y))])
    
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
    Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape(xx1.shape)
    
    plt.contour(xx1, xx2, Z, cmap=mpl.colors.ListedColormap(['k']))
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1], alpha=0.8, c=cmap(idx), marker=markers[idx], s=80, label=cl)

    plt.xlabel(dfX.columns)
    plt.ylabel(dfy.columns)
    plt.legend(loc='upper left')
    plt.title(title)
    
    return Z
draw_decision_tree(model)
from sklearn.metrics import confusion_matrix
confusion_matrix(y_train, model.predict(X_train))
confusion_matrix(y_test, model.predict(X_test))
from sklearn.metrics import classification_report

print(classification_report(y_train, model.predict(X_train)))
print(classification_report(y_test, model.predict(X_test)))
for name, importance in zip(dfX.columns, model.feature_importances_):
    print(name, importance)
from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(y_test, model.predict_proba(X_test)[:, 1])
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))

plt.plot(fpr, tpr, label="Decision Tree")
plt.legend()
plt.plot([0, 1], [0, 1], 'k--', label="random guess")
plt.xlabel('False Positive Rate (Fall-Out)')
plt.ylabel('True Positive Rate (Recall)')
plt.title('Receiver operating characteristic example')
plt.show()
from sklearn.metrics import auc
auc(fpr, tpr)<jupyter_output><empty_output><jupyter_text>Random Forest<jupyter_code>from sklearn.ensemble import RandomForestClassifier
model2 = RandomForestClassifier(criterion='entropy', n_estimators=10, max_depth=10, 
                                min_samples_split=5 , min_samples_leaf=5
                                ).fit(X_train, y_train)
confusion_matrix(y_train, model2.predict(X_train))
confusion_matrix(y_test, model2.predict(X_test))
print(classification_report(y_train, model2.predict(X_train)))
print(classification_report(y_test, model2.predict(X_test)))
fpr, tpr, thresholds = roc_curve(y_test, model2.predict_proba(X_test)[:, 1])

plt.figure(figsize=(10, 10))

plt.plot(fpr, tpr, label="Decision Tree")
plt.legend()
plt.plot([0, 1], [0, 1], 'k--', label="random guess")
plt.xlabel('False Positive Rate (Fall-Out)')
plt.ylabel('True Positive Rate (Recall)')
plt.title('Receiver operating characteristic example')
plt.show()
auc(fpr, tpr)
for name, importance in zip(dfX.columns, model2.feature_importances_):
    print(name, importance)<jupyter_output>single_count 0.02113344205566914
freq_billboard 0.004976718618026675
freq_genius 0.01100244812256996
freq_theSource 0.09062689277411373
freq_xxl 0.052208179451282345
twitter 0.04542646536597916
instagram 0.1282332642114423
facebook 0.03555756636401082
spotify 0.1265149252318301
soundcloud 0.27009151974318535
youtube 0.0672300696557182
genre_funk 0.0
genre_hiphop 0.03661321172836887
genre_pop 0.10665501722865826
genre_rnb 0.0037302794491450493
genre_soul 0.0<jupyter_text>ExtraTree<jupyter_code>from sklearn.ensemble import ExtraTreesClassifier
model3 = ExtraTreesClassifier(criterion='entropy', n_estimators=10, max_depth=10, 
                                min_samples_split=5 , min_samples_leaf=5).fit(X_train, y_train)
confusion_matrix(y_train, model3.predict(X_train))
confusion_matrix(y_test, model3.predict(X_test))
print(classification_report(y_train, model3.predict(X_train)))
print(classification_report(y_test, model3.predict(X_test)))
fpr, tpr, thresholds = roc_curve(y_test, model3.predict_proba(X_test)[:, 1])

plt.figure(figsize=(10, 10))

plt.plot(fpr, tpr, label="Decision Tree")
plt.legend()
plt.plot([0, 1], [0, 1], 'k--', label="random guess")
plt.xlabel('False Positive Rate (Fall-Out)')
plt.ylabel('True Positive Rate (Recall)')
plt.title('Receiver operating characteristic example')
plt.show()
auc(fpr, tpr)<jupyter_output><empty_output><jupyter_text>우리는 Recall (Sensitivity) $ \dfrac{TP}{TP+FN} $ 가 매우 중요하다**Precision의 경우**- False Positive :    - 무시해도 될 신인인데 굳이 컨텐츠를 생산했다.         - 뭐 어때, 에너지 이상한데 소비하긴 했지만 굿.**Recall의 경우**- False Negative:    - 빠르게 컨텐츠를 생산해야 하는 신인인데, 걸러버렸다.        - 다른 매체에 선수를 뺐길 수 있다. 유저 유입이 적어짐.        - 다른 부가 한국에서의 공연 에이전시 계약, 머천다이즈 등 부가적인 기회들을 놓쳐버릴 수 있음.        - 굉.장.히 중요한 부분 !               GridSearch : Random Forest<jupyter_code>from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
RandomForestClassifier.get_params(model2)
# pipe_rfc = Pipeline([('scl', StandardScaler()), ('clf', RandomForestClassifier())])

rfc = RandomForestClassifier()

param_grid = {
    'bootstrap': [True],
     'class_weight': [None],
    'criterion': ['entropy', 'gini'],
    'max_depth': [3, 5, 10, 15, 20, 25, 30, 35, 40, 50],
    'max_features': ['auto'],
    'max_leaf_nodes': [None],
    'min_impurity_decrease': [0.0],
    'min_impurity_split': [None],
    'min_samples_leaf': [2, 3, 4, 5, 7, 10, 12, 15],
    'min_samples_split': [2, 3, 4, 5],
    'min_weight_fraction_leaf': [0.0],
    'n_estimators': [5, 10, 15, 20, 30, 50],
    'random_state': [None],
     'oob_score': [False],
     'verbose': [0],
     'warm_start': [False]
}


gs = GridSearchCV(estimator=rfc, param_grid=param_grid, scoring='recall', cv=10, n_jobs=1)

%%time
gs_result = gs.fit(X_train, y_train)
# gs2 = GridSearchCV(estimator=rfc, param_grid=param_grid, scoring='precision', cv=10, n_jobs=2)
gs.best_score_
gs.best_params_<jupyter_output><empty_output><jupyter_text>Apply Best Parameter from Grid Search<jupyter_code>model4 = RandomForestClassifier(criterion='entropy', n_estimators=15, max_depth=20, 
                                min_samples_split=5, min_samples_leaf=3).fit(X_train, y_train)

confusion_matrix(y_train, model4.predict(X_train))
print(classification_report(y_train, model4.predict(X_train)))
confusion_matrix(y_test, model4.predict(X_test))
print(classification_report(y_test, model4.predict(X_test)))
fpr, tpr, thresholds = roc_curve(y_test, model4.predict_proba(X_test)[:, 1])

plt.figure(figsize=(10, 10))

plt.plot(fpr, tpr, label="Decision Tree")
plt.legend()
plt.plot([0, 1], [0, 1], 'k--', label="random guess")
plt.xlabel('False Positive Rate (Fall-Out)')
plt.ylabel('True Positive Rate (Recall)')
plt.title('Receiver operating characteristic example')
plt.show()
auc(fpr, tpr)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13572357019064124, 'fraction_numerical': 0.06022530329289428, 'mean_word_length': 4.858502538071066, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '224103', 'license': 'MIT', 'n_tokens_mistral': 3998, 'n_tokens_neox': 3674, 'n_words': 706, 'path': 'modeling/modeling-2-tree.ipynb', 'repo_name': 'lucaseo/content-worth-debut-artist-classification-project', 'size': '9232'}