パターン認識入門 パターン認識 • 音や画像に中に隠れた パターンを認識する。 – 音素・音節・単語・文・・・ – 基本図形・文字・指紋・物体・人物・顔・・・ • 「パターン」は唯一のデータではなく、 似通ったデータの集まりを表している。 – 多様性 – ノイズ • 「等しい」から「似ている」へ • 「~だ」から「~らしい」へ 「等しい」から「似ている」へ • 完全に等しいかどうかではなく、 「似ているか」どうかを判定する。 – パターンを代表する模範的データと どのくらい似ているか。 • 例:二つの文字列の比較 – 多少の文字の食い違いや、 文字の欠落を許して、似ているか。 – アラインメントという。 • 動的計画法を活用。 動的計画法 • プロ野球日本シリーズにおける優勝の確率 P(i, j): Aがシリーズに勝つまでにあとi勝、 Bはあとj勝という状況で、 最終的にAがシリーズに勝つ確率 P(i, j) = 1 i=0 かつ j>0 =0 i>0 かつ j=0 = (P(i-1, j) + P(i, j-1))/2 i>0 かつ j>0 i j 0 1 1 1 0 0 1/2 1/4 1/8 3/4 1/2 7/8 0 AとBは 同じ強さと 仮定 動的計画法 • テーブルを用意して、 再帰的な計算の重複を避ける。 • テーブルの中身を順に埋めることにより、 求める値を計算する。 • 各種の最適化問題に適用。 – アラインメント – DNA・RNAのエネルギー最小化 – 構文解析 アラインメント • アラインメント 二つ(複数)の文字列の比較 – 音声認識・文字認識 – DNAやタンパクの比較 GACGGATTAG と GATCGGAATAG ギャップ 不一致 GA-CGGATTAG GATCGGAATAG アラインメント • ぴったり同じでなくとも、 似ているかどうかを判定。 • スコア 一致 不一致 ギャップ 足し合わせる アラインメントの類似度 最適化 • 類似度が最大の アラインメント(ギャップの入れ方)を求める。 例 スコア: 一致 不一致 ギャップ ATAG と AAC をアラインするには ATA と AA のアラインメントに G と C を付加 ATA ATAG 2 これを採用! 1 A-A A-AC ATA と AAC のアラインメントに G と - を付加 ATA ATAG 0 -2 AAC AACATAG と AA のアラインメントに - と G を付加 ATAG ATAG0 -2 A-AA-A-C +2 -1 -2 アラインメントの動的計画法 • 二つの配列s0とs1の間の類似度 • a[i][j] : s0の部分配列s0[0],...,s0[i-1]と s1の部分配列s1[0],...,s1[j-1]の間の類似度 • a[i][j] = max{ a[i][j-1] + g, a[i-1][j-1] + q(i, j), a[i-1][j] + g} g : ギャップのペナルティ(負の数) q(i, j) : s0[i-1] と s1[j-1] の類似度 s0[i-1] と s1[j-1] が等しければ適当なスコア(正) 似ていればそれなりのスコア 似ていなければ不一致のペナルティ(負) Ruby 一文字の類似度を返すメソッドq # s0のi-1文字目とs1のj-1文字目の # 類似度を返す s0とs1は 大域変数とする def q(i,j) if $s0[i-1] == $s1[j-1] return 2 一致 else return -1 不一致 end end 境界条件 • a[0][0] = 0 • a[0][j] = a[0][j-1] + g (j>0) • a[i][0] = a[i-1][0] + g (i>0) • 結局 例えば g = -2 a[0][j] = j*g a[i][0] = i*g • となる。要するに、ギャップばかり。 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G s1 0 -2 -4 -6 -8 A -2 A -4 C -6 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G s1 0 -2 -4 -6 -8 A -2 2 A -4 C -6 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G s1 0 -2 -4 -6 -8 A -2 2 0 A -4 0 C -6 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G s1 0 -2 -4 -6 -8 A -2 2 0 -2 -4 A -4 0 1 2 0 C -6 -2 -1 0 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G s1 0 -2 -4 -6 -8 A -2 2 0 -2 -4 A -4 0 1 2 0 C -6 -2 -1 0 ATA AAC ATA A-A ATAG A-A- スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G s1 0 -2 -4 -6 -8 A -2 2 0 -2 -4 A -4 0 1 2 0 C -6 -2 -1 0 ATA AAC 1 ATA A-A ATAG A-AATAG A-AC Ruby トレースバック • 最大の類似度を与えるアラインメントを提示するために、 配列の最後から、それまでの選択を振り返る(トレースバック)。 i = m; j = n while i>0 && j>0 if a[i][j] == a[i][j-1] + g gap0[i] += 1; j -= 1 elsif a[i][j] == a[i-1][j-1] + q(i, j) i -= 1; j -= 1 elsif a[i][j] == a[i-1][j] + g gap1[j] += 1; i -= 1 end インクリメント デクリメント end mはs0の長さ、nはs1の長さ。 gap0[i]は、s0のi番目の文字の前に入るギャップの数。 0で初期化しておく。 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G gap1 s1 0 -2 -4 -6 -8 0 A -2 2 0 -2 -4 1 A -4 0 1 2 0 0 C -6 -2 -1 0 1 0 gap0 0 0 0 0 0 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G gap1 s1 0 -2 -4 -6 -8 0 A -2 2 0 -2 -4 A -4 0 1 2 0 1 ATA A-A C -6 -2 -1 0 1 gap0 0 0 0 0 0 0 0 ATAG A-AC スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G gap1 s1 0 -2 -4 -6 -8 0 A -2 2 0 -2 -4 1 A -4 0 1 2 0 0 C -6 -2 -1 0 1 0 gap0 0 0 0 0 0 スコア: 一致 不一致 ギャップ +2 -1 -2 ATAG A-AC s0 A T A G gap1 s1 0 -2 -4 -6 -8 0 A -2 2 0 -2 -4 1 A -4 0 1 2 0 0 C -6 -2 -1 0 1 0 gap0 0 0 0 0 0 スコア: 一致 不一致 ギャップ A s0 A A +2 -1 -2 ATAG A-AC AT T A- A G gap1 s1 0 -2 -4 -6 -8 0 A -2 2 0 -2 -4 1 A -4 0 1 2 0 0 C -6 -2 -1 0 1 0 gap0 0 0 0 0 0 Ruby トレースバックの表示 • gap0とgap1を利用し、文字列s0とs1を ギャップを含めて端末に表示する。 e.g. ATAG A-AC for i in 0..m for k in 1..gap0[i] print "-" end if i < m print $s0[i..i] end end puts "" プログラミング演習 • 与えられた二つの文字列に対して 最大の類似度を持つアラインメントを 出力するプログラムを書け。 • スコアは以下のものを使う。 スコア: 一致 不一致 ギャップ +2 -1 -2 レポート課題(萩谷) 1. align.txtの欠けている部分を埋めて、プログラムを 完成させよ。 2. いくつかの例に対して動作を確認せよ。 3. 同じ例に対して、スコアを変えて結果を比較せよ。 レポートは [email protected] に送ってください。Subjectは Subject: 情報科学レポート課題 として下さい。 〆切は1月15日。 「~だ」から「~らしい」へ • あるデータがパターンに従っているか、 否かを、断定するのではなく、 その確からしさを求める。 • 例:文字列の判別 – 文字列がパターンに従っている 確からしさを求める。 – 有限オートマトンから隠れマルコフモデルへ • ここでも動的計画法を活用。 隠れマルコフモデル • 有限オートマトンに確率を付加したようなもの。 • 遷移ではなく、状態に文字が対応。 出力文字と考える。(本質的ではない。) • 各遷移と各出力文字に確率が与えられる。 1 0.5 A: 0.2 G: 0.8 0.1 0 0.6 0.3 1.0 0.5 2 T: 1.0 A: G: C: T: 0.3 0.1 0.5 0.1 非決定的だが 確率的でない A C 1 G 0 2 T 012という状態遷移は可能。 GCTという文字列は出力可能。 010という状態遷移は不可能。 GCGという文字列は出力不可能。 遷移と出力に 確率が付加 1 0.5 A: 0.2 G: 0.8 0.1 0 0.3 A: G: C: T: 0.3 0.1 0.5 0.1 1.0 0.5 2 状態遷移 010 011 012 ... 0.6 T: 1.0 出力文字列 0.5*0.1 = 0.05 0.5*0.6 = 0.30 0.5*0.3 = 0.15 GCG 0.8*0.5*0.8=0.32 0.016 GCG GCT 0.8*0.5*0.1=0.04 0.012 0.8*0.5*0.1=0.04 0.012 GCT 0.8*0.5*1.0=0.40 0.060 マルコフ過程 • 次の状態は、現在の状態のみに依存し、 過去の履歴には依存しない。 隠れ? • 各状態の出力も確率的に定まる。 • 従って、状態遷移は直接観測できない。 • 観測可能な現象の背後にある 確率的なモデル いかさまカジノ • よく使われる例 ときどき、いかさまサイコロを使う。 0.9 1: 2: 3: 4: 5: 6: 1/6 1/6 1/6 1/6 1/6 1/6 正しいサイコロ 0.7 0.1 0.3 1: 2: 3: 4: 5: 6: 1/10 1/10 1/10 1/10 1/10 1/2 いかさまサイコロ 隠れマルコフモデル • trans[i][j] : 状態iから状態jへ遷移する確率 • init[i] : 状態iが初期状態である確率 • out[i][c] : 状態iで文字cを出力する確率 • input[t] : t番目の文字(最初の文字は0番目) 隠れマルコフモデルの出力文字列 アルゴリズムにとっては入力なので、 inputという配列に格納 評価問題 • 出力文字列wとモデルMに対して、 モデルMのもとでwが生成される確率 P(w|M)を求める。 アルゴリズムにとっては • ここでも動的計画法。 入力なので、 inputという配列に格納 • a[t][i] : 出力文字列wの最初のt文字を 出力して状態iに到達し、 状態iにおいて次の文字(t番目の文字)を 出力した確率 • いかさまカジノの場合 – 特定の目の列(例えば666)の出る確率を求める。 前向きアルゴリズム • a[0][i] = init[i]*out[i][input[0]] • a[t][i] = ( • r= Sj a[t-1][j]*trans[j][i])*out[i][input[t]] Si a[tt-1][i] P(w|M) jは状態を動く ttはinput(すなわちw)の長さ Ruby 前向きアルゴリズム for i in 0..nn-1 a[0][i] = $init[i]*$out[i][input[0]] end nnは状態の数 for t in 1..tt-1 for i in 0..nn-1 大域変数にしている p = 0.0 for j in 0..nn-1 p += a[t-1][j]*$trans[j][i] end a[t][i] = p*$out[i][input[t]] end end r = 0.0 for i in 0..nn-1 r += a[tt-1][i] end 復号化問題 • 出力文字列wとモデルMに対して、 wを出力した最も確からしい状態列を求める。 • Viterbiのアルゴリズム • d[t][i] : wの最初のt文字を出力し 状態iに到達する状態列の最大確率に 状態iにおいて次の文字(t番目の文字)を 出力する確率を掛けたもの • prev[t][i] : 最大確率を持つ状態列の直前の状態 • いかさまカジノの場合 トレースバック! – 特定の目の列(例えば666)に対して、 どこでいかさまサイコロが使われたかを推定する。 Viterbiのアルゴリズム • d[0][i] = init[i]*out[i][input[0]] • d[t][i] = (max d[t-1][j]*trans[j][i])*out[i][input[t]] j • r = max d[tt-1][i] i S max Ruby Viterbiのアルゴリズム for i in 0..nn-1 d[0][i] = $init[i]*$out[i][input[0]] end for t in 1..tt-1 for i in 0..nn-1 このときのjをkに記憶 p = 0.0; k = 0 for j in 0..nn-1 if (d[t-1][j]*$trans[j][i] > p) p = d[t-1][j]*$trans[j][i]; k = j end d[t][i] = p*$out[i][input[t]]; prev[t][i] = k end end end 記憶しておいた r = 0.0; m = 0 kをprev[t][i]に設定 for i in 0..nn-1 if (d[tt-1][i] > r) r = d[tt-1][i]; m = i このときのiをmに記憶 end end 推定問題 • 以上の他に、 観測された出力列(複数)から、 モデルのパラメータ(確率)を 推定する問題が重要である。 • いかさまカジノの場合 – 出た目の列(複数)から、 いかさまサイコロへ切り替える確率、 公正なサイコロに戻す確率、 いかさまサイコロの目の確率を推定する。 プログラミング演習 • いかさまカジノに対して、 前向きアルゴリズムを実装せよ。 • いかさまカジノに対して、 Viterbiのアルゴリズムによって、 与えられた文字列を出力する 最も確からしい状態列を求める プログラムを書け。 実際のパターン認識 • 音声認識 実際は はるかに複雑 – 波形データから音素を抽出 – 音素列に対する隠れマルコフモデル • 手書き文字認識 – ストロークをセグメントに分割 – セグメントの列に対するアラインメント 実際は もっと複雑 • 画像認識 – 様々な前処理 • エッジ検出・背景分別・・・ – アラインメント・隠れマルコフモデル・・・ 画像の種類に 応じた様々な 手法
© Copyright 2024 ExpyDoc