More Related Content
Similar to 分類問題 - 機械学習ライブラリ scikit-learn の活用 (20)
分類問題 - 機械学習ライブラリ scikit-learn の活用
- 2. 自己紹介
内山 雄司 (@y__uti)
◦ http://y-uti.hatenablog.jp/ (phpusers-ja)
仕事
◦ 受託開発の会社 (株式会社ピコラボ) でプログラマをしています
興味
◦ プログラミング言語処理系
◦ 機械学習
2017-05-18 社内勉強会 2
- 5. Iris データセット
2017-05-18 社内勉強会 5
「あやめ」の 3 品種 150 サンプルからなるデータセット
◦ データベースでいうところのテーブルだと思えばよい
◦ 150 行のレコードがあるということ
各サンプルは以下の情報 (カラムだと思えばよい) を持つ
◦ がく片の長さ sepal length
◦ がく片の幅 sepal width
◦ 花びらの長さ petal length
◦ 花びらの幅 petal width
◦ 品種 class
◦ Iris-Setosa
◦ Iris-Versicolor
◦ Iris-Virginica
- 8. 層化抽出法
手持ちのデータは 3 品種それぞれ 50 サンプル
教科書の方法で分割すると各品種の比率は維持されない
2017-05-18 社内勉強会 8
>>> from collections import Counter
>>> sorted(Counter(y_train).items())
[(0, 34), (1, 32), (2, 39)]
層化抽出法:母集団の比率を維持してサンプリングする
◦ train_test_split 関数の stratify オプション
>>> X_train, ... = train_test_split(X, y, ..., stratify=y)
>>> sorted(Counter(y_train).items())
[(0, 35), (1, 35), (2, 35)]
- 9. 特徴量のスケーリング
何のために?
◦ アルゴリズムそのものに由来する問題
◦ コンピュータでの計算上の都合
具体的には・・・
1. 特徴量が不揃いだと良い結果を得られないアルゴリズムがある
◦ たとえば k 近傍法 (距離の定義による)
2. 特徴量が不揃いだと遅くなるアルゴリズムがある
◦ たとえばパーセプトロン (パーセプトロンの収束定理)
3. 特徴量が不揃いだと数値計算上の問題を招くアルゴリズムがある
◦ たとえばサポートベクトルマシン
◦ see sec. 2.2 in "A Practical Guide to Support Vector Classification"
◦ https://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
2017-05-18 社内勉強会 9
- 10. 標準化
データを次の操作で変換する
1. 平均が 0 になるように平行移動する
2. 標準偏差が 1 になるように定数倍する
2017-05-18 社内勉強会 10
>>> X_train_tmp = X_train - np.mean(X_train, 0)
>>> X_train_std = X_train_tmp / np.std(X_train_tmp, 0)
- 14. One vs Rest classifier
二クラス分類器を使って多クラス分類を実現する方法の一つ
例:Iris データセットの場合
次の 3 個の二クラス分類器を学習する
1. Setosa か「それ以外」か ⇒ 判別関数の値が正なら Setosa
2. Versicolor か「それ以外」か ⇒ 判別関数の値が正なら Versicolor
3. Virginica か「それ以外」か ⇒ 判別関数の値が正なら Virginica
多クラス分類の方法
◦ 学習した 3 個の分類器でそれぞれ判別関数の値を求める
◦ 判別関数の値が最大となったクラスを採用する
◦ 個々の値を見れば「全て正」や「全て負」になっているかもしれないが気にしない
2017-05-18 社内勉強会 14
- 15. パーセプトロンの学習率
パーセプトロンでは学習率を調整する必要はない
◦ この点に関する教科書の記述は誤り
◦ eta0 の既定値は 1.0 であり既定値のまま使えばよい
参考 (他の教科書など)
◦ 『パターン認識と機械学習』4.1.7 パーセプトロンアルゴリズム
◦ "一般性を失うことなく学習率パラメータ τ を 1 に設定することができる" (p. 192)
◦ 『オンライン機械学習』アルゴリズム 3.1 (p. 24)
◦ アルゴリズムを説明した擬似コードに学習率は表れない
◦ Perceptron - Wikipedia
◦ https://en.wikipedia.org/wiki/Perceptron
◦ "Learning Algorithm" の記述に学習率は表れない
◦ scikit-learn の API ドキュメント
◦ http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html
◦ eta0 の既定値が 1.0 であることを確認できる
2017-05-18 社内勉強会 15
- 23. コストパラメータ [1/2]
コスト関数 (= 分類のはずれ具合の総和) に掛ける係数
◦ 小さな値に設定 ⇒ 重みベクトルを小さくすること (正則化項) を重視
◦ 大きな値に設定 ⇒ 学習データを分類することを重視
2017-05-18 社内勉強会 23
- 27. SVM のコスト関数
(導出過程はさておき) 結果として SVM は
◦ 「ヒンジ損失 + L2 正則化」をコスト関数として最適化する
いろいろな損失関数 (右図)
◦ 青:パーセプトロン
◦ 橙:ロジスティック回帰
◦ 緑:ヒンジ損失
2017-05-18 社内勉強会 27
- 29. LinearSVC での実行結果
線形 SVM での分類には LinearSVC も利用できる
2017-05-18 社内勉強会 29
>>> svm = LinearSVC(random_state=0)
◦ LinearSVC は liblinear を利用する
◦ https://www.csie.ntu.edu.tw/~cjlin/liblinear/
- 30. SGDClassifier
一括学習 (batch learning)
◦ すべての学習データを読み込んでから学習する
◦ LogisticRegression, SVC, LinearSVC はこちら
◦ 内部で利用している libsvm や liblinear が一括学習のため
◦ LogisticRegression は solver を選べる。solver='liblinear' がデフォルト
逐次学習 (online learning)
◦ 学習データを一つずつ使って学習する
◦ Perceptron はこちら (教科書の記述は誤り)
◦ 確率的勾配降下法 (Stochastic Gradient Descent)
◦ http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html
◦ データ量が多い場合やストリームで供給される場合などに有用
2017-05-18 社内勉強会 30
- 32. カーネル SVM の威力 [1/4]
以下のようなデータを考える
◦ 左図:X と Y の符号が同じなら 0, 符号が異なっていたら 1
◦ 右図:原点からの距離の 2 乗が 2 未満なら 0, 2 以上なら 1
2017-05-18 社内勉強会 32
- 33. カーネル SVM の威力 [2/4]
このようなデータは線形分離不可能
◦ 下図は線形 SVM を適用して学習した結果
◦ まともに動かない
2017-05-18 社内勉強会 33
- 34. カーネル SVM の威力 [3/4]
カーネル SVM を適用する
◦ 下図は「二次の多項式カーネル」を用いて学習した結果
◦ なんだこれは!
2017-05-18 社内勉強会 34
- 35. カーネル SVM の威力 [4/4]
カーネル SVM を適用する
◦ 下図は「RBF カーネル」を用いて学習した結果
◦ なんだこれは!
2017-05-18 社内勉強会 35
- 36. カーネル SVM の概要 [1/2]
次の二つのアイデアの組み合わせ
1. 特徴量を「水増し」して高次元空間で線形分類する
2. 本当に水増しするのではなく「カーネル関数」で効率的に計算する
特徴量の水増し
◦ 元々の特徴量が 2 種類 (x1, x2) だったら・・・
◦ 2 次の項を追加すれば 5 種類
◦ x1*x1
◦ x1*x2
◦ x2*x2
◦ 3 次の項も追加すれば 9 種類
◦ x1*x1*x1
◦ x1*x1*x2
◦ x1*x2*x2
◦ x2*x2*x2
2017-05-18 社内勉強会 36
2 次の項を入れた 5 次元空間なら
これらはアッサリ分類できる
- 37. カーネル SVM の概要 [2/2]
次の二つのアイデアの組み合わせ
1. 特徴量を「水増し」して高次元空間で線形分類する
2. 本当に水増しするのではなく「カーネル関数」で効率的に計算する
カーネル関数
◦ 単純に特徴量を増やすと次元の数が爆発して実用にならない
◦ 重みベクトルとの内積さえ計算できればよい
例:2 次の多項式カーネル (本当はもう少し細かなパラメータがあります)
2017-05-18 社内勉強会 37
z = (1 + w1*x1 + w2*x2)^2
= 1 + 2 * w1 * x1
+ 2 * w2 * x2
+ w1*w1 * x1*x1
+ 2 * w1*w2 * x1*x2
+ w2*w2 * x2*x2
このスライドは色々と間違えています
- 42. 決定木のアルゴリズム
If-else のネスト構造でデータを判別する
2017-05-18 社内勉強会 42
if petal_width <= 0.75:
return 0 # Iris-Setosa
else:
if petal_length <= 4.95:
return 1 # Iris-Versicolor
else:
return 2 # Iris-Virginica
分岐条件をどのように決めるか?
◦ 各クラスが then, else に「なるべく綺麗に分かれる」条件を探す
◦ ジニ不純度
◦ エントロピー
- 43. 決定木の実行結果
max_depth = 3 での実行結果
◦ criterion='entropy' で実行 (教科書と同じ)
◦ デフォルトは criterion='gini'
2017-05-18 社内勉強会 43
- 45. エントロピー
情報理論の何やら難しい概念
◦ ここでは「各クラスのサンプルの混ざり具合い」だと思えばよい
2017-05-18 社内勉強会 45
def entropy(counts):
return np.sum([
-p * np.log2(p) if p > 0 else 0
for p in counts / np.sum(counts)])
>>> print(entropy([50, 50, 50])) # 1.58496250072
>>> print(entropy([20, 30, 50])) # 1.48547529723
>>> print(entropy([ 0, 30, 50])) # 0.954434002925
>>> print(entropy([ 0, 10, 50])) # 0.650022421648
>>> print(entropy([ 0, 0, 50])) # 0.0
◦ -p * log2(p) は p = 0 で計算不能だが +0 の極限が 0 なので 0 とする
- 50. k 近傍法の実行結果
k = 5 での実行結果
◦ 距離尺度は metric='euclidean' で実行
◦ 教科書に書かれている metric='minkowsky', p=2 と同じ
2017-05-18 社内勉強会 50
- 52. 多数決が同数の場合 [1/2]
scikit-learn の実装では「クラスの順序」に依存する
◦ scipy.stats.mode を利用しているため
◦ 教科書 91 ページの囲みの記述は誤り
参考
◦ scikit-learn の実装
◦ https://github.com/scikit-learn/scikit-learn/blob/0.18/sklearn/neighbors/classification.py
◦ scipy.stats.mode のドキュメント
◦ https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.stats.mode.html
weights='distance' パラメータ
◦ "weight points by the inverse of their distance"
◦ これは「多数決が同数の場合に距離が近いものを優先」ではない
2017-05-18 社内勉強会 52