Perlで機械学習

機械学習アプリを作りましょう

Yomitan.pm #3

今日のメニュー

  1. 機械学習の正体に迫る!
  2. 特徴があるから違いが判る
  3. 文字が読めるのはなぜ
  4. 自然言語処理で遊ぶ
  5. Perlの機械学習モジュールをご紹介
  6. 魔法使いに俺はなる!

機械学習の正体に迫る!

そもそも「機械学習」って何?

簡単に言うと、
「訓練データを用いて機械に自動分類・判別させる」
技術や方法論です。

機械学習を含む、さらに大きな概念として「人工知能」があります。

分かりやすい身近な応用例

例えば・・・

  • 硬貨・紙幣識別 : 貨幣の種類を判別
  • 手書き文字認識 : 書かれている文字が何かを判別
  • 画像認識 : 指静脈認証、笑顔検出
  • スパムメールフィルタ

などなど・・・

「パターン認識」と「機械学習」

かつては別物として扱われていましたが、
現在主流の考え方によると特に違いはありません(笑)

「認識」と「学習」の言葉の違いを述べると・・・

物事の区別がつくようになるまでの訓練過程が「学習」、
区別する過程が「認識」です

機械が学習して、機械が識別する

それが機械学習

訓練データを使った学習は大前提

機械が識別する

それがパターン認識

機械による学習の有無は不問

パターン認識のムダな補足

かつてはルールベースの識別機械が主流だったので、「パターン認識」は人間が人生経験で習得した識別方法も含む概念です。

つまり、学習する過程を人間が行うのか機械が行うのかは問わないのが「パターン認識」と言えます。

(かつての郵便番号のOCRやバーコードリーダなどは機械による学習のプロセスがありません)

そういえば「学習」って何?

少し哲学的な疑問。
学習といえば学ぶこと。
学ぶといえば「先生」を思い浮かべる・・・。
普通は学ぶためには教師が必要だよな。
あ、でも先生が居なくても経験だけからいろいろと学べるよなぁ・・・。

教師あり学習と教師なし学習

  • 教師あり(supervised) : 先生が教えてくれる学習
  • 教師なし(unsupervised) : 経験から空気を読んで自分で学習

大まかに上記2つのタイプがあります。
(どちらにも属さないような手法もあります)

教師なし学習は置いといて・・・ (^_^;)

まずは教師ありで機械学習の本質を

学習風景 その1

教師「これは新鮮です。...で、これは腐ってます。」

(・・・・・延々と教育が続く・・・・・)

教師「ハイ!ではこれは新鮮?それとも腐ってる?」

???「たぶんそれはしんせんなもの。ちぃおぼえた」

初めて見た物でも良し悪しが判る?

当たり前だけど、冷静に考えると不思議!

腐ったものはニオイが「特徴的」

「うわくさい、これくさってるだろ」

いやなニオイで腐ったものか判る

間違えるかもしれないけど、妥当な判断方法!
見た目でもわかるが、ニオイでヤバさが判る!

ニオイを重要視すれば良いことを学習した!?

判別に役に立たない特徴は切り捨てる

たくさんの特徴が情報として与えられても、判別するときに役に立たない特徴は切り捨てる。

「学習」して「役に立つ情報」がわかる

学習風景 その2

教師「この人は男で、背が高い。...で、この人は女で、背は高くない」

(・・・・・延々と教育が続く・・・・・)

教師「では、この人はどんな人かな?」

生徒A「見た目からいうと女っぽいです」
生徒B「見た目と身長から、背は高い方かなぁ」

教師あり学習はレッテル貼り

教師がラベルを貼って教える。
「この人は男」
「この人は背が高い」

今度は1つの対象に複数のラベルを貼りました

ラベルの種類ごとに...

使う特徴が違うかも?

  • 性別 : 顔つき、ヒゲ、胸の膨らみなど
  • 背の高さ : 顔つき、ヒゲ、胸の膨らみ、身長

...あれれ?「背の高さ」は「身長」だけで良くないか?
「背の高さ」ってなに?

「背が高い」はあいまい

「背が高い人」は主観的です。
「身長」と違って人間の感性で決まる。
しかも性別によって判断が変わる

女性で165cmなら背が高いほう
男性で165cmなら背が高いとは言えない

「背が高いか」というのは、性別を特定できる情報も必要です

たくさん例示して一般常識を教え込む必要がありますね。

でも、極端な例ばかり出すと
非常識な機械になりますよ!

長身スーパーモデルの女性、男性騎手、NBA選手、などなど

人間の感性は曖昧な部分がある

偏りのないデータで学習しても、問題は残ります

男性で172cmなら、高いとも高くないとも言えない

白黒付けにくいものは機械学習でも苦手です。そもそも人間ですらボーダーライン上の例は難しいです。

まとめ

  • 機械が学習して機械が識別するのが「機械学習」
  • 教師ありはラベルを貼ってあげるもの
  • 識別に必要な特徴と不要な特徴を学習する
  • 幅広く経験をたくさん積むことは重要
  • 極端に偏った経験ばかりを積むとダメです

特徴があるから違いが判る

「なんかロシア製のアサルトライフルっぽい名前のアイドルグループがあるじゃん?なんとかフォーティセブンだっけ?みんな目と耳が2つずつあって鼻と口が1つずつあるから区別がつかないんだよな」

「特徴」って何?

違うモノを区別するために、利用できるかもしれない情報です

