Skip to content

Instantly share code, notes, and snippets.

@kubo39
Last active October 4, 2015 14:58
Show Gist options
  • Save kubo39/2656848 to your computer and use it in GitHub Desktop.
Save kubo39/2656848 to your computer and use it in GitHub Desktop.

パターン認識

ものがどのくらい似ているか=類似度

似ている=相対量

  • 他のものがないと判断できない(正例、負例)

パターン認識アルゴリズム

  • kNN

  • naive bayes

  • 決定木

  • neural network

  • SVM

ここではSVMが重要、次にkNN

パターン認識の評価

confusion matrix

(例)

       認識結果1 認識結果2 認識結果3

正解データ1   10     0     0

正解データ2    0     9     1

正解データ3    2     7     1

横:認識結果 縦:正解データ

精度 = 正解したデータ / 全部のデータ

上のグラフはデータ1の認識精度が高く、データ3の認識精度が低いといえる

confusion matrixでは、

精度 = 対角線の数の合計 / 表の数の合計

上のグラフでは、

精度 = (10+9+1) / (10+0+0+0+9+1+2+7+1) = 20 / 30

 66.6666666...... %

パターン認識の目標:精度をあげる

アルゴリズムの評価方法

ダメダメ: 全部のデータを使って学習

いい:k-fold cross-validation

全データをランダムにk分割

分割したデータのまとまりをひとつ選択し、それ以外のデータを学習データとして扱って最初に選択したデータをテストする。それを分割した数だけ繰り返す。

各パターン認識アルゴリズム

kNN(k近傍法)

最も単純な分類アルゴリズム

  • アルゴリズムの骨子

未知データにたいし、正例不例全ての点との距離を求め、距離が短いほうのクラスに分類する。

ダメダメな点:

認識の度に全ての学習データとの距離を計算

学習データ増えると大変

いい点:

実装が簡単

理論的にはよくわかっていない

距離関数をうまくえらぶとSVMと同性能に

ベイズ

けっこう単純なアルゴリズム

ベイズの定理でぐぐれ

昔、ポール・グラアムというスーパーハカーがこれを使ってスパムフィルタリングを実装したので、プログラマ界隈では有名

ダメダメ:

正直あまり使いどころがない

いいところ:

実装しやすい

決定木

アルゴリズムはそこそこ複雑

派生が多い

学習結果がわかりやすい

ダメダメ:

あまり性能よくない

特徴量増えると大変

ここがおもしろい:

見た目がわかりやすい

ニューラル・ネットワーク

脳のニューロンをモデル化したアルゴリズム

歴史あるアルゴリズム

実装簡単。並列化もできる、性能も高い

入力層:ユニット数=特徴量の次元数

隠れ層: ユニット数=勘

出力:ユニット数=クラス数

分類には微分可能な関数でなければいけない ->学習のために逆関数が定義できなければならない

パラメータ 隠れ層の数、隠れユニットの数、etc

とにかくいっぱいおっぱい

ダメダメなところ:

パラメータの選択がむずかしい

いいところ:

(理論的には)どんな関数でも近似できる

実装が簡単

SVM(サポートベクターマシーン)

とりあえずこれ使えばOk

大抵の問題で一番いい性能

チューニングも簡単

実装がむずかしいがライブラリは豊富に容易されている(OpenCV,libsvm)

理論的には極めて難しい

  • 以下は線形SVMのアルゴリズム

1、正例負例からいくつかのサポートベクタを選択

2、サポートベクタとの距離の総和が最大となる回帰直線を求める

非線形SVMでは、線形分離できないデータを高次元空間に写像することで線形分離できるかたちにもっていく。

写像すると計算量が増えるので、それを高速化するためのテクニックがカーネル正則化

具体的にはデータを内積でかける形に変形して、それをカーネルと呼ばれる特殊な関数に置き換える。

絶対に使えるように、そうでないとパターン認識は厳しい

(Rのgammaとcost調べる指標) plotは濃い青のところによいパラメータがある

  • gammaとcostの決定

チューニング前と後ろで学習でーたの正解率が大きく向上

つまりgammaとcostの値は非常に大事

ここがダメダメ:

学習が超重い、学習データnとするとO(n^3)

カーネルトリック使うと並列化できない

ここがおもしろい:

性能高すぎわろた

とにかくSVM使っとけばいいんじゃないですかね

Rを使う

RStudioが安パイ

ライブラリのインストール

install.packages('e1071')

今回のまとめ

  • 色々な分類器を使った

  • パターン認識はツール

  • 基本はSVM、それでだめだったらそのとき考える

  • 理解はあとから、とりあえず使えることが大事

library(e1071)
x <- order(rnorm(nrow(iris)))
iris_learn <- iris[x[1:100],]
iris_test <- iris[x[101:150],]
naiveBayes(Species ~ ., data=iris_learn) -> model
predict(model, iris_test)
table(iris_test$Species, predict(model,iris_test)) -> result
result
acc <- function(t) sum(diag(t)) / sum(t)
acc(result)
x <- order(rnorm(nrow(iris)))
iris_learn <- iris[x[1:100],]
iris_test <- iris[x[101:150],]
nrow(iris)
nrow(iris_learn)
nrow(iris_test)
library(klaR)
sknn(Species ~ .,data=iris_learn,kn=1) -> model
predict(model, iris_test)
table(iris_test$Species, predict(model,iris_test)$class) -> result
result
acc <- function(t) sum(diag(t)) / sum(t)
acc(result)
x <- order(rnorm(nrow(iris)))
iris_learn <- iris[x[1:100],]
iris_test <- iris[x[101:150],]
library(nnet)
nnet(Species ~ ., data=iris_learn, size=5) -> model
predict(model, iris_learn)
table(iris_test$Species, predict(model, iris_test, type="class")) -> result
result
acc <- function(t) sum(diag(t)) / sum(t)
acc(result)
x <- order(rnorm(nrow(iris)))
iris_learn <- iris[x[1:100],]
iris_test <- iris[x[101:150],]
library(mvpart)
rpart(Species ~ .,data=iris_learn) -> model
plot(model)
text(model)
x <- order(rnorm(nrow(iris)))
iris_learn <- iris[x[1:100],]
iris_test <- iris[x[101:150],]
library(e1071)
svm(Species ~ ., data=iris_learn) -> model
predict(model, iris_test)
table(iris_test$Species, predict(model, iris_test)) -> result
result
acc <- function(t) sum(diag(t)) / sum(t)
acc(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment