2015年9月2日水曜日

機械学習を使った、twitterのクレーム検知、通報システム


機械学習とその分類アルゴリズムにニューラルネットワークを利用したディープラーニングを使い、米国の携帯会社4社を対象としたクレーム検知、担当者への自動通知システムを作成した。
米国携帯会社用として作成したが、いろいろな分野でも応用が効くだろう。
※IBM Bluemix Challenge 2015"Attention Informer"という名称で応募していたアプリケーションである。


◆ UI


designed by 西大輝



◆ アプリ概要
twitterでの苦情を検知し適切な担当へ通知することを目的とする。

アプリの動きは大きく2つ。
twitterタイムラインから
● 肯定的発言、否定的発言を抽出・・・
さらに、同音異義語があっても意図するものだけを選択・・・
● クレーム内容から連絡先を自動判別・・・


簡易的に図示するとこのようになる。
twitter → positive tweets
        → negative tweets → 各担当部署
                     


①から③の部分でIBMのBluemix上にあるwatsonサービス群を利用している。
(Insights for Twitter)
①異常の検知
Negative tweetとPositive tweetを分類させる。
異常な状態は、Negative tweetの比率が対象期間全ツイートの10%を超えた場合とした。

(Natural Language Classifier(NLC))
※アプリを動作させる前に当然学習させておく必要がある。
その手段は下段"◆ コード補足"を参照のこと。

②同音異義語の判別
例えば、sprintと検索した時、それが携帯会社に関連したツイートとは限らない。
Natural Language Classifierを用いて携帯会社のtweetを自動判別させる。
  o:I wanna an Apple iPhone sold in sprint.
  x:I need to work on my sprint finish.

③通知先の判別
本アプリでは、通知先として"基地局監視部署"と"サーバ監視部署"を想定して実装した。
  基地局:Can't call any Sprint customers right now for some reason.
  サーバ:Sprint server down? There is no valid DNS server so !?

通知手段としてtwilioを利用したがメールでもなんでもよいだろう。


◆ コード
https://github.com/alpha-netzilla/attention-informer

一部、NLCの操作面について補足しておく。
APIはすべてREST経由で操作できる。
利用する言語に依らないようにcurlでのコード例を記載しておく。
※本アプリの実コードはRuby on Railsのフレームワークを使っている

○ 学習データの用意
以下の形式のcsvセットを用意する必要がある。

文章, 分類したいインテント

ここでは、ある文章が、cellphoneについて語っているのか、そうではないのかをインテント付けしている。

I'll buy new cell phone?, cellphone
Sprint network improved!!, cellphone
Do show your sprint", others
He made a sprint for escape, others
〜snip〜

以下説明のため、ここでは上記をファイル名"file=train.csv"で保存したとする。

どの程度、どういった文章を学習させればよいのかについて公式マニュアルには明確な言及がなかった。
学習後に独自に性能評価をする必要があるだろう。


○ 学習
$ url="https://gateway.watsonplatform.net/natural-language-classifier/api"

$ curl -u  ${username}:${password} \
-F training_data=@${file} \
-F training_metadata="{\"language\":\"en\",\"name\":\"claim\"}" \
"${url}/v1/classifiers"
en部分をjaにすると、日本語にも対応する。

正常に登録できれば分類器のid(classifier_id)を確認できる。
$ curl -u ${username}:${password} ${url}/v1/classifiers| jq .


○ ステータス確認
学習が終わるまでに数分かかる。
ステータスの変化で進捗を判断できる。

$ curl -u ${username}:${password} ${url}/v1/classifiers | jq .
"status": "Training" ⇒ "Available"


○ 問合わせ(POST)
適当な文章を作り、その内容がどのようにカテゴライズされるかを確認する。
学習時の言語設定をenにしている想定である。jaにしていれば日本語での質問も対応する。
$ question="I want to buy an iPhone"

$ curl -X POST -u ${username}:${password}\
-H "Content-Type:application/json" \
-d "{\"text\":\"${question}\"}" \
"${url}/v1/classifiers/${classifier_id}/classify" | jq .
{
  ~snip~
  "classes": [
    {
      "class_name": "cellphone",
      "confidence": 0.9165256889739971
    },
    {
      "class_name": "other",
      "confidence": 0.08347431102600286
    }
  ]
}

cellphoneについて言及している確率が91%になっている。


○ 分類器の削除
$ curl -X DELETE -u ${username}:${password} "${url}/${classifier_id}"



◆ NLCの選択動機
少し脱線するが、watsonサービスのNLCを本アプリを実装する上で選択した理由を書いておく。今回の対象データは自然言語という非構造化データであり、機械学習の分類系の実装であるNLCであれば対応できると判断したためである。

機械学習の基礎を確認しておこう。

● 機械学習の流れ
(教師データあり)
1.
教師データ     →     特徴ベクトル     →     予測モデル
         特徴生成               学習
            

2.
未知データ     →     特徴ベクトル     →     予測
                   予測モデル
         特徴生成               予測



