機械学習
名古屋大学大学院 情報学研究科
出口 大輔

2

講義内容
 機械学習の基礎
 最近傍法 K最近傍法 線形判別分析法

 演習（Pythonによる実践機械学習プログラミング）
 Pythonによる機械学習環境の構築
 Google Colaboratory の準備 手書き文字認識
 Nearest Neighbor （最近傍法）

3

4

まずはじめに・・・ 自動で「りんご」を分類／認識する機械を作りたい！
 何らかの特徴（丸さ，色，…）を測れば分類できる？
 特徴を数値の並び（ベクトル）として扱うことを考える

円形度： 0.8
赤成分： 1.0
緑成分： 0.2
青成分： 0.2

入力（画像）データ

特徴量の記述

0.8
1.0
0.2
0.2
⋮

ベクトル化

5

まずはじめに・・・ いろいろな果物の特徴（ベクトル）をプロットすると？
○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○

6

まずはじめに・・・ いろいろな果物の特徴（ベクトル）をプロットすると？
 「りんご」かどうかのラベル（＝教師データ）があれば・・・

×× × ×××
○

○×× ×

○

○×○×

○
○
○

○
○

○
○

×
○

このあたりに境界がありそう

×× ×
○

○×○

7

機械学習とは？
 人間が自然に行っている学習能力と同様の機能をコンピュータで実現しようとする技術[Wikipediaより引用]
 データの集合から何らかのルールや法則を計算機に学習させる技術
円形度： 0.8
赤成分： 1.0
緑成分： 0.2
青成分： 0.2

×× × × × ×
×××××× ××

入力（画像）データ

特徴量の記述

識別器××

出力

りんご

8

機械学習でどんなことができるの？
 Teachable Machine で試してみよう！
 WEBブラウザーを使って機械学習を体験できるサイト
 ２０１７年にGoogleが公開

https://teachablemachine.withgoogle.com/

10

機械学習の種類
○
○

○

○ ○

○

○

○
○

○ ○ ○
○
○
何個の塊が見えますか？
○
○
○

○
○
○

○
○
○
○

○

×

○

○

○

○

教師なし学習×××

×
×
境界はどこに引けますか？
○

○

○

○
○
○

○

×× ×

○

○

○
○

×× × ×

○
○

○
○

×
○

× ×
○

○

教師あり学習○11

機械学習の種類 教師あり学習 教師データ（入力と出力のペア）を与えてその関係性を表現するモデルを構築する方法
 入力から出力への写像を求める問題（回帰，分類，など）

 教師なし学習 入力データのみからモデルを構築する方法
 データの分類（クラスタリング）など

 その他
 半教師あり学習 ・・・ 教師ありと教師なしの折衷案
 オンライン学習 ・・・ 動的に得られるデータを使って学習 強化学習 ・・・ 行動に対する報酬を最大化するように学習

12

機械学習の用語（クラスとラベル）
ぶどう
りんご

ラベル
メロン

クラス

梨

13

14

〜最近傍法〜

15

最近傍法（２クラスの場合）

りんご

？
りんご

教師データ

X

入力データ

X<YY

りんご？ OR メロン？

メロン
教師データ

特徴量X

16

最近傍法（２クラスの場合）
 入力データに最も近い教師データを出力する手法
特徴 𝑋𝑋2××××××？
×××

２クラス（○と✕）の場合？

特徴 𝑋𝑋1

17

最近傍法（２クラスの場合）
 入力データに最も近い教師データを出力する手法
 𝑖𝑖 番目の教師データを 𝒛𝒛𝑖𝑖 =𝒙𝒙𝑖𝑖 , 𝑦𝑦𝑖𝑖 とする

𝑥𝑥1 , 𝑥𝑥2 , 𝑥𝑥3 , ⋯ 𝑇𝑇 はN次元の特徴量ベクトル 𝑦𝑦 は 𝒙𝒙𝑖𝑖 に対する教師ラベルであり ±1 の値をとる
 𝒙𝒙𝑖𝑖 =※ +1 はりんご（ポジティブデータ）， −1 はメロン（ネガティブデータ）

 分類したいデータの特徴量を 𝒙𝒙 とするとそのラベル 𝑦𝑦� は？

𝑦𝑦� 𝒙𝒙 = 𝑦𝑦𝚤𝚤̃𝚤𝚤̃ = argmin 𝒙𝒙 − 𝒙𝒙𝑖𝑖𝑖𝑖

