機械学習 はじめよう

第3回 ベイジアンフィルタを実装してみよう

この記事を読むのに必要な時間:およそ 6.5 分

今回は,前回の最後で説明したナイーブベイズの応用である「ベイジアンフィルタ」をPythonで実装しながら,実際に確率の計算がどのように行われるかをみていきましょう。

ベイジアンフィルタとは

ベイジアンフィルタとは,ナイーブベイズ(Naive Bayes)というアルゴリズムを利用して,テキストの自動分類などに応用することのできるフィルタの総称です。

このベイジアンフィルタは,現在では様々なところで応用されているのをご存知ですか? 有名なところではメールのスパム判定やブログのカテゴリ分類に利用されています。

例えばベイジアンフィルタによるスパム判定では,事前に手動でメールをスパムとハムというカテゴリに分類しておきます。これにより,メールの傾向を学習し出現する単語から自動的に新しく届いたメールが「スパムメールか否か」と分類できるようになります。つまり,スパムメールに含まれている文字集合と通常のメールに含まれる文字集合の確率を計算し,スパムメールか否かを判断しているのです。

ベイジアンフィルタがメールのスパム判定として利用される契機となったのは『ハッカーと画家』オーム社の執筆でも有名なPaul Graham氏が2002年に発表したA Plan for Spam(スパムへの対策)という論文です。この論文によって,スパム判定に統計的なアプローチが用いられることが注目されるようになりました。

先述のようにベイジアンフィルタは,事前に与えられたパターン(情報)にしたがって未知の文章を分類します。事前に正しいデータを与え学習を行うので,「教師あり学習(Supervised Leaning)」と呼ばれる機械学習の手法の一つになります。

「教師あり学習」があるということは「教師なし学習」もありそうですよね? 今後の連載の中で「教師なし学習」も紹介する機会があると思いますので楽しみにしていてください。

環境構築

本連載では基本的にプログラミング言語にPythonを使って実装していきます。バージョンは2.6.1を利用します。

Pythonでは大規模な多次元配列や行列をサポートしている拡張モジュールNumpyの提供する高水準の数学関数ライブラリ,それを基礎として統計や最適化,線形代数などのモジュールを提供する科学技術計算のためのライブラリSciPyなどの数値解析モジュールが充実しているため,数値計算をとても簡単に行えます。

また,グラフモジュールとしてMatplotlibなども存在しているため,可視化も簡単に行うことができます。

bag-of-wordsを利用したテキスト分類

それでは早速,ベイジアンフィルタの実装を始めていきましょう。ベイジアンフィルタを実現するのは,何度も言及しているナイーブベイズというアルゴリズムです。

ナイーブベイズは簡単な計算でよい結果のでる「いいモデル」と前回紹介されていますが,実装も計算と同じようにそう難しくありません。

今回は,ベイジアンフィルタを利用して文章をそれぞれのカテゴリに分類してみたいと思います。ベイジアンフィルタを文章と文章が属するカテゴリで訓練して,受け取った文章がどのカテゴリに分類されるかを見ていきます。

一般的に文章を分類するためには何が必要になるでしょうか。それは文章に含まれている特徴になります。 今回は文章の中に出現する単語を出現する順番を意識せずに特徴として扱います。このように文脈に依存しない,単語が文章内のどこに登場するか考慮しないようなテキスト表現をbag-of-wordsと呼びます。バッグの中にごちゃごちゃと単語が入っているようなイメージです。

例えば,以下の文章を考えてみます。

これらは「機械学習」という技術を使って実現されているのです。

この文章ををbag-of-wordsで表現すると,以下のような単語の集合になります。

「これら」,「機械」,「学習」,「技術」,「実現」

文章を形態素に分割する

今回は日本語を含む文章から単語の集合を作るにあたって「形態素解析」を用いることにします。

英文の場合は単語がスペースによって分割されているため,スペースで区切られた文字列を抽出することで単語を取得できます。しかし,日本語にはそのような「わかち書き」の習慣がありません。そこで,形態素解析を用いて文脈の解析や単語の分解を行う必要があります。

形態素解析ライブラリとしてはMeCabChaSenなどが有名ですが,今回はYahoo!デベロッパーズネットワークの日本語形態素解析を利用してみます。利用するにあたって,Yahoo!デベロッパーネットワークのアプリケーションIDを取得する必要があります。Yahoo!のIDさえ持っていれば,こちらから登録するだけで利用できます。