● 特徴ベクトルの生成手法
(特徴抽出)
・Word2Vec NLCが利用?
・TF-IDF
・CountVectorizer

(特徴変換)
・Tokenizer
・StopWordsRemover
・n-gram
・StringIndexer
・Binarizer、Bucketizer、QuantileDiscretizer
・PCA
・PolynomialExpansion
・OneHotEncoder
・Normalizer、StandardScaler、MinMaxScaler

(特徴選択)
・VectorSlicer
・RFormula
・ChiSSelector


● 機械学習で実現可能なことと代表的な手法
(教師データあり)
・回帰(過去の実績を元に未知の数値を予測)
      - 線形回帰
      - ベイズ線形回帰

・クラス分類(与えられたデータを適切なクラスへ割り当て) NLCが得意
      - ディープラーニング(ニューラルネットワーク) NLCの実装
      - 決定木
      - SVM
      - ロジスティック回帰
       ※過去のデータを元に、ある事象が起こる確率を求められるため、回帰と名がついている。予測できる確率に対して閾値を設け、それ以上か未満かでデータの分類ができるため、クラス分類の手法として用いられている。

・レコメンデーション(価値があると思われるコンテンツを個別提示)
      - 協調フィルタリング
   ※教師データあり、なしの中間と言ったところだろうか


(教師データなし) 
・クラスタリング(類似データのグルーピング)
      - k-means
      - コング正規分布モデル

・情報圧縮/次元削減(データの本質的特徴の作成)
      - 主成分分析
      - 特異値分解


(強化学習)
・報酬を最も多く得られるように機械が適切な行動を判断(一つ一つの判断(囲碁なら指し手)の良し悪しが、勝ち負けなどの結果として後になって得られる。それぞれの指し手の正しさを教わることはできない)
      - Q学習
      - DQN


● 機械学習の予測モデルの評価
(教師データあり)
・クラス分類
      - ROC曲線(2クラス分類時)  ※補足にて若干詳しく説明
      - クロス表(多クラス分類時)

・回帰
      - 平均絶対誤差(MAE: Mean Square Error)・・・小さいほど良好
      - 二乗平均平方根誤差(RMSE: Root Mean Square Error)・・・小さいほど良好

・レコメンデーション
      - NDCG(Normalized Discounted Cumulative Gain)・・・1.0に近いほど良好
      - 平均絶対誤差(MAE: Mean Square Error)・・・小さいほど良好
      - 二乗平均平方根誤差(RMSE: Root Mean Square Error)・・・小さいほど良好


(教師データなし)
      明確な回答がないため、満足度、売上、利益、になるだろうか。


-------------------

〜補足〜
2クラス(2項、2値)分類の評価時に必須となる基礎的な知識を下の図を元に覚書として記録しておく。





・精度(Precision)
Precision = A / (A+B)
○と推測したデータのうち、正解が○のデータである割合。
100%に近いほど良好。

・真陽性率(TPR: True Positive Rate) ※再現率(Recall)とも呼ばれる
TPR = A / (A + C)
正解が○のデータのうち、正しく○と推測した割合。
100%に近いほど良好。

・正解率(Accuracy)
Accuracy = (A+D) / (A + B + C + D)
全データのうち正解○のデータを正しく○、正解×のデータを正しく×と推測した割合。
100%に近いほど良好。

・偽陽性率(FPR: False Positive Rate)
FPR = B / (B + D)
正解が×のデータのうち、誤って○と推測した割合。
0%に近いほど良好。

・ROC(Receiver Operating Characteristic)曲線
横軸に偽陽性率(FPR)、縦軸に真陽性率(TPR)をとり閾値を変化させた場合の曲線である。真陽性率(TPR)と偽陽性率(FPR)は一方が良くなれば他方が悪くなるトレードオフの関係にあった。

閾値が1.0なら、どのようなデータも×と判定するため(AとBがゼロ)、真陽性率も偽陽性率も共に0%となる。
閾値が0.0なら、どのようなデータも○と判定するため(CとDがゼロ)、真陽性率も偽陽性率も共に100%となる

閾値を1.0から0.0へ変化させていく際に、偽陽性率をあまり悪化させず(横軸が小さい時に)、信用性率が向上する(縦軸が大きくなる)左上に張り付くようなグラフほど、良好であると判断できる。定量化した指標としてAUC(Area Under the Curve)がある。

・F値(F Score)
トレードオフの関係にある指標を統合的に見る指標。
1.0に近いほど良好。


(練習問題)
イヌの画像が50枚、イヌ以外の画像が50枚の計100枚の画像がある。

1. 精度
分類機は60枚をイヌと認識し、48枚が正解であった。
48 / 60 * 100 = 80%

2. 真陽性率(再現率)
50枚のイヌの画像のうち分類機が48枚をイヌの画像と正しく認識した。
48 / 50 * 100 = 96%

3. 正解率
100枚のうち、86枚を正確に認識(イヌをイヌと、イヌ以外をイヌ以外)した。
86 / 100 * 100 = 86%