Word2Vecを用いて蒙古タンメン中本の口コミ評価を予測してみる

はじめに

word2vecを用いた分類は以前からやってみたいと思っていたのですが、関心を持てるテキストデータがなかったのでなかなか手を出していませんでした。
ある時、ふとしたことから某グルメ系口コミサイトから蒙古タンメン中本の口コミと評価点を抽出して、その評価をword2vecでやってみるのは面白いだろうと思いついたので、さっそくやってみます。
こういう時にはじめて、データ分析だけでなくクローリング屋としても業務をやっていて良かったなと思うところですね。
コードは以前見つけて紹介した「分散表現を特徴量として文書分類するための方法について調べてみた」のものを再利用します。

目次

・目的
・データ収集
・形態素解析
・集計
・分散表現とは
・word2vecについて
・gensimのword2vecの引数
・word2vecによる文書分類の適用
・終わりに
・参考情報

目的

某グルメ系口コミサイトの口コミを収集し、個々人の口コミの内容から個々人の店に対する評価が高いか低いかを予測する。

データ収集

BeautifulSoupで収集しており、各店舗あわせて数千件ほど集めました。(実行コードはこちらでは紹介しません。)

このようなデータが手に入っている前提で以下の分析を進めていきます。

形態素解析

文書を形態素解析して、名詞のみを抽出するためのコードを用意します。

先ほどのデータフレームに対して以下のように実行すれば、名詞のみの分かち書きを行ったカラムが手に入ります。

集計

点数のヒストグラム

3.5点から4点の間が最も評価が多いようです。1点台をつける人はほとんどいないことがわかります。

単語数のヒストグラム

大体の口コミで100単語未満のようです。

単語数と点数の散布図

どうやら口コミにおいて500語を超える記述をしている人は評価が3点を下回ることはないようですが、文字数と点数でキレイに傾向が出ているわけではないですね。

形態素解析結果の集計、単語ランキング

名詞の抽出に関して非常に便利なMeCab Neologdを用いています。蒙古タンメンもきちんと捉えることができています。

味噌よりも北極の方が出現しているようです。北極は言わずもがな、極端に辛い罰ゲームレベルの一品。味噌タンメンは辛さが抑えめのラーメンで、知人の間では最もおいしいのがこのレベルだという合意があったりしますね。

分散表現とは

  • 単語の意味を低次元の密な実数値ベクトルで表現したもの。
  • 入力層から中間層への重み自体が各単語の分散表現となっている。
  • 2017年9月のテキストアナリティクスシンポジウムにてメルカリとGunosyが特徴量として分散表現を活用しており性能が出ているとの発言があった。

word2vecについて

単語の分散表現を作ることを目的としている。

  • CBOW(Continuous Bag-of-Words)
    注目している単語の前後N単語を文脈と呼び、その文脈をBag-of-Words表現として入力し、注目している単語を出力するというニューラルネットワークを学習する。入力層から隠れ層への結合は単語の位置を問わず同じとし、隠れ層の活性化関数をただの恒等関数としている。
  • Skip-gram
    文脈のBOWを突っ込むCBOWとは異なり、入力層に1単語だけを入れる。1単語を入力し、正解データとして他の単語を入れることを繰り返して学習し、ある単語の入力に対して、どの単語の出現確率が高いかどうかを計算する。正解確率が上がるようにニューラルネットワークの重みを調整する。深層学習で使われる自己符号化器と似たような構造とされている。

gensimのword2vecの引数

