集合知プログラミング勉強会 7章(前半)

43
集合知プログラミング勉強会 7章 決定木によるモデリング (前半) 2013.02.12 #TokyoCI 担当 : @_kobacky

Upload: koji-ono

Post on 14-Apr-2017

2.570 views

Category:

Documents


0 download

TRANSCRIPT

集合知プログラミング勉強会7章 決定木によるモデリング (前半)

2013.02.12 #TokyoCI担当 : @_kobacky

今日の話の流れ

•決定木はどのように使われる?

•どうやって決定木を構築するのか?

•ジニ不純度, エントロピー, 情報ゲインとは?

•決定木による予測

決定木はどのように使われる?

まずは状況設定

•アカウント登録制のWEBサイトを運営

•無料トライアル版あり

•トライアル終了時に有料ユーザーへ移行 or 離脱

•どんな特徴の無料ユーザーが有料ユーザーに移行しやすいか知りたい

•無料ユーザー登録時にユーザー情報を収集する

•その無料ユーザーが最終的に有料ユーザーになったか調べる

こんなデータが取れましたユーザーの行動と購入サービス (学習データ)リファラー 住所 FAQ読? 見たページ数 購入サービスSlashdot USA Yes 18 NoneGoogle France Yes 23 PremiumSlashdot UK No 21 NoneDigg USA Yes 24 Basic

Kiwitobes France Yes 23 Basic・・・その他9件のユーザーのデータ

そこに新規無料ユーザー来たる!

リファラー 住所 FAQ読? 見たページ数 購入サービスSlashdot USA Yes 18 NoneGoogle France Yes 23 PremiumSlashdot UK No 21 NoneDigg USA Yes 24 Basic

Kiwitobes France Yes 23 Basic・・・その他9件のユーザーのデータ

リファラー 住所 FAQ読? 見たページ数 購入サービス(直接) USA Yes 5 ???

ユーザーの行動と購入サービス (学習データ)

購入サービスのわからない新規無料ユーザーの行動(評価データ)

そこに新規無料ユーザー来たる!

リファラー 住所 FAQ読? 見たページ数 購入サービスSlashdot USA Yes 18 NoneGoogle France Yes 23 PremiumSlashdot UK No 21 NoneDigg USA Yes 24 Basic

Kiwitobes France Yes 23 Basic・・・その9件のユーザーのデータ

リファラー 住所 FAQ読? 見たページ数 購入サービス(直接) USA Yes 5 ???

ユーザーの行動と購入サービス (学習データ)

購入サービスのわからない新規無料ユーザーの行動(評価データ)

サービスを購入するのか?生データからは判断困難。

そこで決定木です

学習データから決定木を構築

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 3

no yes

※注 本章のプログラム・サンプルデータで生成される決定木は   正確には「None : 3, Basic : 1」の部分がさらに分類されます。

決定木とは

• 予測モデルの一つ

• 目的変数が同じデータがなるべく同グループに属するようデータを分類する分岐条件を表す木構造。分岐条件は説明変数によって表される。

• 目的変数:予測したい変数(「購入サービス」)

• 説明変数:目的変数の要因となる変数(「リファラ」「住所」など)

• 決定木の構成要素

• 枝(ノード):分岐条件のこと

• 葉(帰結):条件分岐を辿った結果の帰結

ref = google ?

Basic : 4

評価データの購入サービスを予測

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 1

no yes

ref = (direct)address = USA

FAQ = Yespage = 5

評価データ

評価データの購入サービスを予測

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 1

no yes

ref = (direct)address = USA

FAQ = Yespage = 5

評価データ

評価データの購入サービスを予測

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 1

no yes

ref = (direct)address = USA

FAQ = Yespage = 5

評価データ

評価データの購入サービスを予測

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 1

no yes

ref = (direct)address = USA

FAQ = Yespage = 5

評価データ

評価データの購入サービスを予測

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 1

no yes

ref = (direct)address = USA

FAQ = Yespage = 5

評価データ

Basicサービス購入者4人の帰結に到達。評価データのユーザーはBasicサービスを購入すると予測できる。

では決定木はどうやって構築するのか?

もう一度決定木を眺めてみると・・

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 3

no yes

もう一度決定木を眺めてみると・・

ref = google ?

ref = slashdot ? page >= 21 ?

FAQ = Yes ? FAQ = Yes ?

None : 3Basic : 1 Basic : 4

None : 3

None : 1 Basic : 1

Premium : 3

no yes

なぜ「リファラーがgoogleか否か」で分類するのか??

分類条件の決定方法について考えましょう

そもそも有効な分類条件とは?

①なぜリファラーがgoogleか否かで分岐すれば良いとわかるの?

リファラー 住所 FAQ読? 見たページ数 購入サービスSlashdot USA Yes 18 NoneGoogle France Yes 23 BasicSlashdot UK No 21 NoneDigg USA Yes 24 Basic

Kiwitobes France Yes 23 Basic

そもそも有効な分類条件とは?

①なぜリファラーがgoogleか否かで分岐すれば良いとわかるの?

リファラー 住所 FAQ読? 見たページ数 購入サービスSlashdot USA Yes 18 NoneGoogle France Yes 23 BasicSlashdot UK No 21 NoneDigg USA Yes 24 Basic

Kiwitobes France Yes 23 Basic

address = USA ? page >= 23 ?

None : 2 Basic : 3None : 1Basic : 2

None : 1Basic : 1

no yes no yesどっち?

そもそも有効な分類条件とは?

①なぜリファラーがgoogleか否かで分岐すれば良いとわかるの?

リファラー 住所 FAQ読? 見たページ数 購入サービスSlashdot USA Yes 18 NoneGoogle France Yes 23 BasicSlashdot UK No 21 NoneDigg USA Yes 24 Basic

Kiwitobes France Yes 23 Basic

page >= 23 ?

None : 2 Basic : 3

no yes

こっち!address = USA ?

None : 1Basic : 2

None : 1Basic : 1

no yes

購入サービスがよりきれいに分類される条件の方が良い

「きれいに分類される」を定量的に評価するために

•ジニ不純度、エントロピー

•集合に属する要素の分布のバラつき加減を表す尺度

•情報ゲイン

•分類により集合に属する要素のバラつき加減がどの程度減少したかを表す尺度

0246

None Basic Premium

集合に属する要素の分布とは・・↓

ジニ不純度とは

•集合中のアイテムの一つに、ランダムに帰結を当てはめる場合の期待誤差率

• 値が高いほど集合の要素はバラついている

• giniimpurity = Σ (P( a ) × P( a ))

• a ∈ A = {None, Basic, Premium}

• P( a ) :集合A内の要素aが選ばれる確率

• P( a ) :要素aに対して誤った帰結が当てはめられる確率

a ∈ A

ジニ不純度の計算例None : 7Basic : 6

Premium : 30246

None Basic Premiumginiimpurity = (7/16 × 9/16) + (6/16 × 10/16) + (3/16 × 13/16) = 0.6328

None : 3Basic : 1

0246

None Basicginiimpurity = (3/4 × 1/4) + (1/4 × 3/4) = 0.375

ジニ不純度を算出するプログラムdef giniimpurity(rows): total=len(rows) counts=uniquecounts(rows) imp=0 for k1 in counts: p1=float(counts[k1])/total for k2 in counts: if k1==k2: continue p2=float(counts[k2])/total imp+=p1*p2 return imp

rows →ジニ不純度計算対象のデータ集合uniquecounts(rows) →集合に属す要素の目的変数に関する  度数分布を算出

None : 7Basic : 6

Premium : 3

エントロピー

•集合中の無秩序の量  (p161 より引用)

• 値が大きいほど集合は無秩序。

• entropy = -1 × Σ(P( a ) × logP( a ))

• a ∈ A = { None, Basic, Premium }

• logの底は2

a ∈ A

エントロピーの計算例None : 7Basic : 6

Premium : 30246

None Basic Premiumentropy = -1 × ((7/16 × log(7/16)) + (6/16 × log(6/16)) + (3/16 × log(3/16))) = 1.5052

None : 3Basic : 1

0246

None Basicentropy = -1 × ((3/4 × log(3/4)) + (1/4 × log(1/4))) = 0.8112

エントロピーの比較①(集合の要素数固定で比較してみた)

None : 5Basic : 1

0

2

4

6

None Basicentropy = -1 ×((5/6 × log(5/6)) + (1/6 × log(1/6))) = 0.6500

None : 3Basic : 3

0

2

4

6

None Basicentropy = -1 ×((3/6 × log(3/6)) + (3/6 × log(3/6))) = 1.0000

エントロピーの比較②(各クラスの要素数固定で比較してみた)

None : 2Basic : 2

0

2

4

6

None Basicentropy = -1 × ((2/4 × log(2/4)) + (2/4 × log(2/4))) = 1.0000

None : 2Basic : 2

Premium : 20

2

4

6

None Basic Premiumentropy = -1 × ((2/6 × log(2/6)) + (2/6 × log(2/6)) + (2/6 × log(2/6))) = 1.5850

エントロピーを算出するプログラム

def entropy(rows): from math import log log2=lambda x:log(x)/log(2) results=uniquecounts(rows) ent=0.0 for r in results.keys(): p=float(results[r])/len(rows) ent=ent-p*log2(p) return ent

rows →エントロピー計算対象のデータ集合uniquecounts(rows) →集合に属す要素の目的変数に関する  度数分布を算出

None : 7Basic : 6

Premium : 3

情報ゲイン

•集合の分類操作によるエントロピーの減少量

• 分類後のエントロピーは、真集合のエントロピーと偽集合のエントロピーの加重平均としている

• 分類操作によってどれだけ集合がきれいに分割されたかを示す

• (エントロピーではなくジニ不純度を使っても良い)

gain = [分類前のentropy] - [分類後のentropy]

[分類後のentropy] = tr × entropy(真集合) + (1 - tr) × entropy(偽集合)

(tr = [分類後の真集合要素数] / [分類前の集合要素数])

情報ゲインの計算例(分岐条件を決めて、集合を分類)

None : 7Basic : 6

Premium : 3

None : 6Basic : 5

Premium : 0

None : 1Basic : 1

Premium : 3

ref = google ?

no yes

情報ゲインの計算例(各集合のエントロピーを計算)

None : 7Basic : 6

Premium : 3

None : 6Basic : 5

Premium : 0

None : 1Basic : 1

Premium : 3

ref = google ?

no yes

1.5052

1.37100.9940

情報ゲインの計算例(分類後集合のエントロピーを加重平均で計算)

None : 7Basic : 6

Premium : 3

None : 6Basic : 5

Premium : 0

None : 1Basic : 1

Premium : 3

ref = google ?

no yes

1.5052

1.37100.9940

0.9940 × 11/16 + 1.3710 × 5 / 16 = 1.1118

情報ゲインの計算例(分類後の集合エントロピーを加重平均で計算)

None : 7Basic : 6

Premium : 3

None : 6Basic : 5

Premium : 0

None : 1Basic : 1

Premium : 3

ref = google ?

no yes

1.5052

1.37100.9940

0.9940 × 11/16 + 1.3710 × 5 / 16 = 1.1118

Gain = 1.5052 - 1.1118 = 0.3934

分類条件の決定

• 全ての分類条件で情報ゲイン計算して、情報ゲインが最大になる条件を選んでいるだけ。

• リファラーがGoogle?

• FAQ読んだ?

• 見たページ数 >= 18 ?

• 見たページ数 >= 21 ?

• ・・・etc (全部です)

• 本章のデータでは「 リファラーがGoogle?」で分類すると情報ゲインが最大になる。

あとは再帰的に分類して決定木を構築None : 7Basic : 6

Premium : 3

None : 6Basic : 5

Premium : 0

None : 1Basic : 1

Premium : 3

ref = google ?

no yes

さらに分類処理 さらに分類処理

あとは再帰的に分類して決定木を構築None : 7Basic : 6

Premium : 3

None : 6Basic : 5

Premium : 0

None : 1Basic : 1

Premium : 3

ref = google ?

no yes

さらに分類処理 さらに分類処理

集合に対する(最良の)分類による情報ゲインが正( > 0)である限り分類を繰り返す。

決定木の構築プログラム

def buildtree(rows,scoref=entropy): if len(rows)==0: return decisionnode() current_score=scoref(rows)

best_gain=0.0 best_criteria=None best_sets=None column_count=len(rows[0])-1 for col in range(0,column_count): column_values={} for row in rows: column_values[row[col]]=1###(続く)

分類前のエントロピー( or ジニ不純度)

各説明変数に対するループ

決定木の構築プログラム

###(続き) for value in column_values.keys(): (set1,set2)=divideset(rows,col,value) # Information gain p=float(len(set1))/len(rows) gain=current_score-p*scoref(set1)-(1-p)*scoref(set2) if gain>best_gain and len(set1)>0 and len(set2)>0: best_gain=gain best_criteria=(col,value) best_sets=(set1,set2) if best_gain>0: trueBranch=buildtree(best_sets[0]) falseBranch=buildtree(best_sets[1]) return decisionnode(col=best_criteria[0],value=best_criteria[1], tb=trueBranch,fb=falseBranch) else: return decisionnode(results=uniquecounts(rows))

情報ゲイン

現ループの説明変数が取り得る各値に対するループ

分類した真集合と偽集合に対して再帰的に木を構築

部分木のルートノード返却

帰結を返却

構築した決定木による予測プログラム

def classify(observation,tree): if tree.results!=None: return tree.results else: v=observation[tree.col] branch=None if isinstance(v,int) or isinstance(v,float): if v>=tree.value: branch=tree.tb else: branch=tree.fb else: if v==tree.value: branch=tree.tb else: branch=tree.fb return classify(observation,branch)

葉に辿り着いたら、帰結を返却する

再帰的に木を辿る