18

最近傍法（２クラスの場合）
 入力データに最も近い教師データを出力する手法
特徴 𝑋𝑋2×××××××××

２クラス（○と✕）の場合

特徴 𝑋𝑋1

19〜K最近傍法〜

20

K最近傍法（２クラスの場合）
 入力データのK近傍内で最も多く現れる教師データを出力する手法
特徴 𝑋𝑋2××××××？

××3近傍（K=3）の場合×？

特徴 𝑋𝑋1

21

K最近傍法（２クラスの場合）
 入力データのK近傍内で最も多く現れる教師データを出力する手法
 𝑖𝑖 番目の教師データを 𝒛𝒛𝑖𝑖 =𝒙𝒙𝑖𝑖 , 𝑦𝑦𝑖𝑖 とする

𝑥𝑥1 , 𝑥𝑥2 , 𝑥𝑥3 , ⋯ 𝑇𝑇 はN次元の特徴量ベクトル 𝑦𝑦 は 𝒙𝒙𝑖𝑖 に対する教師ラベルであり ±1 の値をとる
 𝒙𝒙𝑖𝑖 =※ +1 はりんご（ポジティブデータ）， −1 はメロン（ネガティブデータ）

 分類したいデータの特徴量を 𝒙𝒙 とするとそのラベル 𝑦𝑦
� は？

1+1 if 0 ≤𝐾𝐾𝑦𝑦� 𝒙𝒙 = �−1�𝒙𝒙𝑖𝑖 ∈𝒩𝒩𝐾𝐾 𝒙𝒙𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑜𝑦𝑦𝑖𝑖※ 𝒩𝒩𝐾𝐾 𝒙𝒙 は 𝒙𝒙 のK最近傍【メリット】 分類（識別）境界が滑らかなる

𝒙𝒙 から近い順にK個集めた集合

22〜線形判別分析〜

23

データの確率的な表現
 大量のりんごから求めた特徴量はどんな分布？

24

データの確率的な表現
 大量のりんごから求めた特徴量はどんな分布？
 中心の密度（リンゴの密集度）が高い分布になる

25

データの確率的な表現
 大量のりんごから求めた特徴量はどんな分布？
 中心の密度（リンゴの密集度）が高い分布になる

 ある特徴量Xが与えられたら，それはどれくらい「りんご」らしいでしょう？
か？

= Pr りんご 𝒙𝒙

確率６０％くらいで「りんご」っぽい26

線形判別分析（２クラスの場合）
 入力 𝒙𝒙 がクラス+1（もしくは−1）である確率を考える
 +1 である確率は Pr +1 𝒙𝒙
 −1 である確率は Pr −1 𝒙𝒙

Pr +1 𝒙𝒙 ≥ Pr −1 𝒙𝒙 ならば +1，それ以外は −1 に分類

27

線形判別分析（２クラスの場合）
 入力 𝒙𝒙 がクラス+1（もしくは−1）である確率を考える
 +1 である確率は Pr +1 𝒙𝒙
 −1 である確率は Pr −1 𝒙𝒙

Pr +1 𝒙𝒙 ≥ Pr −1 𝒙𝒙 ならば +1，それ以外は −1 に分類

 ここで，Pr ±1 𝒙𝒙 が正規分布に従うと仮定する
Pr 𝑘𝑘 𝒙𝒙 =1𝑝𝑝
2𝜋𝜋 21𝚺𝚺 21− 𝒙𝒙−𝝁𝝁𝑘𝑘 𝑇𝑇 𝚺𝚺 −1 𝒙𝒙−𝝁𝝁𝑘𝑘𝑒𝑒 2※ 𝝁𝝁𝑘𝑘 はクラス毎の平均であり，共分散行列 𝚺𝚺 は全クラスで共通とする

28

正規分布？
 確率論や統計学で非常に良く用いられる関数
 平均 𝝁𝝁 を中心，共分散行列 𝚺𝚺 で分布形状が決まる

 中心から離れるに従って関数値が減少

𝝁𝝁𝒙𝒙

29

線形判別分析（２クラスの場合）
 Pr +1 𝒙𝒙≥ Pr −1 𝒙𝒙 なら +1，それ以外は −1Pr +1 𝒙𝒙
Pr −1 𝒙𝒙