gensimのword2vecには数多くの引数が存在します。gensimのドキュメントに英語で書かれていますが、せっかくなのでこちらで紹介します。

  • sentences
    解析に使う1行1センテンスで書かれた文書。日本語の場合はLineSentenceフォーマットを使えばうまくいった。単語が空白文字で区切られていて、文章は改行で区切られていれば問題ない。
  • sg
    {1,0}の整数で訓練アルゴリズムを設定できる。 1を選べばskip-gramで、0ならばCBOWを使う。
  • size
    特徴ベクトルの次元を設定する。
  • window
    文書内における現在の単語と予測した単語の間の距離の最大値を設定する。言い換えると、文脈の最大単語数を設定する。
  • alpha
    学習率の初期値を設定する。
  • min_alpha
    訓練の過程で徐々に落ちていく学習率の最小値を設定する。
  • seed
    乱数を生成する際のシード番号を設定する。
  • min_count
    一定の頻度以下の単語を除外する際の値を設定する。
  • max_vocab_size
    語彙ベクトルを構築している際のメモリ制限を設定する。
  • sample
    (0, 1e-5)の範囲で、頻度語がランダムに削除される閾値を設定する。高速化と精度向上を狙っており、自然言語処理においても高頻度語はストップワードとして除去するなどの対応が取られている。
  • workers
    モデルを訓練するために多くのワーカースレッドを利用するかどうか設定する。(並列化関連)
  • hs
    {1,0}の整数で、1であれば階層的ソフトマックスがモデルの訓練で用いられ、0であり引数negativeがnon-zeroであればネガティヴサンプリングが設定できる。全部計算することが大変なので、階層的なグループに分けて各グループごとに学習するというのがモチベーション。
  • negative
    0よりも大きければネガティブサンプリングが用いられる。5〜20などを選び、どれだけノイズワードが描かれているかを識別する。0であればネガティブサンプリングが適用されない。ネガティブサンプリングは計算高速化を目的に出力層で正解ニューロン以外のニューロンを更新しないように学習する手法。
  • cbow_mean
    {1,0}の整数で、0であれば単語ベクトルの合計を用い、1であればCBOWが用いられた際の平均が用いられる。
  • hashfxn
    訓練の再現性のためにランダムに初期値のウエイト付けできる。
  • iter
    コーパスにおける繰り返し回数(エポック数)を設定できる。
  • trim_rule
    ある単語を語彙に含めるべきかどうかを識別する、語彙のトリミングルールを設定する。
  • sorted_vocab
    {1,0}の整数で、1であれば頻度の降順で語彙を並べ替える。
  • batch_words
    ワーカースレッドにわたすバッチの大きさを指定する。(並列化関連)
  • compute_loss
    Trueであれば損失関数の計算と蓄積を行う。
  • callbacks
    訓練時の特定の段階で実行する際に必要なコールバックのリストを指定できる。

word2vecによる文書分類の適用

口コミの点数が4点以上であれば1、そうでなければ0を取る変数を作成し、それをラベルとして文書分類を行います。
以前、紹介したブログ同様に、scikit-learnのExtraTreesClassifierを用いてCountVectorizerとTfidfVectorizerを特徴量としたものをベースラインとして、同様の手法に対してword2vecで作成した分散表現を特徴量として用いたものとを比較します。評価指標はクロスバリデーションスコア(5-folds)とします。

分類の前に、せっかくword2vecを使ったので、任意の単語に類似した単語を見てみます。

まずは初心者向けの味噌ラーメン

続いて、中級者向けの蒙古タンメン

そして、上級者向けの北極ラーメン

最後に、誰もが経験する翌日という単語。

どれも関連性の高いと思われる単語が抽出できているように思われます。

それでは分類モデルの学習を以下のコードで行います。
scikit-learnを使えば、データさえあれば非常に短いコードで書けてしまいます。

一応、ベースラインよりもword2vecを特徴量としたものの方がスコアが高いのですが、わずかです。TF-IDFベースで特徴量を作成したモデルは十分に性能が出ているようです。
word2vecを用いることによる旨味はそれほどなさそうですが、パラメータを試行錯誤していけばよくなるかもしれません。

終わりに

蒙古タンメン中本のテキストをWebスクレイピングし、その口コミ情報をコーパスとして口コミ評価の二値分類に挑戦しましたが、TF-IDFよりもわずかに優秀な特徴量になりうるという結果になりました。もっと劇的な向上を夢見ていたのですが、パラメータの試行錯誤を今後の宿題としようと思います。

参考情報

Chainer v2による実践深層学習
word2vecによる自然言語処理
models.word2vec – Deep learning with word2vec
Python で「老人と海」を word2vec する
Python3 – MeCabで日本語文字列の名詞出現数の出し方について
Transform a Counter object into a Pandas DataFrame

「NOSQLの基礎知識」を読んで基礎知識を養う

同じ職場のエンジニアに『NOSQLの基礎知識』はいいぞ〜と勧められて読もうとしているのですが、マーケターレベルだと、2章と4章を読めば良いとのことです。それ以外は実際に手を動かす人が必要な知識らしい。なので、今回は1、2、4章に書かれている内容を簡単にまとめてみようと思います。

