【Aidamy】 ディープラーニングで手書き文字を識別してみよう④
前回に引き続き。
Aidemyの手書き文字認識コースをやっていく。
今回は機械学習概論。
機械学習概論
機械学習が今注目される理由
- 人間では到底実現不可能な時間で、大量のデータから自動的に短時間で正確な結果を得ることができる
- 画像、音声、マーケティング、自然言語、医療など様々な分野で進化を発揮
- コンピュータの処理速度が向上し、豊富なデータの解析に耐えうるデバイスが登場
機械学習とは
- データから反復的に学習し、そこに潜むパターンを探しだすこと
- 機械学習は大きく3つに分けられる
- 教師あり学習(Supervised Learnings)
- 教師なし学習(Unspervised Learnings)
- 強化学習(Reinforcement Learnings)
教師あり学習
- 「教師」とは「データに付随する正解ラベル」のこと
- データと正解ラベルの例
- 手書き数字画像 -> その画像が表す数字
- 動物の写真 -> 写っている動物
- 文章 -> 作者
- ある部屋に関する定量的な条件 -> 家賃
- 上3つの様にカテゴリを予測するものは「分類問題」
- 一番下の様に数値を予測するものは「回帰問題」
- 教師あり学習の流れ
- 様々なデータをコンピュータに与え、「正解ラベル」を学習し、「正解ラベル」を出力するようにモデルを学習
- 学習したモデルに未知のデータを適用した時に【正解ラベル」に近い値が出るかどうか検証
教師なし学習
- 与えられたデータから規則性を発見し、学習する手法
- 予め答えが与えられないため、正解や不正解がない
- 以下の様な場面で用いられる
- おすすめの商品やメニューを推薦するレコメンデーション
- 多次元データを人間が可視化しやすいように圧縮
- 自然言語処理などの分野で情報を圧縮
強化学習
- 「エージェント」と「環境」が存在
- エージェントは環境に対してある行動をする
- その結果として環境がエージェントに報酬を与える
- エージェントはその報酬に基づいて次の行動を決定
- 深層学習と組み合わせて用いられ、囲碁や将棋、ロボットの操作制御などで用いられている
- 正解ラベルがなくてもコンピュータが自動的に「良い」評価になるような動き方を学習する
機械学習の流れ
全体の流れ
データの学習
- 例えばデータを直線で2つに分けるタスクであれば、ある線を引き、妥当かどうかを確認し、修正、また線を引く、ということを反復し、その結果として正しい線が引けるように鳴る
- コンピュータ自身が、自分で答えを見つけ、データのパターンから作られた基準をモデルという
学習データとテストデータ
- 学習に用いられるデータを学習データ(トレーニングデータ)、精度評価に用いられるデータをテストデータと呼ぶ
- テストデータは未知のデータである必要がある
ホールドアウト法
- 与えられたデータセットをトレーニングデータとテストデータの2つに分割するシンプルな手法
scikit-learn
のtrain_test_split
を用いれば以下の様に分割できるtest_size
でテストデータの割合を指定random_state
を指定すると毎回同じ様にテストデータが分割される
from sklearn import datasets from sklearn.model_selection import train_test_split iris = datasets.load_iris() x = iris.data y = iris.target x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
k-分割交差検証(クロスバリデーション)
- トレーニングデータセットをk分割し、そのうちのk-1個のデータを学習用のデータセットとして用い、残りの1個をモデルのテストに用いる手法
- k回の学習と評価を繰り返し、そのk個の性能評価の平均を酉、平均性能を算出する
- データセットが小さい場合、分割の個数をデータセットと同じ数にして行う「一個抜き」(Leave-One-Out: LOO)交差検証が推奨される
sklearn
のcross_validation
を用いることで実行できる- 以下はSVMの例
import numpy as np from sklearn import svm, datasets, cross_validation iris = datasets.load_iris() x = iris.data y = iris.target svc = svm.SVC(c=1, kernel='rbf', gamma=0.001) scores = cross_validation.cross_val_score(svc, x, y, cv=5)
過学習(オーバーフィッティング)
- 与えられたデータに適用しすぎてしまい、正しい基準が構築されないこと
- 過学習の解決手段
- 逆にデータを学習できていない状態を学習不足と呼ぶ
- 過学習を起こしているモデルのことをバリアンスが高いという
- 学習不足を起こしているモデルのことをバイアスが高いという
アンサンブル学習
- 複数のモデルに学習させることによってデータの一般化を獲得しようとする試み
- 2種類の手法が存在
- バギング:複数のモデルを同時に学習させ、予測結果の平均を取ることで予測結果の汎化を試みる
- ブースティング:モデルの予測結果に対するモデルを作成し汎化性能を高める
性能評価指標
混同行列
- 学習済みモデルがどの程度良いものであるかを判断する評価指標の一つ
- 書くテストデータに対する予測結果を真陽性(True Positive: TP)、真陰性(True Negative: TN)、偽陽性(Falase Positive: FP)、偽陰性(False Negative: FN)の④つの観点で分類し、それぞれに当てはまる予測結果の個数をまとめた表
- 「真か偽」は予測が的中したかどうか/「陽性か陰性」は予測されたクラス
sklearn.metrics
モジュール内のconfusion_matrix
関数を利用して実装
from sklearn.metrics import confusion_matrix # 0: 陽性 / 1: 陰性 y_true = [0, 0, 0, 1, 1, 1] y_pred = [1, 0, 0, 1, 1, 1] confmat = confusion_matrix(y_true, y_pred) print(confmat) # Output # [[2 1] # [0 3]]
正解率
- すべての事象の中で予測結果があっていた数の割合
[tex: 正解率=\frac{TP+TN}{FP+FN+TP+TN}]
F値
- データに偏りがある状態で正解率という指標を使うのは危険
- そこで適合率/精度(precision)、再現率(recall)、F値という値が用いられる
- 適合率/精度(precision):陽性と予測されたデータのうち、実際に陽性であるものの割合
- 再現率:実際の陽性データのうち陽性と予測できたものの割合
- F値:適合率と再現率の調和平均
- どの指標も0~1の範囲で示され、1に近い方が性能が良い
[tex: 適合率=\frac{TP}{FP+TP}] [tex: 再現率=\frac{TP}{FN+TP}] [tex: F値=2\frac{適合率\times再現率}{適合率+再現率}]
性能評価指標の実装
from sklearn.metrics import precision_score, recall_score, f1_score y_true = [0, 1, 1, 0, 1] y_pred = [1, 0, 1, 1, 1] precision_score(y_true, y_pred) recall_score(y_true, y_pred) f1_score(y_true, y_pred)
再現率と適合率の関係
- 2つの性能評価指標はトレードオフの関係にある
- 具体例
PR曲線
- 横軸を再現率縦軸を適合率としてデータをプロットしたグラフを表したもの
- 陽性と識別されたデータに対して一つずつ適合率と再現率を計算
PR曲線を用いたモデルの評価
- 適合率と再現率はトレードオフだが、適合率と再現率が一致するブレークイーブンポイント(BEP)が存在する
- BEPは適合率と再現率の関係をバランスよく保ったままコストと利益を最適化できるので、ビジネス上重要な点
- PR曲線においてBEPが右上に遷移するほどよいモデル
しばらく放置しちゃったから時間かかったけどなんとか終わった、、、。