こんにちは!
テービーテックの村松です。
「言語処理100本ノック2020]」
nlp100.github.io
に挑戦中!
途中でくじけないか見守ってください・・・。
そして、皆さんも一緒に挑戦してみましょう!
本日は第 5章:機械学習 55~59です!
間違い・コード改善点などありましたら教えていただけると嬉しいです。
第5章:機械学習
「Fabio Gasparetti氏が公開しているNews Aggregator Data Setを用い,ニュース記事の見出しを「ビジネス」「科学技術」「エンターテイメント」「健康」のカテゴリに分類するタスク(カテゴリ分類)に取り組む.」
ここからは
UCI Machine Learning Repository: News Aggregator Data Set
を使用して問題に取り組んでいきます。
本日の内容の補助知識として、
混同行列・適合率・再現率・F1スコアに関しては
こちらがわかりやすいのでおススメです。
55. 混同行列の作成
「52で学習したロジスティック回帰モデルの混同行列(confusion matrix)を,学習データおよび評価データ上で作成せよ.」
from sklearn.metrics import confusion_matrix import seaborn as sns import matplotlib.pyplot as plt #学習データの混同行列 train_cm = confusion_matrix(y_train, train_predict[1]) print(train_cm) sns.heatmap(train_cm, annot=True, cmap='Blues') plt.show()
##出力 [[4486 5 0 11] [ 7 4227 0 2] [ 4 4 721 0] [ 20 5 0 1180]]
#評価データの混同行列 test_cm = confusion_matrix(y_test, test_predict[1]) print(test_cm) sns.heatmap(test_cm, annot=True, cmap='Blues') plt.show()
##出力 [[546 9 3 17] [ 9 518 0 3] [ 12 12 59 2] [ 20 13 2 109]]
56.適合率・再現率・F1スコアの計測
「52で学習したロジスティック回帰モデルの適合率,再現率,F1スコアを,評価データ上で計測せよ.カテゴリごとに適合率,再現率,F1スコアを求め,カテゴリごとの性能をマイクロ平均(micro-average)とマクロ平均(macro-average)で統合せよ.」
#適合率 from sklearn.metrics import precision_score pre = precision_score(y_test, test_predict[1], average=None, labels=['b','t','e','m']) print (pre) micro_average = precision_score(y_test, test_predict[1], average='micro') macro_average = precision_score(y_test, test_predict[1], average='macro') print('ミクロ平均:' + str(micro_average)) print('マクロ平均:' + str(macro_average))
##出力 [0.93015332 0.83206107 0.9384058 0.921875 ] ミクロ平均:0.9235382308845578 マクロ平均:0.9056237969449723
#結合 pre = np.append(pre, [micro_average, macro_average]) print(pre)
##出力 [0.93015332 0.83206107 0.9384058 0.921875 0.92353823 0.9056238 ]
再現率とF1スコアも同様の手順で算出します。
#再現率 from sklearn.metrics import recall_score rec = recall_score(y_test, test_predict[1], average=None, labels=['b','t','e','m']) micro_average = recall_score(y_test, test_predict[1], average='micro') macro_average = recall_score(y_test, test_predict[1], average='macro') rec = np.append(rec, [micro_average, macro_average]) #Fスコア from sklearn.metrics import f1_score f1 = f1_score(y_test, test_predict[1], average=None, labels=['b','t','e','m']) micro_average = f1_score(y_test, test_predict[1], average='micro') macro_average = f1_score(y_test, test_predict[1], average='macro') f1 = np.append(f1, [micro_average, macro_average])
最後に見やすいようにデータフレーム化します。
#データフレーム化 scores = pd.DataFrame({'適合率':pre, '再現率':rec, 'F1スコア':f1}, index=['b','e','t','m','micro','macro']) scores
57.特徴量の重みの確認
「52で学習したロジスティック回帰モデルの中で,重みの高い特徴量トップ10と,重みの低い特徴量トップ10を確認せよ.」
#カラム名 features = x_train.columns.values #重みの高い特徴量トップ10 for c,coef in zip(model.classes_, model.coef_): idx = np.argsort(coef) print(c,features[idx][-10:][::-1])
##出力 b ['bank' 'fed' 'ecb' 'obamacare' 'yellen' 'ukraine' 'argentina' 'china' 'buy' 'oil'] e ['kardashian' 'chris' 'miley' 'transformers' 'thrones' 'cyrus' 'movie' 'paul' 'trailer' 'met'] m ['ebola' 'cancer' 'fda' 'mers' 'study' 'drug' 'brain' 'cases' 'cigarettes' 'doctors'] t ['facebook' 'google' 'apple' 'climate' 'microsoft' 'tesla' 'nasa' 'fcc' 'moon' 'heartbleed']
#重みの低い特徴量トップ10 for c,coef in zip(model.classes_, model.coef_): idx = np.argsort(coef) print(c,features[idx][:10])
##出力 b ['aereo' 'ebola' 'virus' 'subscription' 'nintendo' 'she' 'cap' 'apple' 'gay' 'my'] e ['google' 'facebook' 'china' 'microsoft' 'gm' 'data' 'ebola' 'study' 'oil' 'climate'] m ['dimon' 'gm' 'facebook' 'ceo' 'apple' 'twitter' 'climate' 'google' 'jobs' 'sales'] t ['stocks' 'percent' 'still' 'office' 'concerns' 'fed' 'thrones' 'drug' 'grows' 'movie']
58.正則化パラメータの変更
「ロジスティック回帰モデルを学習するとき,正則化パラメータを調整することで,学習時の過学習(overfitting)の度合いを制御できる.異なる正則化パラメータでロジスティック回帰モデルを学習し,学習データ,検証データ,および評価データ上の正解率を求めよ.実験の結果は,正則化パラメータを横軸,正解率を縦軸としたグラフにまとめよ.」
result = [] C = np.logspace(-5, 4, 10, base=10) for c in C: #モデルの学習 model = LogisticRegression(random_state=0, max_iter=5000, C=c) model.fit(x_train, y_train) #それぞれの予測値 train_predict = predict(model, x_train) val_predict = predict(model, x_val) test_predict = predict(model, x_test) #正解率の計算 train_acc = accuracy_score(y_train, train_predict[1]) val_acc = accuracy_score(y_val, val_predict[1]) test_acc = accuracy_score(y_test, test_predict[1]) #resultに格納 result.append([c, train_acc, val_acc, test_acc]) result = np.array(result).T result
##出力 array([[1.00000000e-05, 1.00000000e-04, 1.00000000e-03, 1.00000000e-02, 1.00000000e-01, 1.00000000e+00, 1.00000000e+01, 1.00000000e+02, 1.00000000e+03, 1.00000000e+04], [4.21945277e-01, 5.58470765e-01, 7.21045727e-01, 7.86356822e-01, 9.27380060e-01, 9.94565217e-01, 9.98969265e-01, 9.99062969e-01, 9.99062969e-01, 9.99062969e-01], [4.12293853e-01, 5.52473763e-01, 7.00899550e-01, 7.61619190e-01, 8.65067466e-01, 9.04797601e-01, 9.07046477e-01, 9.07046477e-01, 9.05547226e-01, 9.01799100e-01], [4.31034483e-01, 5.57721139e-01, 7.16641679e-01, 7.78110945e-01, 8.88305847e-01, 9.23538231e-01, 9.24287856e-01, 9.27286357e-01, 9.23538231e-01, 9.20539730e-01]])
#可視化 plt.plot(result[0], result[1], label='train') plt.plot(result[0], result[2], label='val') plt.plot(result[0], result[3], label='test') plt.ylim(0, 1.1) plt.ylabel('Accuracy') plt.xscale('log') plt.xlabel('C') plt.legend() plt.show()
59.ハイパーパラメータの探索
「学習アルゴリズムや学習パラメータを変えながら,カテゴリ分類モデルを学習せよ.検証データ上の正解率が最も高くなる学習アルゴリズム・パラメータを求めよ.また,その学習アルゴリズム・パラメータを用いたときの評価データ上の正解率を求めよ.」
import itertools def calc_scores(C,class_weight): #モデルの宣言 model = LogisticRegression(random_state=0, max_iter=10000, C=C, class_weight=class_weight) #モデルの学習 model.fit(x_train, y_train) #モデルの検証 y_train_pred = model.predict(x_train) y_valid_pred = model.predict(x_val) y_test_pred = model.predict(x_test) #スコア scores = [] scores.append(accuracy_score(y_train, y_train_pred)) scores.append(accuracy_score(y_val, y_valid_pred)) scores.append(accuracy_score(y_test, y_test_pred)) return scores # Cとclass_weightの総当たりの組み合わせを試します C = np.logspace(-5, 4, 10, base=10) class_weight = [None, 'balanced'] best_parameter = None best_scores = None max_valid_score = 0 #itertools.product()で全ての組み合わせを作成 for c, w in itertools.product(C, class_weight): # ハイパーパラメータの組み合わせの表示 print(c, w) #ハイパーパラメータの組み合わせで関数の実行 scores = calc_scores(c, w) #前のスコアより高ければ結果を更新 if scores[1] > max_valid_score: max_valid_score = scores[1] best_parameter = [c, w] best_scores = scores #最適なハイパーパラメータの組み合わせとスコアの表示 print ('C: ', best_parameter[0], 'solver: ', 'class_weight: ', best_parameter[1]) print ('best scores: ', best_scores) print ('test accuracy: ', best_scores[2])
##出力 1e-05 None 1e-05 balanced ~中略~ 10000.0 None 10000.0 balanced C: 1.0 solver: class_weight: balanced best scores: [0.9921289355322339, 0.9160419790104948, 0.9212893553223388] test accuracy: 0.9212893553223388
ここまでご覧いただきありがとうございます。
以上、第6章55~59でした!