NOSQLとは(1章)

  • Not Only SQLの略で、SQLではないと言う意味。
  • RDBは単体のハードウェア上で利用するには最適だが、複数台並べてデータを分散して管理するのが不得意だがNOSQLはそれが得意。
  • SQLは膨大かつ多種多様で激しく変化するデータの塊を制限なしに保存することが難しいが、NOSQLはそれを可能にする。

NOSQLの特徴(2章)

  • 機能がRDBほど豊富ではない
    Joinなどの演算子もサポートされていない。(今はMongoDBではlookupとかいう機能が付いている模様)
  • データの整合性がゆるい
  • 結果整合性で良いという考え
    一時的なデータの不整合は問題としない。
  • NOSQLは正規化、更新書き込み量の最小化、メモリキャッシュの利用などの専門性が不要。
  • SQLとNOSQLは補完関係にある。
    SQLは豊富な機能とデータの整合性に強いが、ビッグデータに弱い。NOSQLはその逆。

NOSQLの種類(2章)

  • 世界に100種類以上存在
    ビッグデータに関連するカテゴリは以下の4つ
    ・キーバリュー
    ・カラム指向
    ・ドキュメント指向
    ・グラフ型

  • 一般的なRDBなどのSQL
    将来どのようなデータが発生するか想定の範囲内で設計が行われる。

  • キーバリュー
    ・キーとバリューの対が行として格納される。(データモデルがシンプル)
    ・キーを指定すればバリューを探し出せるのでサーバが何台増えても対応でき、スケールアウトに適している。
    ・複数のサーバに複数のバリューを複製した場合、複数のバージョンが存在する可能性がある。
    ・具体的なNOSQL:Dynamo,Voldemort,Riak,Hibari,Redis,Scalaris,Tokyo Cabinet/Tyrant

  • カラム指向
    ・キーの付された行が複数のカラムを持つことを許容している。
    ・あるカラムにおいて全てにデータが格納されていなくても良い。
    ・カラム数を後から増やしても良い。
    ・具体的なNOSQL:Bigtable,Cassandra,HBase,Hypertable

  • ドキュメント指向
    ・JSONやXMLといったデータ記述形式で記述されている。
    ・各ドキュメントは階層構造を持たず、相互の関係が横並びに管理されている。
    ・具体的なNOSQL:CouchDB,MongoDB

  • グラフ型
    ・データとデータ間のつながりを管理できる。
    ・個々のデータの属性に依存することなく、相互のつながり方だけを独立した形で保存できる。
    ・ノード(頂点)、リレーションシップ(関係の有無、関係の方向)、プロパティ(属性)の3つの要素から構成。
    ・属性は、期間や有効/無効のデータなどを持たせることができる。
    ・データ間の関係性を示すグラフを作成するという目的のために開発され、最適化されている。
    ・具体的なNOSQL:InfiniteGraph,Neo4j

HadoopはNOSQLではない(4章)

  • Hadoopは複数のソフトウェアを包含するフレームワーク
  • HDFSは大量のデータを複数のサーバに分散して格納する点でNOSQLのように見えるが、MapReduceによるバッチ処理前提となっており、リアルタイムでの応答の速さを求められる対話型のNOSQLとは分けて捉える必要がある。

MapReduce処理(4章)

  • MapReduceは大規模なデータを複数のノードで並列分散処理するためのプログラミングパターン
  • データ処理をMapタスク(膨大な元データを分解し必要な情報を抽出し有用な形に変換して出力)とReduceタスク(抽出された情報を集約し一塊のデータとして出力)の2段階のフェーズで分けて行う。
  • 多くのNOSQLにもMapReduceは実装されている。

さいごに

これまでR、Python、SQLしか心得ていなかった自分の知識の狭さを、エンジニアと一緒に働くことで実感しました。一冊読むくらいでエンジニアの話に少しはついていけると思うと読書の幅は広げておきたいですね。今後、データを活用したマーケティング支援ツールの開発を先導する際に、技術選定などの意思決定に役立つかもしれません。データアナリストという職種である者からすると、マーケティング・エンジニアリング・データサイエンスを緩急つけて学んでくというスタンスが重要なのかもと思う今日この頃です。

参考文献

NOSQLの基礎知識 (ビッグデータを活かすデータベース技術)