テキストマイニングの流れとその準備

# テキストマイニングの概要

テキストマイニングとはテキストデータを計算機で定量的に解析、有用な情報を取り出すための技術の総称です。主に、自然言語処理、統計、データマイニングといったものを基礎とします。

かつてはこれらの実証分析や論理的研究には、自然言語を計算機で扱うために高価なソフトウェアが必要であり、高い敷居がありました。今日では無料で本格的なテキストマイニングをするための環境が整ってきており、また計算機も高速で安価になったことから、例えば人文社会科学分野などでの応用においても大きな注目と期待が集まっています。

今回はテキストマイニングで雑多な外部のデータを集積し、データセットを作成して、分析手法の選択と適用、可視化までの大雑把なプロセスを整理します。

## ツールの準備

テキストマイニングのためのフリーなソフトウェアとしては主に次のようなものがあります。

|名称|説明|
|:--|:--|
|[TTM](http://mtmr.jp/ttm/)|テキストマイニングの前処理用ソフトウェア。タグ付きのテキストを CSV 形式で読み込んで集計データを出力する。|
|[MeCab](https://code.google.com/p/mecab/)|辞書を選択・カスタマイズ可能な日本語形態素解析器|
|[CaboCha](https://code.google.com/p/cabocha/)|SVM による日本語係り受け解析器|
|[Ruby](http://ruby-lang.org/)|柔軟で強力なプログラミング言語|
|[Python](http://python.org/)|科学計算分野のライブラリが豊富なプログラミング言語|
|[LibreOffice](https://ja.libreoffice.org/)|フリーな表計算ソフトウェアなどオフィススイート|

これらは必要に応じてひとつ、あるいはいくつか組み合わせて利用すれば良いでしょう。

## データセットの準備

分析すると言ってもテキストデータが無ければ話になりません。そこでテキストデータを[収集](http://qiita.com/ynakayama/items/c07c92031802b8d4c3e2)したり[分類](http://qiita.com/ynakayama/items/de19da95cb56763d757d)したりする必要があるわけです。

それではさっそくテキストデータの中から問題領域の語群が含まれるものを抽出してみましょう。

### 文字列の検索と抽出をする

次のメソッドは検索文字列を search_words に格納、与えられた文字列に該当の文字が存在するかを評価します。

search_words には
1 => [検索文字列の配列]
2 => [検索文字列の配列]
...
という風に、語彙群の配列とそれが属するクラスの番号の組み合わせからなる連想配列を用意します。

```rb
def pattern_match(string)
  matched = []
  @search_words.each do |search_word, arr|
    arr.each do |a|
      regexp = Regexp.new(a)
      if regexp =~ string
        # ヒットした検索文字列のクラスを格納
        matched << @search_words[search_word]
      end
    end
  end
  matched # 適合したクラス群を返却
end
```

### 日本語、あるいは英単語を形態素解析する

MeCab には Ruby/Python などのバインドが付属していますので Ruby から呼び出して使うことができます。

```rb
@mecab = MeCab::Tagger.new("-Ochasen")

def pickup_words(string)
  node = @mecab.parseToNode(string)
  words = []
  while node
    word = node.surface.force_encoding("utf-8")
    # 品詞の種類を判定する場合
    # if /^名詞/ =~ node.feature.force_encoding("utf-8").split(/,/)[0] then
    if word =~ /[一-龠]/ # 漢字
      words.push(word)
    elsif word =~ /[あ-ン]/ # ひらがな
      words.push(word)
    elsif word =~ /^[A-Za-z].*/ # 英字
      words.push(word)
    elsif word =~ /^[Ａ-Ｚａ-ｚ].*/ # 全角英字
      words.push(word)
    end
    node = node.next
  end
  words # 形態素群が返る
end
```

といったように Ruby のような柔軟な言語を利用して大量のテキストデータから目的の文書や語群を抽出します。

たとえば、以下のように SI 業界の大手である会社のニュースをピックアップして

```text
NTTデータが4000コアのクラスターでSparkを試行、NTTドコモからの要望受け
http://itpro.nikkeibp.co.jp/article/COLUMN/20140711/570863/
```

↓ このように形態素解析できます。
```json
{
  "title"=>"News ＆ Trend - NTTデータが4000コアのクラスターでSparkを試行、NTTドコモからの要望受け：ITpro",
  "link"=>"http://itpro.nikkeibp.co.jp/article/COLUMN/20140711/570863/",
  "matched"=>[["NTTデータ", "ＮＴＴデータ"]],
  "words"=>["News", "Trend", "NTT", "データ", "が", "コア", "の", "クラ", "スター", "で", "Spark", "を", "試行", "NTT", "ドコモ", "から", "の", "要望", "受け", "ITpro"],
  "key"=>"2014-07-13T19:30:33Z"
}
```

## どうやってたくさんのデータを用意するか

すでに[収集](http://qiita.com/ynakayama/items/c07c92031802b8d4c3e2)や[分類](http://qiita.com/ynakayama/items/de19da95cb56763d757d)については述べましたが、インターネットの情報は流れが速く、また過去に遡って体系的なデータを収集するためにはあらかじめデータを日々自動収集するといったことをしていないと、手元に残らないためなかなか難しいものがあります。

* こういったニーズを見越して、あらかじめ日々データを集めておく
* データセットをお金を出して買う

といった方法が考えられます。それ以外にデータを集めるには何か手段を講じないといけません。

ただ単にこれこれこういったデータが必要だと言っても、そもそもそれを入手する手段が確立されていなければ、分析作業は行き詰まってしまうでしょう。

なにはともあれ、分析の目的に見合ったデータセットをいかに用意するか、どうやって入手するかが大きなテーマとなるでしょう。

## どのようなアプローチをしていくか

手に入れたデータを形態素解析するところまではやりましたが、その後どのようにアプローチしていけば良いのでしょう。

### 大まかな流れ

大まかな流れは次のようになります。

1. 形態素解析などで語群を得る
2. データをクリーニングする (外れ値、欠損値、ノイズを取り除く、など)
3. データを要約する (次元縮約、属性を選択する、など)
4. データマイニングする (統計的手法を使う、他のデータと組み合わせるなどして、価値を見出す)
5. 評価と検証 (1 ～ 4 の結果を検証、有用な知識を得る)

これらの繰り返しになります。

### 解析の手段

データマイニングにおける、よくある解析手法は次のようなものです。

・主成分分析

定義としては、観測変数をより少ない変数で説明する合成変数を得ることです。
得られた主成分得点を散布図にプロットするなどして、対象を大まかに説明します。

・対応分析

行と列を平面に配置して、どの属性がどういった項目に対応しているかといったことを視覚化します。

・多次元尺度構成法

関連が近いと思われる項目を近い距離に配置して、単なる集計表からは読み取れないデータの関連性や傾向を明らかにします。

また、複数の変数を組み合わせるといったこともおこなわれます。

## まとめ

今回はテキストマイニングの概要とツールの準備、形態素解析、またデータの準備とアプローチの方法について触れました。