≥ 1 を調べることと等価 クラス平均を 𝝁𝝁𝑘𝑘 とし，共分散行列は全クラスで等しい 𝚺𝚺 と仮定して左辺の対数を計算
Pr +1 𝒙𝒙log= log Pr +1 𝒙𝒙 − log Pr −1 𝒙𝒙
Pr −1 𝒙𝒙
Pr ±1 𝒙𝒙 =1𝑝𝑝
2𝜋𝜋 21𝚺𝚺 2𝑇𝑇
1− 𝒙𝒙−𝝁𝝁±1 𝚺𝚺 −1 𝒙𝒙−𝝁𝝁±1𝑒𝑒 2

この部分は両クラス同じ

30

線形判別分析（２クラスの場合）
Pr +1 𝒙𝒙= log Pr +1 𝒙𝒙 − log Pr −1 𝒙𝒙
logPr −1 𝒙𝒙

11𝑇𝑇 −1= − 𝒙𝒙 − 𝝁𝝁+1 𝚺𝚺 𝒙𝒙 − 𝝁𝝁+1 + 𝒙𝒙 − 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝒙𝒙 − 𝝁𝝁−1221 𝑇𝑇 −1
1 𝑇𝑇 −1
11𝑇𝑇 −1= − 𝒙𝒙 𝚺𝚺 𝒙𝒙 + 𝒙𝒙 𝚺𝚺 𝝁𝝁+1 + 𝝁𝝁+1 𝚺𝚺 𝒙𝒙 − 𝝁𝝁+1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁+122221111= + 𝒙𝒙𝑇𝑇 𝚺𝚺 −1 𝒙𝒙 − 𝒙𝒙𝑇𝑇 𝚺𝚺 −1 𝝁𝝁−1 − 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝒙𝒙 + 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁−12222
1 𝑇𝑇 −11= − 𝒙𝒙 𝚺𝚺 𝝁𝝁+1 − 𝝁𝝁−1 + 𝝁𝝁+1 − 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝒙𝒙221111𝑇𝑇 −1𝑇𝑇 −1𝑇𝑇 −1= − 𝝁𝝁+1 𝚺𝚺 𝝁𝝁+1 + 𝝁𝝁+1 𝚺𝚺 𝝁𝝁−1 + 𝝁𝝁−1 𝚺𝚺 𝝁𝝁−1 − 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁+12222𝑇𝑇 −1= 𝒙𝒙 𝚺𝚺

11− 𝝁𝝁+1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁+1 − 𝝁𝝁−1 − 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁+1 − 𝝁𝝁−1221𝝁𝝁+1 − 𝝁𝝁−1 − 𝝁𝝁+1 + 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁+1 − 𝝁𝝁−1231

線形判別分析（２クラスの場合）
 入力 𝒙𝒙 がに対して下記を計算して分類

Pr +1 𝒙𝒙
1𝑇𝑇 −1= 𝒙𝒙 𝚺𝚺 𝝁𝝁+1 − 𝝁𝝁−1 − 𝝁𝝁+1 + 𝝁𝝁−1 𝑇𝑇 𝚺𝚺 −1 𝝁𝝁+1 − 𝝁𝝁−1log
Pr −1 𝒙𝒙
2logPr +1 𝒙𝒙
Pr −1 𝒙𝒙≥ log 1 = 0 ならば +1，それ以外は −1

32

機械学習で何ができる？（その１）https://www.cityscapes-dataset.com※深層学習を利用したYOLOv3の結果

33

機械学習で何ができる？（その２）https://www.cityscapes-dataset.com※深層学習を利用したDeepLab v3+の結果

34

Pythonによる実践機械学習プログラミング35

まずはじめに演習の準備をしましょう（1） パソコンにログインし，ブラウザを開く Googleアカウントが無い場合は以下よりアカウント作成
 https://accounts.google.com/signup

 下記URLを入力してGoogle Colaboratoryにアクセス https://colab.research.google.com

36

37

まずはじめに演習の準備をしましょう（2） 演習用のノートブックを作成しましょう 「ファイル」メニューをクリック

 「ノートブックを新規作成」をクリック

38Google Colaboratory の使い方
ファイル名を変更する場合はここをクリック

実行結果はコードの下に表示
1. Pythonコードをここに入力
2. 「Shift + Enter」でコードを実行39

