ガジェット通信

見たことのないものを見に行こう

アドテクの裏側で暗躍!?ユーザーの嗜好を紐解くベイジアンネットワークとは

DATE:
  • ガジェット通信を≫

ベイジアンネットワーク -「因果」のモデリング

ベイズの定理を説明した前編では、以下のような問いを設定していました。

患者Aは咳が出て節々が痛く、喉が腫れている。病名は何?
プリンターが不調。縦線のノイズが入る。どこが故障している?

それぞれ、医師やカスタマーサポートであれば解決できる問題です。しかし、同じ問題をコンピュータで解けたら嬉しいと思いませんか?

実は「因果」という概念を抽象化し、結果から原因を推定可能にした数理モデルがあります。

それがベイジアンネットワーク。条件付き確率を基礎とするこのモデルは、医療からWebマーケティングまで広く活用されています。

キーワードは「明確な結果」から「不明確な原因」を推測することです。早速具体例を見てみましょう。

ひとつの結果に複数の原因が紐付く – 診察のモデル

「結果から原因を推察する」ことを生業にしている職業はたくさんあります。例えばお医者さんですね。

診察の難しさの一つは、「ある症状をもたらす病気は、一つではなく複数ある」ということ。このような経験的判断を、計算機に肩代わりしてもらうことを考えてみましょう。

その目的の為には、ベイジアンネットワークの構築が有効です。実際にやってみましょう。

作業1:症状と病気をリストアップし、関係を有向グラフにする

まず、「有向グラフ」というデータ構造を用いて、症状と病気の定性的関係を記述するところから始めます。

考えうる「症状」と「病気」と洗い出し、リストアップします。並べて書いた病名や症状などを丸で囲み、それらをノードと呼ぶようにします。

そして、「症状」に対して原因となる「病気」を探し出し、病気から症状へ向けて矢印を引きます。矢印のことは有向枝と呼びます。

なお、ある病気が別の病気を誘発するというような場合には、病気から病気へ向けた有向枝を引いても構いません。

こうして、「ノード」と「有向枝」を用いて記述される関係性が「有向グラフ」です。

矢印をたどって一周してしまうような経路があるものは、以下の議論を適用できませんが、それ以外のグラフは全てベイジアンネットワークの範疇です。

作業2:条件付き確率を算出する

作業1で描き上げたグラフには、たくさんの有向枝が引かれています。有向枝の全てに、条件付き確率を割り振っていくのが次の作業です。

例えば「インフルエンザ」から「節々の痛み」に引かれた枝があるとすれば、「インフルエンザに罹った人が、節々の痛みを訴える割合」を算出する必要があります。ここで、前編でベイズの定理を導出するのに使った以下の式を思い出しましょう。

  …(3)

この式(3)は単体で使うこともできます。実際にやってみましょう。

まずは、事象を定義します。

事象
説明
A
患者が節々の痛みを訴える
B
患者はインフルエンザである

このようにAとBを定義すると、式(3)の意味が見えてきますね。

左辺の は「インフルエンザの患者が、節々の痛みを訴える確率」を表すようになります。

縦棒の右側の事象Bを前提として、左側の事象Aが起こる確率を表すのが なのでした。

ここで、式(3)の右辺に登場する二つの確率は何を意味するでしょうか。

これらの確率は、「一定期間」の「病院の患者」全員のリストを持っていれば、その中で何割の患者が条件を満たすか調べることで求まります。

仮に、以下のように確率が求まるとしましょう。

すると、条件付き確率は以下のように求まります。

このようにして求まる条件付き確率を、事後確率と呼ぶのでしたね。

このような手続きを繰り返すことで、全ての有向枝に対して条件付き確率を算出することができます。

この作業のポイントは、直接の因果関係があるノード同士の条件付き確率以外は計算しなくてもよいことです。

全ての症状と病気の組み合わせが起こる確率について計算していると大変な時間がかかります。ノードがn個存在する場合、2^n-1個の確率を導出せねばならず、指数爆発を引き起こします。

これから算出する「確信度」の計算には、直接の因果関係の確率しか使いませんから、計算の手間が大いに省かれて効率化されています。

作業3:患者の症状から確信度を算出する

いよいよ、患者がどのような病気に罹っているのか推定することができます。

まずサンプルとなる患者のカルテを用意しましょう。すべての「症状」に対し、その症状があるかないか、体温などであればどの区間に入るかを調べます。

これは何らかの病気によって引き起こされたものと考え、その患者の病気の組を推定しましょう。尚、複数の病気の併発も考慮します。