所属人数の多いアイドルグループでも、細かな顔の特徴を利用すれば区別ができます

  • 目の幅、高さ、大きさ
  • 顔の輪郭、顎の尖りかた
  • 鼻の幅、長さ、大きさ
  • 各パーツ間の距離
  • その他、肌の色、ほくろなど

隣国のミスコンは人間でも無理でした

もう髪型とか服装とか体格で区別するしか・・・

人間には顔のパーツの特徴はわかるけど・・・

機械でその特徴を扱うのはどうすればいいのか?

「特徴」を機械(コンピュータ)が扱える数値と記号に変換する必要があります

コンピュータが扱いやすいデータ

    • 数値(定量的な情報)
    • 個数や質量、長さなど、大小関係があり四則演算が意味をなすもの
    • 日付や時刻など、大小関係と和差に意味があるもの
    • 記号(定性的な情報)
    • シリアルナンバーや順位など、大小関係があり内部では数値として表現するが、四則演算の対象にならないもの。
    • 性別や名称、単語など、大小関係もなく単なるカテゴリや名前として扱うもの。

・・・とりあえず「特徴」を定量化できればよさそう。

画像処理では

画像から人の顔を識別するときは、
Haar-like特徴量というものがよく使われます

上記のようなエレメントを画像上でスキャンさせて、黒い部分の画素値の合計から白い部分の画素値合計を引き算する

え?これが特徴になるの?

なる。
画像に写った物体を区別・識別するために使える。

人間にとって、あまり直感的ではない

わかりにくいのですが、Haar-like特徴量は画像データから「物体の境界」「線」「点」などを区別できるように作られています。

膨大な種類のエレメントを使って数値化し、それら数値の違いから「人間の顔か否か」を判定する

人間がやってあげる

機械を使って物事を区別、識別させるためには、
識別できるような特徴を取り出す必要があります

それを人間様がやってあげましょう!

ちなみに物体認識といえばOpenCV

機械に物体を認識させるためのライブラリとしては、 OpenCV が有名です。
機械学習も含まれているので、迷わず使っちゃいましょう。

(私は使ったことはありませんが)

まとめ

  • 「特徴」は、区別・判別するために使えるかもしれないもの
  • 特徴を定量的なものに、特徴量に変換する必要がある
  • どんな特徴をどう使うかは人間が決める

文字が読めるのはなぜ

人間は汚い文字も読めちゃう

なんとか読めたり、読めなかったり
似ている文字はどうしても区別がつかなかったり

最近は機械も読めるように

Googleさんの手書き文字検索とか、身近な存在になりました

これ、機械学習が応用されています

「手書き文字認識」
機械による学習と認識で実現されたアプリケーションです。

無料で使える認識エンジンがあります!

Zinnia

手書き文字認識エンジン Zinnia

「SVMを用いたポータブルで汎用的なオンライン手書きエンジンです」

SVMって?

SVMとは、Support Vector Machineと呼ばれる教師あり学習の一つです。

SVMのすごいところ

イメージとしては、区別したいデータの境界線を、出来る限り距離を離して引いてくれます。

オンライン手書き認識って?

タブレット端末などに直接文字を書く時は、書き順がわかります。
書き順を活用する認識方法を「オンライン」といいます

OCRなどは書き順の情報を活用できないので、「オフライン」といいます

つまりZinniaは何をやってる?

数値化された筆順(座標の変化)から特徴量を抽出し、
書かれた文字が何かを判別している!

zinnia内部の筆跡表現

S式で表現します

(character
 (value 認識したい文字)
 (width キャンバス幅)
 (height キャンバス高さ)
 (strokes
   ((0画目x 0画目y) ... (0画目x 0画目y))
   ((1画目x 0画目y) ... (1画目x 1画目y))
   ((2画目x 2画目y) ... (2画目x 2画目y))
   ...
 )
)

これを使うと・・・

こんなすごいことができます。
外部リンク:Ajaxを使った手書き文字認識

perlからZinniaを呼び出すには?

swig対応なので、梱包のzinnia.pmを使えばOK!

my $s = new zinnia::Character;  # S式パーサ
my $r = new zinnia::Recognizer; # 認識モデル
$r->open(モデルファイルまでのpath); # モデルファイルのロード(Zinnia-Tomoeなど)
$s->parse(S式の文字列);
my $result = $r->classify($s, 5); # それらしい文字の候補を上位5つ返す
print $result->value(0); # 最もそれらしい候補の文字を出力

自然言語処理で遊ぶ

日本語の文章をマイニング

日本語のテキストマイニング環境をインストールすると、とても楽しいことができます。

形態素解析

文章を、意味のある最小単位まで分割

すもももももももものうち
すもも  名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
もも    名詞,一般,*,*,*,*,もも,モモ,モモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
もも    名詞,一般,*,*,*,*,もも,モモ,モモ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
うち    名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
      
(MeCabの解析結果)

日本語の文章を単語に分割できる

英語と違って、日本語は単語の間にスペースがありません。
そのため単語の境界を簡単に見つけられるこのツールは便利ですね。

品詞情報が取り出せる

名詞、形容詞といった、単語の品詞(parts of speech)を取り出すことができます。POSタギングと呼ばれています。

  • 名詞 : 「桃」「人間」「文書」など
  • 動詞 : 「働く」「怠ける」など
  • 形容詞 : 「暑い」「厚い」「安い」など
  • などなど

さらに詳細なPOS情報も取得可能

名詞、動詞、形容詞などの大まかな品詞だけでなく、自立語の判別ができます。

「やすい」:「使い易い」は非自立語、「値段が安い」は自立語

動詞や形容詞の活用を取り除く