Python とは？
 インタプリタ型（PHP，Ruby等）のプログラミング言語
 命令を1つずつ読み込んで実行する方式※コンパイル型言語（C++等）は事前に全命令を読み込んで実行可能な形式に変換する方式
 機械学習コミュニティでは主流 Deep Learningのフレームワークの多くはPythonで実装

 Python の学習方法
 Python入門
 https://qiita.com/ponnhide/items/870f0e6b1ae50f201f07

 Progateの無料会員コース
 https://prog-8.com/

40

Python のあいうえお（1） 変数：データを記憶する箱（数学の変数のようなもの）
 数値，文字列，クラス，・・・ 変数名はアルファベットと数字の組み合わせが利用可能 ただし先頭は必ずアルファベットで，大／小文字を区別 関数：ある一定の処理を機能として再利用可能な形でまとめたもの（数学の関数のようなもの）
 def 関数名:
関数名: の形で宣言する

 インデント（半角空白4つ）

で処理のまとまりを判断 異なるインデントは異なる処理ブロックとして扱われる

半角空白４つ41

Python のあいうえお（2） 配列：複数のデータをまとめて管理するもの
 配列内のデータはインデックスを使ってアクセス（例: a[0]） インデックスは 0 から始まる

 角括弧 [ ] で囲むことで配列を作れる
 データはカンマ（,）区切り 連想配列：キーと値のペアでデータを管理する配列
 波括弧 { } で囲むことで配列を作れる
 キーと値をコロン（:）で対応付ける
 例: "key1" : 3.0

 データへのアクセスは角括弧にキーを指定する

42

Python のあいうえお（3） 繰り返し：ある処理のまとまりを繰り返し実行

for 変数 in データの集まり:
なんらかの処理 「データの集まり」の各要素が順に「変数」に代入されながら「なんらかの処理」が実行される
 「データの集まり」には配列や連想配列などを指定可能
 例：１から１０までの総和

43

対象：文字認識 0〜9の手書き数字認識にチャレンジ

学習データ

これは何という数字？

「6」

44

最近傍法の実装
 演習用データのダウンロードと展開 必要なモジュールの読み込み 画像の扱いについて
 学習画像の準備
 認識しよう（最近傍法）
 沢山の画像を認識して認識率を計算しよう45

演習用データのダウンロードと展開
 Google Colaboratoryでは，先頭に ! をつけることでLinuxのコマンドを実行することが可能 以下のコードを入力して実行（Shift+Enter）# 演習用データのダウンロード!wget https://bit.ly/2PVNqUi -q -O info3.zip!unzip -q info3.zip
!ls

実行結果

46

演習用のディレクトリに移動
 演習を実行する際の作業ディレクトリを %cd コマンドを使って「info3」フォルダに変更
 以下のコードを入力して実行（Shift+Enter）# 作業ディレクトリを変更%cd info3!ls

実行結果

47

必要なモジュールを読み込み
 以下のコードを入力して， Shift+Enterキーを押して実行します# モジュールの読み込み%matplotlib inline
import numpy as np
from skimage.io import imread, imshow
from skimage.feature import hog
from sklearn.metrics import accuracy_score, confusion_matrix
from scipy.stats import mode
import matplotlib.pyplot as plt
from print_cmx import print_cmx

48

画像の読み込み 画像の読み込み# 画像の読み込み
image = imread("classes/cls0_0.png")# 表示imshow(image)

実行結果

49

画像からHOG特徴量を抽出
 HOG特徴量の抽出処理# HOG (Histograms of Oriented Gradient) 特徴量を計算
feat, hog_image = hog(image, visualize=True)
imshow(hog_image)とだけ入力して Shift+Enter で画像が表示される

 特徴量の可視化
featと入力して Shift+Enter を押すと特徴ベクトルの値が表示される

imshow(hog_image)
でHOG特徴量を画像化したものが表示される

50

学習画像の準備 samples_per_class クラスごとの学習画像枚数（後で変更：1〜100）samples_per_class = 1
train_images = [] # 入力画像
train_features = [] # 特徴量
train_labels = [] # 対応するクラスラベル
for c in range(10):for i in range(samples_per_class):
img = imread("classes/cls%d_%d.png" % (c, i))feat = hog(img)train_images.append(img)train_features.append(feat)train_labels.append(c)51

学習画像の準備 samples_per_class クラスごとの学習画像枚数（後で変更：1〜100）samples_per_class = 1
train_images = [] # 入力画像
train_features = [] # 特徴量
train_labels = [] # 対応するクラスラベル
for c in range(10):for i in range(samples_per_class):
img = imread("classes/cls%d_%d.png" % (c, i))
スペース4個feat = hog(img)
スペース8個

train_images.append(img)train_features.append(feat)train_labels.append(c)52

認識したい画像の読み込み・特徴抽出 imagesフォルダ内の適当な画像を読み込む 000.png〜099.png まであります

test_image = imread("images/005.png")
test_feature, test_feature_image = hog(test_image, visualize=True) 読み込んだ画像を表示してみよう
plt.subplot(1,2,1)
plt.imshow(test_image)plt.subplot(1,2,2)
plt.imshow(test_feature_image)※ matplotlibのsubplotを使うと画像やグラフを並べて表示できる53

Python Tips #1
 配列を簡単に初期化したい 通常のやり方y = []
for x in range(10):y.append(x) 簡単な書き方（実行時間も早くなる）

y = [x for x in range(10)]54

各クラスの代表との距離を計算# train_featuresの中の全ての学習サンプルとの距離をそれぞれ計算する
distances = [np.linalg.norm(feat - test_feature) \for feat in train_features]
途中で改行する時は \ を入力# 結果を見てみよう
distances

55

各クラスの代表との距離を計算
 距離のばらつきを可視化してみる# matplotlibを用いたグラフ化
plt.bar(range(len(distances)), distances)

56【復習】 最近傍法（２クラスの場合）
 入力データに最も近い教師データを出力する手法
特徴 𝑋𝑋2××××××？
×××

２クラス（○と✕）の場合？

特徴 𝑋𝑋1

57

一番近いデータを求める# 最も近いのは何番目のデータなのかを求める
idx = np.argmin(distances)# idx 番目の教師データを参照
train_labels[idx]

成功した？

# 入力画像の確認
imshow(test_image)

配列内で最も小さい値のインデックスを返す

58

認識処理の関数化# 使いやすいよう，認識処理を関数化
def predict(test_feature, train_features, train_labels):
distances = [np.linalg.norm(feat - test_feature) \for feat in train_features]
idx = np.argmin(distances)
return train_labels[idx]# 関数を使って認識してみる
predict(test_feature, train_features, train_labels)
認識したいデータ

学習データ

学習データのラベル

59

認識率を求める 多数の画像がどのくらい正しく認識できるかを調べる
 画像を読み込む# 評価用画像の読み込み関数（100枚）
def load_images():
images = []features = []for x in range(100):
img = imread("images/%03d.png" % x)feat = hog(img)
images.append(img)features.append(feat)return images, features

60

認識率を求める 多数の画像がどのくらい正しく認識できるかを調べる 正解ラベルの読み込み# 正解ラベルの読み込み関数
def load_labels():
labels = []with open("labels.txt", "r") as fin:
for x in range(100):l = int(fin.readline().strip())
labels.append(l)return labels# 評価用画像，正解ラベルの読み込み
test_images, test_features = load_images()test_labels = load_labels()

61

認識率を求める（1） 全てのテスト画像を使って認識率を計算# test_features の全ての評価用画像について，認識を行う
results = [predict(feat, train_features, train_labels) \for feat in test_features]# 認識率の計算
accuracy_score(test_labels, results)

62

認識率を求める（2） 混同行列による認識誤りの傾向分析# 混同行列を表示（正しく分類したか？どの文字をどの文字に間違えたか？）
print_cmx(test_labels, results)

63

学習データ数を増やすと認識率はどうなる？
 学習画像の準備のところの samples_per_class の値を増やして確認してみよう 「認識率を求める」のコードの再実行を忘れずに
samples_per_class = 100 # ←この部分を 1 から 100 までの値に変更！
train_images = [] # 入力画像
train_features = [] # 特徴量
train_labels = [] # 対応するクラスラベル
for c in range(10):for i in range(samples_per_class):
img = imread("classes/cls%d_%d.png" % (c, i))feat = hog(img)train_images.append(img)train_features.append(feat)train_labels.append(c)

64

まとめ
 機械学習の基礎
 最近傍法 K最近傍法 線形判別分析法

 演習（Pythonによる実践機械学習プログラミング）
 Pythonによる機械学習環境の構築
 Google Colaboratory の準備 手書き文字認識
 Nearest Neighbor （最近傍法）