ここでは非常に単純化されたモデルとして「風邪」か「盲腸」かを識別するベイジアンネットワークを作ってみましょう。

以下のようにノードを定義します。

風邪はすべての症状を引き起こすことがありますから、 から , , への有向枝を引きます。

盲腸といえば腹痛ですが、熱が出ることもありますから、 からは , への有向枝を引きます。

風邪のせいで盲腸になったり、盲腸のせいで風邪を引くことはないと考え、病気同士の有向枝は引かないことにします。

データからそれぞれの条件付き確率を求めますが、ここでは以下のように仮定します。

いよいよ診断がはじまります。「熱がある」「腹痛」という患者を想定し、この患者に対する各病気の「確信度」を計算します。

確信度(信念ともいう)という用語は、ある結果(ここでは症状)が先に与えられた時、推測される原因の組がどれぐらい尤もらしいものかを条件付き確率で表したものです。

英語ではbeliefという単語を使いますから、BEL(X)という記号で、「Xという原因が与えられた結果をもたらした確率」を表すことにしましょう。ある結果の組Yが与えられたとき、Xの確信度は以下の条件付き確率で定義されます。

「Xを前提として、Yが起こる確率」を求めればよいのですね。

実際に、条件付き確率を計算してみます。「風邪」と「盲腸」のうち、どれが患者の症状「熱がある」「腹痛」をもたらしているか調べたいのでした。簡単のため、二つの症状の併発は起こらないものとします。

このときは、 に対する確信度を計算します。

そして、確信度の大きい病気を原因として推定します。

「風邪を引いた患者が来院してこの症状を示す確率は1.8%」
「盲腸の患者が来院してこの症状を示す確率は1.0%」

これらの結論により、患者は風邪であると推定されました。

ノードと有向枝を充実させていくと、精度は飛躍的に向上する

以上で、単純な(あまりにも単純すぎる)ベイジアンネットワークを構築してみました。これだけでは、とんだヤブ医者と思われるかもしれませんね。「熱がある」「腹痛」の患者はすべて、風邪と診断するのですから…。

ただ、これは3つの症状と、2つの原因というモデルで考えたためであり、もっと多くの症状を判断材料とすることで、精度は向上していきます。簡単な改善として、盲腸に特有の症状をノードに採用すれば、誤診の可能性はかなり下がります。

以下の適用例を見れば、どれだけ信頼性の高いモデルに育つかが分かるかと思います。

心臓疾患の医療診断システム
貧血症の医療診断システム
Fuji xeroxによる、複合機の故障診断システム

さらには表題に挙げたように、広告出稿の際、ユーザーの嗜好を推定するベイジアンネットワーク広告に使われています。その仕組みをのぞいてみましょう。

ベイジアンネットワーク広告の仕組み

先の医療診断の例と照らしながら説明していきます。まず、「原因」と「結果」が何に当たるかを確認しましょう。

ベイジアンネットワーク
原因
結果
医療診断
病気
症状
ベイジアンネットワーク広告
ユーザーの嗜好
ユーザーの履歴

医療診断とベイジアンネットワーク広告は、いずれも「結果が先に与えられる」という特徴があり、「そこから原因が分かると嬉しい」ということが共通しています。

医療においては言わずもがなですが、広告技術においては、ユーザーの嗜好を絞り込むことで、クリックしてくれそうな広告を選択して動的に出稿することが可能になるからですね。

広告技術におけるベイジアンネットワークの構築方法も、先の3ステップと全く変わりません。ノードの集合(ユーザーの嗜好、履歴の切り分け)を決定し、「嗜好」と「履歴」の結びつきを有向枝で表現し、条件付き確率を推定する。

そして、サイトに訪れたユーザーのCookieなどから履歴を読み込み、どのような嗜好を持ったユーザーなのかを確信度をもとに算出します。

ベイジアンネットワークを実装するには

ベイジアンネットワークは「ベイズ統計」に含まれ、機械学習の主流の一つです。PythonとRでそれぞれ、ベイジアンネットワークの実装に向いたパッケージがありますから、触れてみるとよいでしょう。

Pythonでベイジアンネットワーク

Peblという学習用ライブラリが用意されています。

pebl-project

Rでベイジアンネットワーク

dealやbnlearnというライブラリが利用可能です。

deal
bnlearn

カテゴリー : デジタル・IT タグ :
CodeIQ MAGAZINEの記事一覧をみる ▶
  • 誤字を発見した方はこちらからご連絡ください。
  • ガジェット通信編集部への情報提供はこちらから
  • 記事内の筆者見解は明示のない限りガジェット通信を代表するものではありません。