Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Python 機械学習プログラミング 第 3 章
分類問題
― 機械学習ライブラリ scikit-learn の活用
内山 雄司 (@y__uti)
2017-05-18 社内勉強会
自己紹介
内山 雄司 (@y__uti)
◦ http://y-uti.hatenablog.jp/ (phpusers-ja)
仕事
◦ 受託開発の会社 (株式会社ピコラボ) でプログラマをしています
興味
◦ プログラミング言語処理系
◦ ...
この章で学ぶこと
1. scikit-learn を使ってみる
2. さまざまな分類アルゴリズムを試してみる
◦ パーセプトロン
◦ ロジスティック回帰
◦ サポートベクトルマシン
◦ 決定木
◦ k 近傍法
2017-05-18 社内勉強会 3
データの準備
3.2 scikit-learn を使ったパーセプトロンのトレーニング
2017-05-18 社内勉強会 4
Iris データセット
2017-05-18 社内勉強会 5
「あやめ」の 3 品種 150 サンプルからなるデータセット
◦ データベースでいうところのテーブルだと思えばよい
◦ 150 行のレコードがあるということ
各サンプルは以下の情報 ...
我々の目的
あやめの品種を判別する関数を作りたい
引数
◦ 花びらの長さ
◦ 花びらの幅
戻り値
◦ 品種
2017-05-18 社内勉強会 6
def predict(petal_length, petal_width):
...
retur...
データセットの分割
何のために?
◦ あやめの品種を判別する関数が得られたとしましょう
◦ その関数を使って「当たった!」とか「外れた」とか遊びたい
◦ ところが手持ちのデータは全部で 150 個しかない
◦ 遊ぶためのデータを 150 個のサ...
層化抽出法
手持ちのデータは 3 品種それぞれ 50 サンプル
教科書の方法で分割すると各品種の比率は維持されない
2017-05-18 社内勉強会 8
>>> from collections import Counter
>>> sorte...
特徴量のスケーリング
何のために?
◦ アルゴリズムそのものに由来する問題
◦ コンピュータでの計算上の都合
具体的には・・・
1. 特徴量が不揃いだと良い結果を得られないアルゴリズムがある
◦ たとえば k 近傍法 (距離の定義による)
2....
標準化
データを次の操作で変換する
1. 平均が 0 になるように平行移動する
2. 標準偏差が 1 になるように定数倍する
2017-05-18 社内勉強会 10
>>> X_train_tmp = X_train - np.mean(X_t...
テストデータの標準化
トレーニングデータと「同じ値だけ」動かす
2017-05-18 社内勉強会 11
>>> X_test_tmp = X_test - np.mean(X_train, 0)
>>> X_test_std = X_test_...
パーセプトロン
3.2 scikit-learn を使ったパーセプトロンのトレーニング
2017-05-18 社内勉強会 12
パーセプトロン
アルゴリズムの説明は第 2 章で既出なので省略
実装と実行手順も教科書のとおりなので省略
2017-05-18 社内勉強会 13
One vs Rest classifier
二クラス分類器を使って多クラス分類を実現する方法の一つ
例:Iris データセットの場合
次の 3 個の二クラス分類器を学習する
1. Setosa か「それ以外」か ⇒ 判別関数の値が正なら Se...
パーセプトロンの学習率
パーセプトロンでは学習率を調整する必要はない
◦ この点に関する教科書の記述は誤り
◦ eta0 の既定値は 1.0 であり既定値のまま使えばよい
参考 (他の教科書など)
◦ 『パターン認識と機械学習』4.1.7 パー...
ロジスティック回帰
3.3 ロジスティック回帰を使ったクラスの確率のモデリング
2017-05-18 社内勉強会 16
ロジスティック回帰の結果
教科書のコード例と同じ設定での実行結果
◦ C = 1000
◦ 一対他の手法で多クラス分類を実現 (パーセプトロンと同じ)
2017-05-18 社内勉強会 17
ロジスティック回帰 [1/4]
例:virginica と「それ以外」を分類
まずは特徴量の重み付け和を考える (パーセプトロンと同じ)
2017-05-18 社内勉強会 18
z = 2.0 * petal_length - 1.5 * pe...
ロジスティック回帰 [2/4]
例:virginica と「それ以外」を分類
シグモイド関数を用いて 0 ~ 1 の範囲に押し込める
2017-05-18 社内勉強会 19
phi = 1.0 / (1.0 + np.exp(-z))
ロジスティック回帰 [3/4]
例:virginica と「それ以外」を分類
コスト関数 (= 分類のはずれ具合の総和) を考える
2017-05-18 社内勉強会 20
J = np.sum(-y * np.log(phi(z)) - (1-...
ロジスティック回帰 [4/4]
例:virginica と「それ以外」を分類
コスト関数を小さくする方向に重みベクトルを更新する
2017-05-18 社内勉強会 21
z = 1.0 * petal_length + 1.0 * petal_...
正則化
正則化とは?
◦ モデルの複雑さを抑えるテクニック
◦ 具体的には「重みベクトルの大きさに応じたペナルティ」を足す
何のために?
◦ パラメータ数が多いと過学習が発生する
◦ そういうモデルはテストデータを予測できない
(たぶん) よく...
コストパラメータ [1/2]
コスト関数 (= 分類のはずれ具合の総和) に掛ける係数
◦ 小さな値に設定 ⇒ 重みベクトルを小さくすること (正則化項) を重視
◦ 大きな値に設定 ⇒ 学習データを分類することを重視
2017-05-18 社...
コストパラメータ [2/2]
ロジスティック回帰の場合
◦ 下図は petal length = petal width に沿って動かしたときの様子
◦ Versicolor (橙) は殆ど変化しない。他の分類器の影響で結果が変わる
2017-...
線形 SVM
3.4 サポートベクトルマシンによる最大マージン分類
2017-05-18 社内勉強会 25
SVM の概要
決定境界のなかで一番「幅を広く」できるものを求める
◦ どうやってそんなことが!
◦ 難しいので説明しないがとにかくできる
下図は Setosa と「それ以外」を二値分類した様子
◦ 中央が SVM で得られる結果
2017-0...
SVM のコスト関数
(導出過程はさておき) 結果として SVM は
◦ 「ヒンジ損失 + L2 正則化」をコスト関数として最適化する
いろいろな損失関数 (右図)
◦ 青:パーセプトロン
◦ 橙:ロジスティック回帰
◦ 緑:ヒンジ損失
201...
線形 SVM の実行結果
教科書のコード例と同じ設定での実行結果
2017-05-18 社内勉強会 28
>>> svm = SVC(kernel='linear', C=1.0, random_state=0)
◦ scikit-learn ...
LinearSVC での実行結果
線形 SVM での分類には LinearSVC も利用できる
2017-05-18 社内勉強会 29
>>> svm = LinearSVC(random_state=0)
◦ LinearSVC は libl...
SGDClassifier
一括学習 (batch learning)
◦ すべての学習データを読み込んでから学習する
◦ LogisticRegression, SVC, LinearSVC はこちら
◦ 内部で利用している libsvm や...
カーネル SVM
3.5 カーネル SVM を使った非線形問題の求解
2017-05-18 社内勉強会 31
カーネル SVM の威力 [1/4]
以下のようなデータを考える
◦ 左図:X と Y の符号が同じなら 0, 符号が異なっていたら 1
◦ 右図:原点からの距離の 2 乗が 2 未満なら 0, 2 以上なら 1
2017-05-18 社内勉強...
カーネル SVM の威力 [2/4]
このようなデータは線形分離不可能
◦ 下図は線形 SVM を適用して学習した結果
◦ まともに動かない
2017-05-18 社内勉強会 33
カーネル SVM の威力 [3/4]
カーネル SVM を適用する
◦ 下図は「二次の多項式カーネル」を用いて学習した結果
◦ なんだこれは!
2017-05-18 社内勉強会 34
カーネル SVM の威力 [4/4]
カーネル SVM を適用する
◦ 下図は「RBF カーネル」を用いて学習した結果
◦ なんだこれは!
2017-05-18 社内勉強会 35
カーネル SVM の概要 [1/2]
次の二つのアイデアの組み合わせ
1. 特徴量を「水増し」して高次元空間で線形分類する
2. 本当に水増しするのではなく「カーネル関数」で効率的に計算する
特徴量の水増し
◦ 元々の特徴量が 2 種類 (x1...
カーネル SVM の概要 [2/2]
次の二つのアイデアの組み合わせ
1. 特徴量を「水増し」して高次元空間で線形分類する
2. 本当に水増しするのではなく「カーネル関数」で効率的に計算する
カーネル関数
◦ 単純に特徴量を増やすと次元の数が爆...
カーネル SVM の実行結果
教科書のコード例と同じ設定での実行結果
◦ kernel = 'rbf'
◦ gamma = 0.2
◦ C = 1.0
2017-05-18 社内勉強会 38
gamma, C による変化 [1/2]
2017-05-18 社内勉強会 39
gamma, C による変化 [2/2]
2017-05-18 社内勉強会 40
決定木
3.6 決定木学習
2017-05-18 社内勉強会 41
決定木のアルゴリズム
If-else のネスト構造でデータを判別する
2017-05-18 社内勉強会 42
if petal_width <= 0.75:
return 0 # Iris-Setosa
else:
if petal_lengt...
決定木の実行結果
max_depth = 3 での実行結果
◦ criterion='entropy' で実行 (教科書と同じ)
◦ デフォルトは criterion='gini'
2017-05-18 社内勉強会 43
木の深さによる結果の変化
2017-05-18 社内勉強会 44
エントロピー
情報理論の何やら難しい概念
◦ ここでは「各クラスのサンプルの混ざり具合い」だと思えばよい
2017-05-18 社内勉強会 45
def entropy(counts):
return np.sum([
-p * np.log2...
閾値ごとのエントロピー
2017-05-18 社内勉強会 46
ランダムフォレスト
次の方法で「雑な」決定木をたくさん作って多数決で判別する
1. トレーニングデータの一部をランダムに取り出す (復元抽出)
2. 取り出したデータだけを使って決定木を作る
◦ 各ノードで分割するときには特徴量の一部をランダム...
k 近傍法
3.7 k 近傍法:怠惰学習アルゴリズム
2017-05-18 社内勉強会 48
k 近傍法のアルゴリズム
学習データセットを丸ごと保持する
次の手順で判別する
1. 最も近い k 個のデータを探す
2. その k 個の多数決で決める
Iris データセットでの例 (右図)
◦ k = 5
◦ 座標 (0.5, 0.55) ...
k 近傍法の実行結果
k = 5 での実行結果
◦ 距離尺度は metric='euclidean' で実行
◦ 教科書に書かれている metric='minkowsky', p=2 と同じ
2017-05-18 社内勉強会 50
k の値による結果の変化
2017-05-18 社内勉強会 51
多数決が同数の場合 [1/2]
scikit-learn の実装では「クラスの順序」に依存する
◦ scipy.stats.mode を利用しているため
◦ 教科書 91 ページの囲みの記述は誤り
参考
◦ scikit-learn の実装
◦...
多数決が同数の場合 [2/2]
人工的なデータに k 近傍法を適用した結果
2017-05-18 社内勉強会 53
metric パラメータ
データによってはユークリッド距離では「近さ」を測れない
◦ 緯度経度で表されたデータ
◦ boolean を要素とするデータ
データ間の距離を計算する方法を指定できる
参考
◦ sklearn.neighbors.Di...
おわり
2017-05-18 社内勉強会 55
Upcoming SlideShare
Loading in …5
×

分類問題 - 機械学習ライブラリ scikit-learn の活用

4,523 views

Published on

社内勉強会で『Python 機械学習プログラミング』の第 3 章の発表を担当した際の資料です。教科書で触れられている各アルゴリズムについて、アルゴリズムの概要と Iris データセットへの適用結果を説明しています。

発表資料に対応して、Jupyter Notebook で実行した ipynb ファイルを Gist にアップロードしています。
https://gist.github.com/y-uti/bd0928ad4f4eff7794a00108f6cbe7cc

[2017-05-08] スライド 37 ページの内容はカーネル SVM の理解について大きな誤りがあったため取り消します。

Published in: Technology
  • Be the first to comment

分類問題 - 機械学習ライブラリ scikit-learn の活用

  1. 1. Python 機械学習プログラミング 第 3 章 分類問題 ― 機械学習ライブラリ scikit-learn の活用 内山 雄司 (@y__uti) 2017-05-18 社内勉強会
  2. 2. 自己紹介 内山 雄司 (@y__uti) ◦ http://y-uti.hatenablog.jp/ (phpusers-ja) 仕事 ◦ 受託開発の会社 (株式会社ピコラボ) でプログラマをしています 興味 ◦ プログラミング言語処理系 ◦ 機械学習 2017-05-18 社内勉強会 2
  3. 3. この章で学ぶこと 1. scikit-learn を使ってみる 2. さまざまな分類アルゴリズムを試してみる ◦ パーセプトロン ◦ ロジスティック回帰 ◦ サポートベクトルマシン ◦ 決定木 ◦ k 近傍法 2017-05-18 社内勉強会 3
  4. 4. データの準備 3.2 scikit-learn を使ったパーセプトロンのトレーニング 2017-05-18 社内勉強会 4
  5. 5. Iris データセット 2017-05-18 社内勉強会 5 「あやめ」の 3 品種 150 サンプルからなるデータセット ◦ データベースでいうところのテーブルだと思えばよい ◦ 150 行のレコードがあるということ 各サンプルは以下の情報 (カラムだと思えばよい) を持つ ◦ がく片の長さ sepal length ◦ がく片の幅 sepal width ◦ 花びらの長さ petal length ◦ 花びらの幅 petal width ◦ 品種 class ◦ Iris-Setosa ◦ Iris-Versicolor ◦ Iris-Virginica
  6. 6. 我々の目的 あやめの品種を判別する関数を作りたい 引数 ◦ 花びらの長さ ◦ 花びらの幅 戻り値 ◦ 品種 2017-05-18 社内勉強会 6 def predict(petal_length, petal_width): ... return iris_class データを睨みながら職人芸で実装するのではなく データから自動的にルールを見つけ出したい
  7. 7. データセットの分割 何のために? ◦ あやめの品種を判別する関数が得られたとしましょう ◦ その関数を使って「当たった!」とか「外れた」とか遊びたい ◦ ところが手持ちのデータは全部で 150 個しかない ◦ 遊ぶためのデータを 150 個のサンプルから最初に分けておく なぜ「分けておく」必要が? (同じデータでは駄目?) ◦ 関数を作るときに使ったデータを判別に使うと「ズル」ができる ◦ たとえば丸暗記 2017-05-18 社内勉強会 7
  8. 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. 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. 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)
  11. 11. テストデータの標準化 トレーニングデータと「同じ値だけ」動かす 2017-05-18 社内勉強会 11 >>> X_test_tmp = X_test - np.mean(X_train, 0) >>> X_test_std = X_test_tmp / np.std(X_train, 0)
  12. 12. パーセプトロン 3.2 scikit-learn を使ったパーセプトロンのトレーニング 2017-05-18 社内勉強会 12
  13. 13. パーセプトロン アルゴリズムの説明は第 2 章で既出なので省略 実装と実行手順も教科書のとおりなので省略 2017-05-18 社内勉強会 13
  14. 14. One vs Rest classifier 二クラス分類器を使って多クラス分類を実現する方法の一つ 例:Iris データセットの場合 次の 3 個の二クラス分類器を学習する 1. Setosa か「それ以外」か ⇒ 判別関数の値が正なら Setosa 2. Versicolor か「それ以外」か ⇒ 判別関数の値が正なら Versicolor 3. Virginica か「それ以外」か ⇒ 判別関数の値が正なら Virginica 多クラス分類の方法 ◦ 学習した 3 個の分類器でそれぞれ判別関数の値を求める ◦ 判別関数の値が最大となったクラスを採用する ◦ 個々の値を見れば「全て正」や「全て負」になっているかもしれないが気にしない 2017-05-18 社内勉強会 14
  15. 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
  16. 16. ロジスティック回帰 3.3 ロジスティック回帰を使ったクラスの確率のモデリング 2017-05-18 社内勉強会 16
  17. 17. ロジスティック回帰の結果 教科書のコード例と同じ設定での実行結果 ◦ C = 1000 ◦ 一対他の手法で多クラス分類を実現 (パーセプトロンと同じ) 2017-05-18 社内勉強会 17
  18. 18. ロジスティック回帰 [1/4] 例:virginica と「それ以外」を分類 まずは特徴量の重み付け和を考える (パーセプトロンと同じ) 2017-05-18 社内勉強会 18 z = 2.0 * petal_length - 1.5 * petal_width - 0.2
  19. 19. ロジスティック回帰 [2/4] 例:virginica と「それ以外」を分類 シグモイド関数を用いて 0 ~ 1 の範囲に押し込める 2017-05-18 社内勉強会 19 phi = 1.0 / (1.0 + np.exp(-z))
  20. 20. ロジスティック回帰 [3/4] 例:virginica と「それ以外」を分類 コスト関数 (= 分類のはずれ具合の総和) を考える 2017-05-18 社内勉強会 20 J = np.sum(-y * np.log(phi(z)) - (1-y) * np.log(1-phi(z))) J = 59.78
  21. 21. ロジスティック回帰 [4/4] 例:virginica と「それ以外」を分類 コスト関数を小さくする方向に重みベクトルを更新する 2017-05-18 社内勉強会 21 z = 1.0 * petal_length + 1.0 * petal_width - 1.0 J = 27.94
  22. 22. 正則化 正則化とは? ◦ モデルの複雑さを抑えるテクニック ◦ 具体的には「重みベクトルの大きさに応じたペナルティ」を足す 何のために? ◦ パラメータ数が多いと過学習が発生する ◦ そういうモデルはテストデータを予測できない (たぶん) よく使われる「ペナルティ」の種類 ◦ L2 正則化 重みベクトルの大きさの二乗に比例 ◦ L1 正則化 重みベクトルの大きさに比例 ◦ elasticnet L2 + L1 2017-05-18 社内勉強会 22
  23. 23. コストパラメータ [1/2] コスト関数 (= 分類のはずれ具合の総和) に掛ける係数 ◦ 小さな値に設定 ⇒ 重みベクトルを小さくすること (正則化項) を重視 ◦ 大きな値に設定 ⇒ 学習データを分類することを重視 2017-05-18 社内勉強会 23
  24. 24. コストパラメータ [2/2] ロジスティック回帰の場合 ◦ 下図は petal length = petal width に沿って動かしたときの様子 ◦ Versicolor (橙) は殆ど変化しない。他の分類器の影響で結果が変わる 2017-05-18 社内勉強会 24
  25. 25. 線形 SVM 3.4 サポートベクトルマシンによる最大マージン分類 2017-05-18 社内勉強会 25
  26. 26. SVM の概要 決定境界のなかで一番「幅を広く」できるものを求める ◦ どうやってそんなことが! ◦ 難しいので説明しないがとにかくできる 下図は Setosa と「それ以外」を二値分類した様子 ◦ 中央が SVM で得られる結果 2017-05-18 社内勉強会 26
  27. 27. SVM のコスト関数 (導出過程はさておき) 結果として SVM は ◦ 「ヒンジ損失 + L2 正則化」をコスト関数として最適化する いろいろな損失関数 (右図) ◦ 青:パーセプトロン ◦ 橙:ロジスティック回帰 ◦ 緑:ヒンジ損失 2017-05-18 社内勉強会 27
  28. 28. 線形 SVM の実行結果 教科書のコード例と同じ設定での実行結果 2017-05-18 社内勉強会 28 >>> svm = SVC(kernel='linear', C=1.0, random_state=0) ◦ scikit-learn の SVC は libsvm を利用する ◦ https://www.csie.ntu.edu.tw/~cjlin/libsvm/
  29. 29. LinearSVC での実行結果 線形 SVM での分類には LinearSVC も利用できる 2017-05-18 社内勉強会 29 >>> svm = LinearSVC(random_state=0) ◦ LinearSVC は liblinear を利用する ◦ https://www.csie.ntu.edu.tw/~cjlin/liblinear/
  30. 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
  31. 31. カーネル SVM 3.5 カーネル SVM を使った非線形問題の求解 2017-05-18 社内勉強会 31
  32. 32. カーネル SVM の威力 [1/4] 以下のようなデータを考える ◦ 左図:X と Y の符号が同じなら 0, 符号が異なっていたら 1 ◦ 右図:原点からの距離の 2 乗が 2 未満なら 0, 2 以上なら 1 2017-05-18 社内勉強会 32
  33. 33. カーネル SVM の威力 [2/4] このようなデータは線形分離不可能 ◦ 下図は線形 SVM を適用して学習した結果 ◦ まともに動かない 2017-05-18 社内勉強会 33
  34. 34. カーネル SVM の威力 [3/4] カーネル SVM を適用する ◦ 下図は「二次の多項式カーネル」を用いて学習した結果 ◦ なんだこれは! 2017-05-18 社内勉強会 34
  35. 35. カーネル SVM の威力 [4/4] カーネル SVM を適用する ◦ 下図は「RBF カーネル」を用いて学習した結果 ◦ なんだこれは! 2017-05-18 社内勉強会 35
  36. 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. 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 このスライドは色々と間違えています
  38. 38. カーネル SVM の実行結果 教科書のコード例と同じ設定での実行結果 ◦ kernel = 'rbf' ◦ gamma = 0.2 ◦ C = 1.0 2017-05-18 社内勉強会 38
  39. 39. gamma, C による変化 [1/2] 2017-05-18 社内勉強会 39
  40. 40. gamma, C による変化 [2/2] 2017-05-18 社内勉強会 40
  41. 41. 決定木 3.6 決定木学習 2017-05-18 社内勉強会 41
  42. 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. 43. 決定木の実行結果 max_depth = 3 での実行結果 ◦ criterion='entropy' で実行 (教科書と同じ) ◦ デフォルトは criterion='gini' 2017-05-18 社内勉強会 43
  44. 44. 木の深さによる結果の変化 2017-05-18 社内勉強会 44
  45. 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 とする
  46. 46. 閾値ごとのエントロピー 2017-05-18 社内勉強会 46
  47. 47. ランダムフォレスト 次の方法で「雑な」決定木をたくさん作って多数決で判別する 1. トレーニングデータの一部をランダムに取り出す (復元抽出) 2. 取り出したデータだけを使って決定木を作る ◦ 各ノードで分割するときには特徴量の一部をランダムに取り出す ◦ 取り出した特徴量だけを候補にして分割の閾値を決める 2017-05-18 社内勉強会 47
  48. 48. k 近傍法 3.7 k 近傍法:怠惰学習アルゴリズム 2017-05-18 社内勉強会 48
  49. 49. k 近傍法のアルゴリズム 学習データセットを丸ごと保持する 次の手順で判別する 1. 最も近い k 個のデータを探す 2. その k 個の多数決で決める Iris データセットでの例 (右図) ◦ k = 5 ◦ 座標 (0.5, 0.55) の品種を判別 ◦ Versicolor 3 個 vs. Virginica 2 個 ◦ Versicolor と判別する 2017-05-18 社内勉強会 49
  50. 50. k 近傍法の実行結果 k = 5 での実行結果 ◦ 距離尺度は metric='euclidean' で実行 ◦ 教科書に書かれている metric='minkowsky', p=2 と同じ 2017-05-18 社内勉強会 50
  51. 51. k の値による結果の変化 2017-05-18 社内勉強会 51
  52. 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
  53. 53. 多数決が同数の場合 [2/2] 人工的なデータに k 近傍法を適用した結果 2017-05-18 社内勉強会 53
  54. 54. metric パラメータ データによってはユークリッド距離では「近さ」を測れない ◦ 緯度経度で表されたデータ ◦ boolean を要素とするデータ データ間の距離を計算する方法を指定できる 参考 ◦ sklearn.neighbors.DistanceMetric ◦ http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.DistanceMetric.html 2017-05-18 社内勉強会 54
  55. 55. おわり 2017-05-18 社内勉強会 55

×