また,今回はXMLの解析にBeautifulSoupというライブラリを利用しています。BeautifulSoupでは特定のタグの抽出やソートを簡単に行え,多少の文法の誤りを修正してくれるなど比較的柔軟に使うことができます。BeautifulSoupはここからダウンロードすることができます。本稿ではBeautifulSoup-3.0.8を使います。

リスト1 形態素解析を使って,わかち書きをする(morphological.py)

# -*- coding: utf-8 -*-
import urllib
import urllib2
from BeautifulSoup import BeautifulSoup

appid = 'Yahoo!デベロッパーズネットワークのアプリケーションIDを入力して下さい'
pageurl = "http://jlp.yahooapis.jp/MAService/V1/parse";

# Yahoo!形態素解析の結果をリストで返します。
def split(sentence, appid=appid, results="ma", filter="1|2|3|4|5|9|10"):
  sentence = sentence.encode("utf-8")
  params = urllib.urlencode({'appid':appid, 'results':results, 'filter':filter,'sentence':sentence})
  results = urllib2.urlopen(pageurl, params)
  soup = BeautifulSoup(results.read())
  
  return [w.surface.string for w in soup.ma_result.word_list]

リスト1のコードをmorphological.pyという名前で保存します。保存時の文字コードにはutf-8を指定してください。このコードではYahoo!JAPANの日本語形態素解析サービスに入力された文章を渡しています。そして,XMLで返される結果をBeautifulSoupでパースしています。

引数のfilterで解析する品詞の種類を指定することができます。filterに指定可能な品詞番号は以下のようになっています表1)。

表1 filterに指定可能な品詞番号

1形容詞
2形容動詞
3感動詞
4副詞
5連体詞
6接続詞
7接頭辞
8接尾辞
9名詞
10動詞
11助詞
12助動詞
13特殊(句読点,カッコ,記号など)

さらに詳細な利用方法が知りたい方は,Yahoo!デベロッパーズネットワークのマニュアルを参照してください。

著者プロフィール

恩田伊織(おんだいおり)

1979年生まれの埼玉県出身。数学と関数型言語,SFとボードゲーム好きなプログラマー。好きな言語はRubyとLISP。現在は航空管制の基盤開発に従事している。

Twitter:http://twitter.com/Iori_o

コメント

  • Re:第3回の実行結果についての質問

    私も同じ結果になりました。

    原因が分かったわけではないですが、一番初めのワード
    「ヴァンロッサム氏によって開発されました」を
    「グイド・ヴァンロッサム氏によって開発されました」に
    変えて実行すると推定カテゴリは「Python」になります。

    記事の掲載時点以降にYahoo!の日本語形態素解析の仕様が変わったのかもしれませんね。
    なかぐろ前後の語は一体として解釈するようにしたとか。

    ちなみにいくつか試してみました。
    「ヴァンロッサム氏によって開発されました」
    →Ruby
    「グイド・ヴァンロッサム氏によって開発されました」
    →Python
    「グイドヴァンロッサム氏によって開発されました」
    →Python
    「グイデ・ヴァンロッサム氏によって開発されました」
    →Ruby
    やっぱりなかぐろが怪しいですね。

    「ヴァンロッサム氏によって開発されました」
    →Ruby
    「ヴァンロッサム氏によって作られました」
    →Python
    「ヴァンロッサム氏によって製作されました」
    →Python
    「ヴァンロッサム氏によって発明されました」
    →Python
    どうも「開発」が「Ruby」に結びついた要因のようです。

    Commented : #3  taz (2015/02/19, 18:06)

  • 第3回の実行結果についての質問

    MacBook Pro OX S V10.9 Mavericksのターミナルで、
    サンプルプログラムをダウンロードしてきたファイルと、
    BeautifulSoup-3.0.8(または3.2.1)のpyファイルを置いて上記を実行させると、一番初めのワード「ヴァンロッサム氏によって開発されました。」の推定カテゴリが「Python」ではなくて「Ruby」になってしまいます。

    リスト9の実行結果は本当に正しいのでしょうか?私の方で何か設定方法に問題があるようでしたら直してやってみますので情報いただけないでしょうか?

    よろしくお願いいたします。

    Commented : #2  三好 徹男 (2014/05/21, 23:46)

  • typo

    リスト7中
    if prob < max:
    の部分の不等号が逆向きになっていました.
    サンプルプログラム一式は正しいようです

    Commented : #1  peccu (2011/07/25, 18:14)

コメントの記入