3 minutes
今さら言語処理100本ノック #6 後半
使用するパラメータや変数の一部は前半で使用したものを使っています。
55. 混同行列の作成
52 で学習したロジスティック回帰モデルの混同行列(confusion matrix)を,学習データおよび評価データ上で作成せよ.
from sklearn.metrics import confusion_matrix
print("訓練データ")
print('confusion matrix = \n', confusion_matrix(y_true=train_Y, y_pred=train_Y_pred))
print()
print("検証データ")
print('confusion matrix = \n', confusion_matrix(y_true=valid_Y, y_pred=valid_Y_pred))
訓練データ
confusion matrix =
[[4522 12 0 23]
[ 13 4165 0 2]
[ 10 7 727 0]
[ 50 17 1 1135]]
検証データ
confusion matrix =
[[511 11 3 18]
[ 13 524 2 3]
[ 15 11 62 4]
[ 33 26 0 100]]
前回記事と比較してみて要素数は合っていそうです。
56. 適合率,再現率,F1 スコアの計測
52 で学習したロジスティック回帰モデルの適合率,再現率,F1 スコアを,評価データ上で計測せよ.カテゴリごとに適合率,再現率,F1 スコアを求め,カテゴリごとの性能をマイクロ平均(micro-average)とマクロ平均(macro-average)で統合せよ.
from sklearn.metrics import precision_score, recall_score, f1_score
# 適合率,再現率,F1スコア
print('適合率: ', precision_score(y_true=valid_Y, y_pred=valid_Y_pred, average='macro'))
print('再現率: ', recall_score(y_true=valid_Y, y_pred=valid_Y_pred, average='macro'))
print('F1スコア: ', f1_score(y_true=valid_Y, y_pred=valid_Y_pred, average='macro'))
適合率: 0.8837034234422294
再現率: 0.8026754172370425
F1スコア: 0.8353613834243956
適合率
は分類されたものが実際にそのクラスである割合、
再現率
はあるクラスのうち、実際にそのクラスに分類された割合
F1スコア
は適合率と再現率の調和平均
57. 特徴量の重みの確認
52 で学習したロジスティック回帰モデルの中で,重みの高い特徴量トップ 10 と,重みの低い特徴量トップ 10 を確認せよ.
weights = {}
for i,w in enumerate(lr.coef_[0]):
weights[dct[i]] = w
sw = sorted(weights.items(), key=lambda x: x[1])
print("低いの")
print(*sw[:10], sep="\n")
print()
print("重いの")
print(*sw[-10:], sep="\n")
低いの
('Aereo', -1.4943036354257244)
('Ebola', -1.1926602012817413)
('past', -1.1663878014633782)
('virus', -1.1543506450531948)
('video', -1.1108024121277575)
('Hat', -1.101384620566056)
('baby', -1.0766692762320573)
('child', -1.0604199141307464)
('soda', -1.0543633796789418)
('Activision', -1.041767185267918)
重いの
('Uber', 1.4360522689124577)
('profit', 1.456241534603359)
('China', 1.4986359849111417)
('bank', 1.5456660201232657)
('Argentina', 1.5867187020325588)
('ECB', 1.7131083455287186)
('Yellen', 1.749698918090413)
('Fed', 1.8263312436827537)
('Ukraine', 1.8665880775606447)
('Bank', 1.9822040580267537)
58. 正則化パラメータの変更
ロジスティック回帰モデルを学習するとき,正則化パラメータを調整することで,学習時の過学習(overfitting)の度合いを制御できる.異なる正則化パラメータでロジスティック回帰モデルを学習し,学習データ,検証データ,および評価データ上の正解率を求めよ.実験の結果は,正則化パラメータを横軸,正解率を縦軸としたグラフにまとめよ.
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
lrl1 = LogisticRegression(penalty="l1", solver='liblinear', max_iter=1000)
lrl1.fit(train_X, train_Y)
train_Y_pred = lrl1.predict(train_X)
valid_Y_pred = lrl1.predict(valid_X)
print('訓練データ:', accuracy_score(y_true=train_Y, y_pred=train_Y_pred))
print('検証データ:', accuracy_score(y_true=valid_Y, y_pred=valid_Y_pred))
訓練データ: 0.9514226881317859
検証データ: 0.875748502994012
前回記事をまんま流用L1正則化
で学習させました。
59. ハイパーパラメータの探索
学習アルゴリズムや学習パラメータを変えながら,カテゴリ分類モデルを学習せよ.検証データ上の正解率が最も高くなる学習アルゴリズム・パラメータを求めよ.また,その学習アルゴリズム・パラメータを用いたときの評価データ上の正解率を求めよ.
アルゴリズムl1
, l2
においてそれぞれC
を1/100, 1/10, 1, 10, 100
と変化させつつ学習結果を見る。
params = [{
"model": LogisticRegression,
"penalty": penalty,
"solver": solver,
"C": 10**i,
}
for i in range(-2, 3)
for penalty, solver in [("l1", "liblinear"), ("l2", "lbfgs")]]
for p in params:
lr = p["model"](C=p["C"], penalty=p["penalty"], solver=p["solver"], max_iter=1000)
lr.fit(train_X, train_Y)
valid_Y_pred = lr.predict(valid_X)
acc = accuracy_score(y_true=valid_Y, y_pred=valid_Y_pred)
p["acc"] = acc
params.sort(key=lambda x: x.get("acc"))
print(*params, sep="\n")
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l1', 'solver': 'liblinear', 'C': 0.01, 'acc': 0.5883233532934131}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l2', 'solver': 'lbfgs', 'C': 0.01, 'acc': 0.7567365269461078}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l1', 'solver': 'liblinear', 'C': 0.1, 'acc': 0.7574850299401198}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l2', 'solver': 'lbfgs', 'C': 0.1, 'acc': 0.8562874251497006}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l1', 'solver': 'liblinear', 'C': 1, 'acc': 0.875748502994012}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l1', 'solver': 'liblinear', 'C': 100, 'acc': 0.8809880239520959}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l2', 'solver': 'lbfgs', 'C': 100, 'acc': 0.8832335329341318}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l1', 'solver': 'liblinear', 'C': 10, 'acc': 0.8884730538922155}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l2', 'solver': 'lbfgs', 'C': 1, 'acc': 0.8959580838323353}
{'model': <class 'sklearn.linear_model._logistic.LogisticRegression'>, 'penalty': 'l2', 'solver': 'lbfgs', 'C': 10, 'acc': 0.8974550898203593}
正規化度合い(C 値)が影響を与えているのがよくわかりますね。
その中でもL2正規化
のC=10
が一番いい結果になりました。