ジョブレコメンデーションについてのリサーチまとめ

9月のイベントでジョブレコメンデーションについて調べて発表(実務と論文で学ぶ ジョブレコメンデーション最前線2022)しましたが、ブログの方が情報量が多いのと、最近のSlideShareが非常にみづらいものになっているのに加え、アップデートもしやすいのでこちらに随時残せる記事を残しておこうと思います。今日はクリスマスなので、誰かにとってはクリスマスプレゼントとなりうるでしょうか。

業界にいるものとしての思い

私は大学時代に経済学部に通っていたときに、労働市場の流動性に関して興味を持っていました。
スキルさえあればすぐに労働者が転職をするという競争的な労働市場について思い巡らすことがありました。

しかしながら、就職活動を通じて、取ってつけたような志望動機で大して勉強をしてこなかったであろう人々と同列に扱われ、「労働市場の効率性に関して、現実は不確実な情報のなかでエイヤで決めるしかないのかな」という印象を感じました。

就職活動では求人メディア系の会社に入社しました。スキルある人が高い給与を享受しやすい仕組み作りをデータ分析の力で実現できたらいいなと思って入りました。

ジョブマッチング界隈の課題

この業界の課題については推薦システム実践入門 ―仕事で使える導入ガイドの8章5節のドメインに応じた特徴と課題で、仕事の推薦について書かれているのも参考になりますので、そちらも合わせてお読みください。

  • 双方の情報の充実化
    • 情報の非対称性を払拭できるだけの情報がない中で企業も候補者も面接に臨んでいる
  • 求人票の充実化
    • 何かしらのエージェントを使う際に自分が本当に行きたい、行くべき職場がないかもしれない
  • 求人票の質の向上
    • 候補者が企業に直接応募するにしても、求人票に記されたレベル感が曖昧なため

ジョブマッチング界隈のデータの課題

  • スキルや職歴の構造化データ化
    • 正確なスキル情報の記載
    • 所属した企業に関しても法人番号などを付与できるといい
  • 求人情報の記載項目の誤り是正、更新性アップ
    • 今は求めていない要件があるとか、扱う技術に変化があったとかを反映
  • 希望する仕事内容や職場の要望のデータ化
    • 希望する仕事について構造化データになっていない

ジョブマッチング系の論文色々

・Job Recommender Systems: A Review(2021)
・Domain Adaptation for Resume Classification Using Convolutional Neural Networks(2017)
・Implicit Skills Extraction Using Document Embedding and Its Use in Job Recommendation(2020)
・Machine Learned Resume-Job Matching Solution(2016)
・SKILL: A System for Skill Identification and Normalization(2015)
・Effectiveness of job title based embeddings on résumé to job ad recommendation(2021)
・conSultantBERT: Fine-tuned Siamese Sentence-BERT for Matching Jobs and Job Seekers(2021)

Job Recommender Systems: A Review(2021)

  • 論文の概要
    • Job Recommender System(JRS)研究のサーベイ論文(2011〜2021)[計133本]
    • 近年は求人などの大量のテキストを用いたジョブレコメンデーションが多い。深層学習も使われている。BERTもCNNも使われている。ハイブリッドモデルが多い傾向。
    • 近年ではアルゴリズムの公平性(年齢/性別での差別)に関心が持たれており、特徴量として差別的なものがなくても学習してしまう可能性が指摘されている。
    • 求職者とリクルーターのインタラクティブなデータ(click/skip)の利活用が重要となっている。研究者はRecsysなどのコンペのデータに依存しており、企業がデータセットの提供をするのが限定的であるのが問題としてある。JRSの発展のためにはKaggleやRecsysのコンペが重要とされている。
  • 参考になるところ
    • 求職者と採用担当者のインタラクティブなデータはこのコミュニティでデータとして貴重であること
    • 最近はTransformer系のアプローチが使われ始めていること

Domain Adaptation for Resume Classification Using Convolutional Neural Networks(2017)

  • 論文の概要
    • 27の職種のラベルが付与された求人票のデータ(テキスト:短文)をもとにCNNで分類器を作成
    • ラベルがない職務経歴データに関しては求人票で学習したモデルで推論
    • fastTextでの分類よりも性能が向上した

    • 求人票の数 > 越えれない壁 > 職務経歴データの数
    • CNNで学習する際の特徴量は学習済みのWord2Vecによる単語の分散表現で、同じ長さのものを使っている。
    • 最大値プーリングでの重要な特徴抽出、ドロップアウトの正則化など画像分類タスクと同様になされ、soft-max関数でマルチクラスの確率を出力している。
    • 苦手な職種でのファインチューニングがfuture work
  • 参考になるところ
    • 職務経歴書と違って収集が容易な求人票のデータをもとに学習し、職務経歴に関するラベルを推論をするスタイル
    • テキストデータに対してCNNを使っている

Implicit Skills Extraction Using Document Embedding and Its Use in Job Recommendation(2020)

  • 論文の概要
    • 職務経歴書や求人からNLPでスキル表現を抽出
    • 暗黙的なスキル表現も抽出
    • 候補者と求人のマッチングのスコア(Affinity Score)を定義
    • 暗黙的スキル情報を使うとマッチングの性能がアップすることがわかった
    • テキストに対して3つの観点でスキル抽出
      ・NER(Named Entity Recognition(固有表現抽出))を適用→文書内のスキルの位置を見つける、カテゴライズを行う
      ・PoS(Part of Speech(品詞の付与))を適用→スキル表現かどうかは専門家によるアノテーションを実施
      ・色々集めた辞書にあるか計算→Wikipedia、Onet/Hopeというサイトなどで自動での拡張型スキル辞書用意
    • 暗黙的なスキル表現も抽出
      暗黙スキル(Web DevelopmentやHard Workingなどの表現)の考慮→分散表現の平均値で表現
    • スキルとの関連度スコアの定義
      職務経歴書や求人からのスキル抽出のためにスコアを用いる
    • 表現の除外
      関連度スコアに閾値を設けて下回ったらその表現を除外するなどを行う。
    • 関連度スコア(x)
      ・NERで抽出した表現の信頼度(S1)
      ・文法が、事前に定義したルールにどれだけ合っているか(S2)
      ・そのスキルがNERで得たスキルっぽいもの、ポテンシャルスキル、辞書スキルの3つの辞書にどれだけ合致したかの割合(S3)
      ・その単語とスキル辞書との分散表現における最大のcos類似度の値(S4)
      ・パラメータは経験則的に決める
      ・関連スコアは0~1の間をとる
    • アフィニティスコア
      ・候補者と求人のマッチの適切さの指標
      ・エッジウェイトの平均としている
    • エッジウェイト(Y)
      ・スキル間のcos類似度(E1)
      ・文書を通じたスキルの出現頻度の割合(E2)
      ・明示的なスキルがあるかどうか(E3)→暗黙だと減点
      ・ウェイト(ω)はそのマッチングが成功したかどうかで重み付ける。
      ・関連スコアは0~1の間をとる
  • 参考になるところ
    • 暗黙的なスキルに関して着目したところ
    • スコアリングのモデルを定め、手元にあるデータとWikipediaなどの集合知も使ってかなり慎重にスキル抽出を行っている
  • Machine Learned Resume-Job Matching Solution(2016)

    • 論文の概要
      • 深層学習(CNN)を用いて、リッチな特徴量を用意した上で、職務経歴書と求人のマッチング最適化を行っている
      • 職務経歴書の数は4.7万枚
      • KerasやScikit-learnで書かれており軽量
      • 浅いモデルとしてXGBoostを、深いモデルとしてCNNの両方を、最終的に多数決によるアンサンブルにすることで性能が向上
      • アンサンブル手法としてはバギングを行っている
      • リッチな特徴量
        ・Manual Feature(年齢とか性別とか)
        ・Cluster Feasture(クラスタリングしたもの、トピック(LDA))
        ・Semantic Feature(意味的な類似度)
      • モデルはGPUでもCPUでも動く
      • ソースコードはGitHubで公開されてる

    • 参考になるところ
      • CNNながらGPUなしでも計算できるようなモデルのアーキテクチャになっている
      • 特徴量はマニュアルで作成したものと自動で抽出したものの両方をうまく使う

    SKILL: A System for Skill Identification and Normalization(2015)

    • 論文の概要
      • 職務経歴書や求人に記されているスキルの抽出に関するNER(Named Entity Recognition:固有表現抽出)の研究
      • 老舗の求人サイトであるCareerBuilderの
        社員による研究
      • Wikipediaベースのカテゴリ分類、Google検索による集合知を利用してスキル表現の抽出をしている
      • Word2Vecを用いて、あるスキルと関連しているスキルをもとにタグ付をするアプローチが紹介されている
      • データ
        大量の職務経歴書と求人票
      • アプローチ
        ・スキル分類→wikipediaベースのAPI、国の定めた定義など
        ・スキル判定→単一語(そのまま利用)、複数語(Google検索結果から判断(集合知))
        ・スキルタグ付け→Word2Vecをユニグラムで学習し、関連度を計算しスキルのタグ付け
    • 参考になるところ
      • Google検索を使って得た集合知をスキルの分類に活かしている
      • Word2vecで計算した類似度をもとにスキルのタグ付けをしている

    Effectiveness of job title based embeddings on résumé to job ad recommendation(2021)

    • 論文の概要
      • 求人票の表現に対して、分散表現を用いた求人レコメンドの研究
      • 求人票全体を使うよりも、タイトル部分を使ったほうがレコメンドの性能が高くなった
        ・分散表現はWord2VecやDoc2Vecの学習済みや学習したものを色々試している
        ・Cold-Start問題に対しても分散表現は有効な手段であるとしている
    • 参考になるところ
      • 汚い本文のテキストを使うよりもタイトルを使ったほうが良いと言う、岡目八目というか、労せずに成果を出す作法を知れたという気持ち
      • 分散表現がCold-Start問題に対する有効な手段という可能性

    conSultantBERT: Fine-tuned Siamese Sentence-BERT for Matching Jobs and Job Seekers(2021)

    • 論文の概要
      • データは27万件で正例が12.6万件、負例が10.9万件で職務経歴書(ユニークだと15万件)と求人票(2.3万件)からなる。ラベルはキャリアアドバイザーが付けたもの。
      • 各センテンスに対してBERTを適用し、文書単位で平均を取るなどしている。文書は最初の512トークンを使うのがよいとしている。
      • BERTを分類問題・回帰問題についてそれぞれSiamese network(シャムネットワーク)を用いてファインチューニング
        ・出力層は求職者のレジュメと求人票のCOS類似度をマッチングスコアとしている
        ・埋め込み層のデータで教師あり学習をランダムフォレストで行い、COS類似度ではなくランダムフォレストの吐いたスコアを使って推論するバージョンも用意している
      • 回帰タスクでのファインチューニングが一番よかった
    • 参考になるところ
      • BERTをセンテンスに対して使って、平均値をとりそれを特徴量にしている
      • 全文を使わないほうが分類性能が良い可能性
      • 埋め込み層のデータで教師あり学習をして、それのスコアを用いるというアプローチ

    BLSTMを用いた文書分類でデザイナーズマンション予測に再挑戦

    はじめに

    仕事で深層学習を使うことはないのですが、扱える技術の幅を広げていきたいなと思い、BLSTMを用いた文書分類についてkerasでの簡単なサンプルコードをやってみようと思います。データは以前集めた、某不動産紹介サイトの賃貸マンションの設備に関する文書とそれがデザイナーズマンションかどうかのラベルを使います。そして文書内の単語からその文書がデザイナーズマンションかどうかを予測します。前回はAUCで83%だったので、それを超えれると良いですね。

    目次

    単純なRNNとは

    • モチベーション
      • フィードフォワード型のニューラルネットワークではうまく扱うことができない時系列データをうまく扱えるようにすること。
    •  特徴
      • 入力が互いに関係している(多層パーセプトロンの際は置かれていない仮定)
        • 直訳すると循環するニューラルネットワークとなる。
      • 最初の文の単語が2つ目、3つ目の単語に影響を与える可能性を考慮。
      具体的な関数の形としては、 $$ h_t = \tanh (W h_{t-1} + U x_t) \\\ y_t = softmax(V h_t) $$ で与えられる。
      \( h_t \)は隠れ層の状態を、\( x_t \)は入力変数を、\( y_t \)は出力ベクトルを表している。(他のアルファベットは重み行列)

    LSTMとは

    • モチベーション
      • 単純なRNNの勾配消失問題を解決するために提案された手法。
    • 特徴
      • 単純なRNNに置き換えることで性能が大幅に向上することも珍しくない。
        • 時系列データ、長い文章、録音データからなる長期的なパターンを取り出すことを得意としている手法。
      • 勾配消失問題に強い
      • Long Short-Term Memory:長短期記憶
        • 長期依存性を学習できるRNNの亜種。
        • 入力ゲート、忘却ゲート、出力ゲート、内部隠れ層という4つの層が相互に関わり合う。重要な入力を認識し、それを長期状態に格納すること、必要な限りで記憶を保持すること、必要なときに記憶を取り出すことを学習する。
          • 入力ゲート:内部隠れ層のどの部分を長期状態に加えるかを決める。
          • 忘却ゲート:長期状態のどの部分を消去するか決める。
          • 出力ゲート:各タイムステップで、長期状態のどの部分を読み出し、出力するかを決める。
    $$
    i = \sigma (W_i h_{t-1} + U_i x_t) \\
    f = \sigma (W_f h_{t-1} + U_f x_t) \\
    o = \sigma (W_o h_{t-1} + U_ox_t ) \\
    g = \tanh (W_g h_{t-1} + U_g x_t) \\
    c_t = (c_{t-1} \otimes f ) \otimes ( g \otimes i) \\
    h_t = \tanh (c_t) \otimes o
    $$ i:入力ゲート(input)
    f:忘却ゲート(forget)
    o:出力ゲート(output)
    \( \sigma \):シグモイド関数
    g:内部隠れ層状態
    \(c_t \):時刻tにおけるセル状態
    \(h_t \):時刻tにおける隠れ状態

    Bidirectional LSTMとは

    • モチベーション
      •  従来のRNNの制約を緩和するために導入。
    • 特徴
      • ある特定の時点で過去と将来の利用可能な入力情報を用いて訓練するネットワーク
        • 従来のRNNのニューロンをフォワード(未来)なものとバックワード(過去)なものとの2つに分ける。
          • 2つのLSTMを訓練している。
        • 全体のコンテキストを利用して推定することができるのが良いらしい。
          • 文章で言うと、文章の前(過去)と後(未来)を考慮して分類などを行うイメージ。
        • 人間もコンテキストを先読みしながら解釈することもある。
      • BLSTMは全てのシークエンスの予測問題において有効ではないが、適切に扱えるドメインで良い結果を残す。
      • 1997年とかなり歴史があるものらしい
    出典:Deep Dive into Bidirectional LSTM

    Bidirectional LSTMで文書分類

    今回は、BLSTMを使って、マンションの設備に関するテキスト情報から、そのマンションがデザイナーズマンションかどうかを予測します。全体のソースコードはGoogle Colabを御覧ください。

    データ

    データを確認してみると、
     
    今回のデータがテキストとラベルからなっていることがわかる。なお、データ数は1864件あり、そのうち16%がデザイナーズマンションです。

    前処理

    Google Colab上で形態素解析を行うために、MeCabをインストールする。
     
    これでMaCab NeologdをGoogle ColabのPythonで実行できます。
    テキストデータの前処理を行うために名詞だけを抽出してリスト形式で返す関数を定義します。
     
    ここで、語彙に関するデータを作成します。
     
    続いて、単語とそのインデックスからなるdict形式のデータを作成します。
     
    最後に、これまでに作成した語彙とそのインデックスのデータを用いて、実際に学習に使う入力データと出力データを作成します。
     

    実行

    先程作成したデータを訓練データとテストデータに分けます。
    ここで、AUCを計算するための関数を定義します。(まるまる拝借しました)
    続いて、kerasを用いて、ネットワークを構築し、コンパイルを行います。
      テストデータでの予測精度を確認します。
    実際のラベルとテキストデータを見比べてみます。
    LSTMの場合は、BLSTMに関する記述(1行)をネットワークから除外すれば良いので簡単に試すことができます。 せっかくなので比較してみたところ、AUCは0.841でした。BLSTMは0.844だったので、若干上回る程度のようです。 以前扱った記事ではデザイナーズマンション分類はAUCが0.83程度だったので、LSTMを使ったほうが精度が少しだけ高いようです。

    追記

    TensorBoardの検証のloglossを見てみます。 エポックに対してloglossが非常に荒れています。学習曲線としてはセオリー的にアウトなようです。一方で、検証のAUCはエポックに従って高まるようです。 AUCは良くなっているけどloglossが増え続けている。loglossが下がらないと過学習している可能性が高いので、これは過学習しているだけなのだろう。

    参考文献

     

    [R]ボージョレ・ヌーボーのコメントに対してLDATSパッケージを使って時系列トピックモデルを扱う

    はじめに

    先日、某勉強会でLTをしました。その際に10秒だけ紹介したRのパッケージについて記事を書いてみようと思います。

    LDATSパッケージについて

    時系列でのトピックモデルを推定することができるパッケージです。
    やっていることとしてはLDAでトピックを推定して次元を減らし、そのトピックの多変量時系列に関してベイズ手法による変化点検知のためのパラメータ推定を行っているようです。GitHubの該当しそうなソースコードに多変量のデータに対するsoftmax関数での回帰をやっているとの記述がある。(multinomial Bayesian Time Series analysis

    元となっている論文を見る限り、BoW(Bag of Words)を想定して作っておらず、20~30程度のグループからなるデータに対して適用するのがちょうど良いです。アクセスログのページカテゴリや、マーケティングの顧客セグメントであればそんなに数は多くないので扱いやすいと思います。

    データ

    Webサイトから集めてきたボージョレ・ヌーボーのキャッチコピー14年分を今回は扱います。実は販売店側のキャッチコピーとワイン委員会が決めた評価が存在します。私の知っている世界は販売店側のキャッチコピーだけでした。

    試してみた

    今回はとにかく動くことだけを考えて、汚いコードとなっております。やっていることとしては、キャッチコピーを販売側とワイン委員会側のものを一つにつないで、数字を正規表現で「数字」に変換し、RMeCabで形態素解析をし、LDATS向けの形式のデータを作成していきます。
    途中で、日本語の文字化け問題を回避するためにGoogle翻訳を使って単語名を置き換えています。
    1時系列につき1文書となるようにデータを作っていく必要があるのですが、今回はボージョレ・ヌーボーのキャッチコピーなので最初から1時系列につき1文書となっているため都合が良いです。
    データとソースコードはこちら

    こちらは論文の図と同じものだとドキュメントの説明にあったので、論文の説明を見る限り、表すものとしては以下のようです。

    • 一番上の積み上げグラフはトピックごとの単語の割合を表しています。
    • 二番目の折れ線グラフはLDAによって推定されたトピックの時系列推移です。
    • 三番目のヒストグラムは二番目の時系列における変化点を集計したものです。
    • 四番目の折れ線グラフはモデルが推定したトピック割合の変化点の前後での推移です。

    今回の図では文字が潰れていて見にくいですが、

    • トピック1はボキャブラリーが比較的リッチなコメント(「フルーティー」「フレグランス」「複雑」)
    • トピック2は数字を用いたコメント(「何年に一度の!」みたいな)
    • トピック3はボキャブラリーが貧相なコメント(「すごい!」みたいな)

    のようです。
    二番目の折れ線グラフを見る限り、周期的に数字を用いたコメントが現れているように思われます。四番目の折れ線グラフの変化点を見る限り、近年は数字を用いたコメントが相対的に減ってきて、リッチなボキャブラリーになってきているようです。

    おわりに

    時系列トピックモデルをカジュアルに試せる面白そうなパッケージだなと思い、LDATSパッケージを触ってみましたが、そもそもBoWなどを想定して作られているパッケージではないので、単語数が多いような分析ではそもそも可視化ができず使いにくいだろうなと思いました。マーケティングなどでユーザーのセグメントの推移を分析したい場合などにちょうど良いのだろうと思われます。

    参考情報

    [1] Long‐term community change through multiple rapid transitions in a desert rodent community
    [2] Latent Dirichlet Allocation coupled with Bayesian Time Series analyses
    [3] Package ‘LDATS’

    R advent calendar 2019 RSelenium、jpmesh、sfパッケージで東京23区の事故物件を分析してみよう!

    はじめに

    今回で3回目となるR advent Calendarですが、前回は「一発屋芸人の検索トレンドのデータ」を扱い、前々回は「ポケモンのデータ」を扱いました。今回は人の命に関わるようなデータを扱ってみたいと思い、某サイトから東京都の23区内における事故物件の住所と詳細を集めてきました。どのようなエリアが事故が起きやすいのかの分析を行います。(以下では、事故物件をAP(Accident Property)と呼びます。)

    分析工程

    ・データの収集
    ・データの整形
    ・可視化
    ・分析

    データの収集

    APに関する情報を某サイトより集める必要があります。そこで必要なライブラリとしては、RSeleniumやtwitteRがあげられます。
    twitteRが必要な理由は、APに関するサイトにAPの一覧ページがなく、公式アカウントがAPに関するページのリンクを投稿しているところにあります。ただ、私が以前使っていた頃とはTwitterAPIの仕様が変わり、3ヶ月よりも前の情報にアクセスできなくなっていました。そのため、今後のデータに関してはTwitterAPIでいいのですが、過去のものに関しては別アプローチが必要となります。
    また、APに関するサイトはJavaScriptで地図が表示されているだけなので、RSeleniumを使って地図をクリックさせ、表示された情報をスクレイピングするなどの処理が必要となります。
    当初の想定ではTwitterのデータ収集、リンク先の情報をRSeleniumでスクレイピングするだけの簡単な仕事だと思っていたのですが、過去のデータにアクセスできないので、地図上で一つ一つ見つけていくためにRSeleniumだけで頑張ることにしました。(私の過去のアドカレ史上、一番面倒なデータとなりました。)

    誰もやらないと思うのですが、一応手順を記しておきます。

    RSeleniumだけでMapからAPの情報を抽出するための手順
    1.都内の住所一覧を収集
    2.検索窓に住所を入力
    3.検索結果一覧の上位5件をクリック
    4.一度地図を引くことでAPを広い範囲で捉えれるようにする
    5.APのマークの要素を取得し、1件ずつクリックし、表示されたAPの情報をデータフレームに格納する

    こちらが取得できたデータです。

    RSeleniumでAPの
    ・住所
    ・発生時期(フリーテキスト)
    ・AP詳細
    ・投稿日
    を集めることができるので、その住所データに対して、Yahoo!のジオコードに関するAPIを利用します。(利用申請が必要なはずです。4年前くらいに申請していたのでそのまま使えました。)
    Yahoo!のAPIを使えば、住所から緯度経度の情報を取得することができます。

    APの緯度経度がわかれば、jpmeshパッケージを用いて1kmメッシュやら10kmメッシュやらのメッシュデータに変換することができます。
    jpmeshを用いてメッシュデータに変換し、メッシュ単位でAPの発生件数を集計します。

    データ収集用のソースコードは思いのほか長くなってしまったので、GitHubにあげておきました。
    https://github.com/KamonohashiPerry/r_advent_calendar_2019

    ここで再度、手順を整理しておきましょう。

    Twitterに出てきたものだけを取得(直近3ヶ月〜)する場合、
    run_tweet_collect.RでTweetを収集

    run_selenium.RでAPの情報をスクレイピング

    run_map_api.Rで住所から緯度経度の取得

    making_mesh_data_and_download_other_data.Rで緯度経度からメッシュデータへの変換、その他の人口データや地価データと接続をします。

    直近3ヶ月以前のものを取得する場合、
    run_selenium_from_map.Rで地図上から直接APの情報を取得する

    making_mesh_data_and_download_other_data.Rで緯度経度からメッシュデータへの変換、その他の人口データや地価データと接続をします。

    データの整形

    APの1kmメッシュデータを手に入れたら、kokudosuuchiパッケージを使って国土地理院の収集したデータをつなぎこみます。手順としては、以下のとおりです。

    まずは推計人口というそのエリアの人口の予測値です。今回は2010年のものを抽出しました。こちらは1kmメッシュのデータなので、変換することなく使えて都合が良いです。

    続いて、2015年の公示地価を抽出しました。

    こちらはメッシュデータではないので、緯度経度の情報から1kmメッシュのデータに変換する必要があります。後で行います。

    単純集計・可視化

    今回のデータセットのデータ数は3919件です。本当は7000件以上はあると思われますが、マップから取ってくるという勝手上、なかなか全てを取り切ることができませんでした。

    まずは、1kmメッシュごとのAP発生件数のヒストグラムです。

    1kmメッシュにおける人口のヒストグラムです。

    公示地価のヒストグラムです。

    1kmメッシュにおける人口あたりのAP件数のヒストグラムです。

    分析

    ここでは、色々な軸でAPのデータに向き合ってみようと思います。

    APの発生件数の集計

    人口が多いところがAPの発生件数が多いところだと思われますが、とりあえず確認します。

    世田谷区は最も人口が多いことから、AP発生件数では一番となっています。続いて、歌舞伎町などがある新宿が来ています。しかしながら、人口に占めるAP発生件数で言うと、港区がかなり高く出ているのがわかります。

    人口あたりのAP件数

    ここでは、メッシュデータをsfパッケージ用のオブジェクトに変換して、1kmにおける人口あたりのAP発生割合を可視化しています。

    こちらのmapviewパッケージで作ったマップはインタラクティブにいじることができます。ぜひ関心のあるエリアでいじってみてください。

    1kmメッシュ人口あたりのAP発生件数(×100)の可視化

    1kmメッシュでのAP発生件数の可視化

    比率ベースで、色の明るいメッシュのところを見ると、港区、中央区、新宿区、渋谷区などがAPが発生しやすいようです。件数ベースで言うと新宿が一番多いですね。
    一番色が明るい港区はてっきり六本木ではないかと思ったのですが、新橋から日比谷にかけたエリアでした。会社員による自○が多いようです。恐ろしいものです。

    APの名前の集計

    APの名前を集計してみます。これは別にこの名前だからAPになりやすいというわけではなく、単純に数が多いだけの可能性がありますし、実際にそうだろうと思われます。AP発生率を知るには、APではないものも含めた全物件名に占めるAP発生件名を手に入れないといけませんが、全物件名を収集するのが難しいことから単純に頻度の集計となります。今回は、wordcloud2パッケージを使って、ワードクラウドにしてみます。文字が大きいと頻度が高いものとなります。

    ハイツ、荘、コーポ、マンション、号棟、アパート、ハウスなどが多く出現しているようです。ただ、物件の名前としても頻度が高いとも考えられますね。

    地価と人口あたりのAP発生件数の関係

    ここでは地価のデータとAP発生の関係性について見てみます。

    地価の階級値(10個のパーセンタイルに分割)を横軸に、縦軸に人口あたりAP発生数をおくと、地価が上がるに従い人口あたりAP発生数が高まる傾向があります。これは、人口密度が高く地価の高いところではAPが発生しやすいということを示しているのではないでしょうか。人口密度が高いと地価があがる、人口密度が高いと治安が悪くなるという可能性が考えられます。

    APの詳細の集計

    ここではAPになってしまった詳細の内容について先ほどと同様に形態素解析を行いワードクラウドにしてみます。

    どうやら孤独死が多いようです。高齢者の人口構成比が関係しているのだろうと思われます。

    APの発生時期に関するテキストマイニング

    ここでは、発生時期に含まれる四桁の数字を集計して、何年くらいのAPが多いのかをざっくりと掴みます。

    どうやら昔のデータはあまり登録されていないようです。記憶が確かではないかもしれませんし、古すぎるものは消されているのかもしれませんね。あのサイトはユーザー生成コンテンツ(UGC)なので、投稿する人はそこまで昔のことをわざわざ投稿しないのかもしれないですね。

    APの詳細に関するテキストマイニング

    ここではトピック数10として、topicmodelsパッケージを使いLDAを行います。

    なかなか恐ろしいキーワードが多いですが、なんとなくですがうまく分類されているのではないかと思われます。

    トピック1は男性の不幸
    トピック2は不動産屋に言われた告知事項
    トピック3は孤独死
    トピック4は病死
    トピック5は火災・転落・事故
    トピック6は事故のあった建物に関する記載
    トピック7は腐乱した事例
    トピック8は建物に関して不明であることの記載
    トピック9は心理的瑕疵あり
    トピック10は自○

    となっているように思われます。まさかこのようなデータにトピックモデルを使うことになるとは。

    おわりに

    今回はR言語のみを用いて、APに関するデータを収集し、地図にプロットしたり他のメッシュデータとつなぎ合わせて分析をするなどしました。APが発生しやすいエリア、APと地価との関係、APのテキストマイニングなど興味深い結果が得られたと思います。
    一つ残念なのは、時系列情報がフリーテキストなので、APがどのエリアでどの頻度で発生していくのかの分析のコストが高く、今回は時系列情報を用いた分析にチャレンジできませんでした。
    今後はタクシーの需要推定の分析で行われているように、メッシュ単位でのAP発生確率の推定などを機械学習で行えると面白いなと思います。どなたか一緒にアノテーションしましょう!

    それでは、どうか良い年末をお過ごし下さい!
    メリークリスマス!

    参考情報

    数多くの方々の記事を見てどうにか仕上げることができました。感謝します。

    [1]【追記あり】sfパッケージでシェープファイルを読み込んでmapviewパッケージで可視化するまで
    [2]How to use mesh cord in R
    [3]Rを使ってワードクラウドを作ってみました
    [4]国土数値情報ダウンロードサービスWeb APIからデータを取得するためのRパッケージです
    [5]東京の地価公示データを眺める
    [6]Chapter 1 Introduction to spatial data in R
    [7][翻訳] RSelenium vignette: RSeleniumの基本
    [8]RからYahoo!のジオコーディングを利用する方法
    [9]EMBEDDING A LEAFLET MAP ON WORDPRESS
    [10]mapview advanced controls
    [11]RSeleniumでChromeからファイルをダウンロードするディレクトリを指定する方法
    [12]Selenium Serverが立ち上がらないときはportが被っているかも!?
    [13]brew install selenium-server-standalone
    [14]ナウでヤングなRの環境変数管理方法
    [15]タクシードライバー向け需要予測について
    [16]LDA with topicmodels package for R, how do I get the topic probability for each term?
    [17]dplyr — 高速data.frame処理

    [Python]機械学習などでテキストデータを特徴量にする際のソースコード集

    テキストデータの特徴量化について

    仕事ではテキストデータを多用するので、機械学習などで扱うためにテキストデータを特徴量にするためのアプローチを色々と整理してソースコードを残しておきたいと思います。今回はあくまでも私の知っているものだけなので、網羅性はないかもしれませんが悪しからず。
    (2019/08/18 追記)Stackingをカジュアルに行えるvecstackというモジュールを用いた予測も試してみました。下の方の追記をご覧ください。

    アプローチ

    テキストデータを特徴量にする際のアプローチとしては、以下の3つが良く使っているものとなります。
    ・単語ベース
    ・クラスタ、トピック、分散表現ベース
    ・文書間の類似度ベース

    今回扱うデータ

    ひょんなことから、昨年10月くらいに取りためたマンションの施設情報のテキストです。

    緑色が印象的な某不動産紹介サイトをクローリングしました。全部で1864件ほどの文書数となります。

    加えて、デザイナーズマンションかどうかのフラグを作成しました(17%くらいがデザイナーズマンションの割合)。これでもって、マンションの施設情報からデザイナーズマンションかどうかを分類できるかチャレンジしたいと思います。
    ここにデータを置いていますので、興味のある方はご利用ください。

    今回扱うモデル

    ランダムフォレストです。10foldsクロスバリデーションによるAUCの結果を各手法のスコアとして扱います。

    こちらは、任意の手法に関して10foldsクロスバリデーションで実行し、AUCのグラフを生成してくれるソースコードです。主にscikit-learnのサイトに載っているものです。引数のclassifierをsklearnの任意のモデルのインスタンスで渡せば動きます。

    単語ベース

    シンプルに単語をそのまま特徴量にするというものですが、文書によっては単語数が多すぎて収集がつかないと思います。そこで単語を簡単に選択できるDocumentFeatureSelectionというパッケージを利用します。

    このパッケージでは
    ・TF-IDFベースの特徴量選択
    ・PMI(Pointwise Mutual Information)ベースの特徴量選択
    ・SOA(Strength of association)ベースの特徴量選択
    ・BNS(Bi-Normal Separation)ベースの特徴量選択
    を行うことができます。

    まずは今回のベースラインとして、単語のカウントベースでの特徴量を扱いたいと思います。
    その前に、GitHubに上がっているデータに対して以下のように簡単な前処理をしておきます。

    ようやくベースラインの予測となります。以下のコードを実行すると、ROCが描かれた図がJupyter上で表示されます。

    AUC82%というのはベースラインとしてはなかなか強敵なのではないでしょうか。

    さて、本題の特徴量選択パッケージの適用をするためのソースコードを以下に記します。

    以上のソースコードを実行すれば、tf_idf_scored_df、pmi_scored_df、soa_scored_df、bns_scored_dfにスコアを付与された単語のリストが手に入ります。

    ここでは各スコアに関してアドホックに閾値を設けて、特徴量として利用することにします。

    TF-IDFベースの特徴量選択

    PMIベースの特徴量選択

    SOAベースの特徴量選択

    BNSベースの特徴量選択

    クラスタ、トピック、分散表現ベース

    続いて、k-meansやLDAやword2vecを用いて特徴量を作成する方法です。今回はk-means、ミニバッチk-means、LDA、FastTextによる分散表現を扱います。

    k-means、ミニバッチk-means

    LDA

    こちらはgensimでLDAを推定し、推定したトピックの割合をデータフレームで返すコードです。

    トピック数をとりあえず30個くらいに指定して推定したトピックの割合を特徴量として文書分類を行います。そのため、特徴量の数は30個になります。

    FastTextによる分散表現

    今回はデータ数が少ないことから、学習済みの分散表現を用います。日本語のコーパスに対して、FastTextで推定された分散表現となります。学習済み分散表現はこちらから拝借しました。

    分散表現は単語に対して計算されるので、単語に対して分散表現を足し合わせたものを特徴量として扱います。ここでは分散表現の合計値、平均値、TF-IDFで重みを付けた平均値の3つのパターンを試します。

    合計値ベース

    平均値ベース

    TF-IDFで単語を重みづけた平均値ベース

    文書間の類似度ベース

    今回は、デザイナーズマンションの定義文に似ているかどうかという観点で類似度ベースの特徴量を作ってみたいと思います。

    今回は変数が一つだけなので、機械学習はせず、デザイナーズマンション割合との関係を図示するにとどめておきます。横軸がデザイナーズマンションの定義と施設情報の類似度で、縦軸がデザイナーズマンション割合です。

    どうやら、途中でデザイナーズマンション割合がピークを迎えるようです。

    おわりに

    最先端の手法は調べれていないですが、テキストデータを特徴量に落とし込む手段を備忘録として残しておきました。今回あげた中では、SOAベースの特徴量選択のAUCが83%と一番高かったですが、ベースラインが82%と僅差でした。そして、分散表現形のものは80%に届いた程度です。余力があれば新しい特徴量の作り方が分かり次第アップデートしようと思います。

    追記

    “Automate Stacking In Python How to Boost Your Performance While Saving Time”という記事を見つけたので、紹介されているvecstackモジュールを使って今回のモデルに関して簡単にstackingしてみようと思います。
    コードに関しては、こちらのGitHubに上げています。試してみた所、AUCは88%になりました。結構上がりましたね。しかもコードはめちゃ短いので楽です。

    参考文献

    [1]Julian Avila et al(2019), 『Python機械学習ライブラリ scikit-learn活用レシピ80+』, impress top gear
    [2]Receiver Operating Characteristic (ROC) with cross validation
    [3]@Kensuke-Mitsuzawa(2016), “テキストデータで特徴量選択をする”, Qiita
    [4]JapaneseTokenizer 1.6
    [5]DocumentFeatureSelection 1.5
    [6]自然言語処理における自己相互情報量 (Pointwise Mutual Information, PMI)
    [7]【Techの道も一歩から】第3回「第11回テキストアナリティクス・シンポジウム」
    [8]文書分類タスクでよく利用されるfeature selection

    学習済み分散表現を用いた文書分類に挑戦(一部再学習も)

    はじめに

    2018年9月のテキストアナリティクスシンポジウムに行った際に、学習済みの分散表現で事前学習したモデルを使って分類してうまくいく事例が紹介されていました。
    全てのタスクにおいてうまくいくとは思えませんが、試すコストはあまりかからないので試してみます。

    2017年のテキストアナリティクスシンポジウムにおいても、メルカリやGunosyでは分散表現を用いた手法が一番精度が高いと言われていましたし、今年の会ではNLP系の学会でも分散表現はデファクトスタンダードになっているという話も伺いました。
    2013~14年はLDAを使った研究が多かった気がしますが、徐々にシフトしていっているんですね。

    これまで(Word2Vecを用いて蒙古タンメン中本の口コミ評価を予測してみる)は4000件程度の蒙古タンメン中本の口コミの情報を元に分散表現を手に入れていましたが、学習済みの分散表現を用いたアプローチも有効かもしれないと思い、試してみようと思います。

    分類タスク

    某グルメ口コミサイトの蒙古タンメン中本の口コミのテキストから、3.5点以上の評価かどうかを予測するタスクを扱います。
    本当は、ポケモン図鑑の説明文から水やら炎やらのタイプを予測するとかをしたいのですが、あいにく手元にデータがないので、以前集めた蒙古タンメン中本の口コミを使います。(実は後日、ポケモン図鑑のデータを集めたのですが、平仮名にまみれたデータな上に、データ数も800件しかなかったので、どのみち厳しかったです。)

    学習済み分散表現

    Word2Vecなどで大量の文書をもとに学習させた分散表現のことを指します。
    大規模コーパスで分散表現を手に入れる際は、数十GBにも相当するテキストデータを数時間かけて推定するので、学習済みのモデルは非常にありがたいです。(4年前に会社のPCで計算した際は、12時間くらいかかったこともありました。)

    無料で提供してくださっている分散表現については、すでにこちらのブログで紹介されています。そこで紹介されているものに少し付け足すと、日本語の分散表現に関しては以下のようなものがあります。

    • 白ヤギコーポレーションのモデル:Gensim
    • 東北大学 乾・岡崎研究室のモデル:Gensim
    • Facebookの学習済みFastTextモデル:Gensim
    • NWJC から取得した単語の分散表現データ (nwjc2vec):Gensim
    • NNLM embedding trained on Google News:TensorFlow

    そこで、今回は各種学習済み分散表現と蒙古タンメン中本コーパスで求めた分散表現の文書分類の性能バトルをしてみたいと思います。
    ただ、分散表現ではなく、単語の頻度をもとに特徴量を作ったものが一番精度が高いのですが、分散表現同士の比較でもってどの学習済み分散表現が中本の口コミ分類に役に立ちそうなのかを明らかにしようと思います。(本来は分析という観点から即でボツですが、見苦しくも比較していきます。)

    前処理

    前処理は以下の通りで、テキストデータを分かち書きして、数値や低頻度・高頻度語を除外しています。

    処理を施すとこのようなデータになります。

    特徴量は、scikit-learnのCountVectorizerやTfidfVectorizer、分散表現の合計・平均・TF-IDFを求めたものを用意します。

    蒙古タンメン中本の口コミ4000件から作成した分散表現:Gensim

    まず、以前のブログで紹介した蒙古タンメン中本の分散表現ですが、以下のように推定しています。

    Pipelineを用いてExtraTreesClassifierによる学習をします。特徴量は先程あげた、テキストベースのCountVectorizerやTfidfVectorizer、分散表現の合計・平均・TF-IDFで、評価指標はAUCのクロスバリデーションスコアとします。

    汗に関してコンテキストの似ている単語を抽出しています。

    結果は、以下の通りで、分散表現を使わない方がAUCが高いです。ただ、w2v_tfidf(分散表現のTF-IDFを特徴量にしたもの)が分散表現の中でAUCが高いようです。今回はこの60.5%をベースラインに比較していこうと思います。

    白ヤギコーポレーションのモデル:Gensim

    こちらのリンク、「word2vecの学習済み日本語モデルを公開します」から、ダウンロードしてそのまま以下のコードでモデルを扱えます。

    汗の関連語を抽出していますが、中国の歴史の何かですか?可汗とかいう単語は聞いたことあるかも。

    まずは白ヤギさんの分散表現をそのまま使って予測してみます。(コードは先程のものとほぼ重複するので省略しています。)
    残念ながら、ベースラインの60.5%には至りませんでした。

    hogehoge.modelというフルモデル形式の場合は、再学習が可能です。詳しくはこちら(models.word2vec – Word2vec embeddings model)に書かれています。

    今回は、白ヤギさんの分散表現に対して、追加で蒙古タンメン中本のテキストを食わせて再学習させます。

    ベースラインの60.5%よりも下回り、さきほどの白ヤギさんのもともとの分散表現よりも下回りました。

    再学習してもかえって精度が下がったりすることから、簡単に精度が出るわけではなさそうです。まぁ、理想はその適用領域での大量のテキストデータがあることで、Wikipediaを元に作成した分散表現に強く依存しても駄目なのだろうと思われます。

    東北大学 乾・岡崎研究室のモデル:Gensim

    日本語 Wikipedia エンティティベクトルからダウンロードした学習済み分散表現を用います。ダウンロード後は普通に「gzip -d file.txt.gz」みたいにターミナル上で解凍します。以下のコードを実行すればすぐに使うことができます。
    ただし、KeyedVectors形式のものは白ヤギさんのように再学習ができません。(Why use KeyedVectors instead of a full model?

    汗の類似語に関しては、難しい単語が高めに出ているようです。

    残念ながら、ベースラインの60.5%には至りませんでした。

    Facebookの学習済みFastTextモデル:Gensim

    FastTextはGoogleにいたTomas Mikolov氏がFacebookに転職されて作られた分散表現を求めるためのモデルです。Gensimでも呼び出せます。学習済みのものはこちらのGitHub(Pre-trained word vectors)にあるのですが、NEologdで形態素解析したものをベースに学習し公開されている方がいるとのことで、こちら(fastTextの学習済みモデルを公開しました)からダウンロードしたものを使わせていただきました。

    何だこれはレベルの結果が返ってきました。中国の歴史上の人物か何かなんでしょうか。

    若干ですがベースラインの60.5%よりも良い結果が得られましたが、 誤差の範囲な気がします。

    NWJC から取得した単語の分散表現データ (nwjc2vec):Gensim

    国立国語研究所の収集されたテキストデータを元に学習した分散表現が提供されています。ただし、利用するためには申請する必要があります。申請が受理されたらこちら(NWJC から取得した単語の分散表現データ (nwjc2vec) を頒布)からダウンロードして使えます。

    汗の関連語ですが、うまく関連付けれているように思われます。少なくとも中国史ぽくはありません。しかしながら、顔文字まで学習していたとは。

    ベースラインの60.5%よりも1%ポイントほど高い結果となりました。

    NNLM embedding trained on Google News:TensorFlow

    こちら(tensorflow-hubで超簡単にテキスト分類モデルが作成できる)で紹介されているように、GoogleがTensorFlowでGoogleニュースのテキストをもとに学習した分散表現が提供されています。

    こちらのGitHub(NNLM embedding trained on Google News)から、Japaneseのnnlm-ja-dim50、nnlm-ja-dim50-with-normalizationなどが使えます。分散表現の説明についてはこちらのドキュメント(Token based text embedding trained on Japanese Google News 6B corpus.)にあります。

    AUCが65%となっているものの、先程のsklearnでのクロスバリデーションのものとの比較ではないので、なんとも言えないですが、Googleニュースのデータだし結構精度が出そうな可能性を感じますね。
    今後、TensorFlowでクロスバリデーションによるAUCスコアの出し方を調べてみて、順当に比較できるようにしたいです。(Kerasを使って計算している事例は見つけた。)

    比較

    今回の分類タスクはそもそも分散表現では精度が出なかったのですが、学習済み分散表現の中で序列を作るとすると、梵天が一番良く、FastTextが少しだけ良かったです。
    TensorFlowをほぼ業務で使わないので、Googleニュースの分散表現を今回の比較対象にできなかったのですが、後日比較できるようにしたいと思います。

    あと、今回の口コミの点数を当てるタスクよりも、分散表現にとって相性がいいタスクがあるかもしれないので、今回の結果で諦めることなく色々と試して行きたいです。

    おわりに

    様々なシンポジウムなどでスタンダードとなってきた分散表現ですが、学習済み分散表現をそのまま使って分類問題で役に立つのかを見てきました。残念ながら、口コミの評価予測タスクにおいては全然効果がなさそうでした。ただ、分散表現の中でもタスクによって相性の良い学習済み分散表現がありそうです。
    先程も述べたように、理想は大量のテキストデータで学習した分散表現を求め、それを予測に使うことなので大量のテキストデータを集めて再チャレンジしたいです。どれくらいのテキストデータがあれば十分なのかの規模感もわからないので、実践あるのみなんですかね。

    参考情報

    Word Embeddingだけで文書分類する
    tensorflow-hubで超簡単にテキスト分類モデルが作成できる
    Error: ”Word2vec’ object has no attribute index2word
    Word2vec Tutorial Online training / Resuming training
    Word Embeddingモデル再訪
    Googleの事前学習済みモデルを手軽に利用出来るTensorFlow Hub
    ゼロから作るDeep Learning ❷ ―自然言語処理編

    蒙古タンメン中本コーパスに対してのLDAの適用とトピック数の探索

    モチベーション

    前回の記事では、Webスクレイピングにより入手した、蒙古タンメン中本の口コミデータに関して、Word2Vecを適用した特徴量エンジニアリングの事例を紹介しました。
    今回はせっかく興味深いデータがあるので、どのようなトピックがあるのかをLDAを適用したいと思います。加えて、これまで記事で扱ってきたLDAの事例では評価指標であるPerplexityやCoherenceを扱ってこなかったことから、トピック数がどれくらいであるべきなのか、考察も含めて行いたいと思います。以前扱った階層ディリクレ過程であれば、トピック数を事前に決める必要が無いのですが、今回は扱わないものとします。

    環境

    ・MacBook Pro
    ・Python3.5
    ・R version 3.4.4

    Gensimで行うLDA

    今回もPythonのGensimライブラリを用いて行います。

    • パープレキシティ
      • テストデータに対して計算
      • 負の対数尤度で、低いほどよい。
        • パープレキシティが低いと、高い精度で予測できるよい確率モデルと見なされる。汎化能力を表す指標。
        • トピックの数をいくらでも増やせばパープレキシティは下がる傾向が出ている。
        • 教科書でのパープレキシティの事例に関しては、トピック数を増やせば低くなるという傾向が出ている。

    以下のコードでパープレキシティを計算します。

    実際に、中本コーパスで計算したトピック数に対してのパープレキシティは以下のように推移しました。

    Ldaのモデル選択におけるperplexityの評価によると、
    ”複数のトピック数で比べて、Perplexityが最も低いものを選択する。」という手法は人間にとって有益なモデルを選択するのに全く役に立たない可能性がある。”と記されています。

    『トピックモデルによる統計的潜在意味解析』には、”識別問題の特徴量として使う場合は識別問題の評価方法で決定すればよい”とあるので、目的によってはパープレキシティにこだわらなくても良いと思われます。

    今回のケースだと、パープレキシティだけだと、決めかねてしまいますね。

    • コヒーレンス
      • トピックごとの単語間類似度の平均
      • トピック全体のコヒーレンスが高ければ、良い学習アルゴリズムとみなす。

    以下のコードでコヒーレンスを計算します。

    実際に推定してみたところ、トピック数が20を超えたあたりからコヒーレンスが下がる傾向があるので、
    それ以上のトピック数は追い求めない方が良いのかもしれません。

    Rでもやってみる

    Rでトピック数を決める良い方法がないか調べてみたところ、ldatuningとかいうパッケージがあることがわかりました。複数の論文(Griffiths2004, CaoJuan2009, Arun2010,Deveaud2014)で扱われている手法を元に、適切なトピック数を探れるようです。このパッケージを紹介しているブログの事例では、90から140の範囲で最適なトピック数となることが示されています。詳しくはこちらを見てください。
    Select number of topics for LDA model

    以下のコードで実行しました。一部、驚異のアニヲタさんのコードを拝借しております。なお、ldaパッケージのlexicalize関数を用いることで、ldatuningに入力するデータを作成することができます。

    これを見る限りは、60〜70個の辺りに落ち着くのでしょうか。

    トピックの吐き出し

    Rでの結果から、60個程度のトピックで推定し、各記事に割り当てが最大のトピックを付与して、トピック別の口コミ評価をみてみようと思います。

    以下のコードではトピック別の口コミ評価のしやすさからtopicmodelsパッケージを用いた推定となっています。

    口コミ評価の点数が上位のトピックはこんな感じです。

    口コミ評価の点数が下位のトピックはこんな感じです。

    中本は社会人2〜3年目で新規メディアの立ち上げのストレス解消で数回行きましたが、北極の赤さは異常だと思います。北極を食べたり、トッピングする余裕のある人、ましてや辛さを倍にするという時点で口コミ評価も高くなると考えるのは自然なのかもしれません。

    参考情報

    トピックモデル (機械学習プロフェッショナルシリーズ)
    トピックモデルによる統計的潜在意味解析 (自然言語処理シリーズ)
    models.ldamodel – Latent Dirichlet Allocation
    Ldaのモデル選択におけるperplexityの評価
    pythonでgensimを使ってトピックモデル(LDA)を行う
    gensim0.8.6のチュートリアルをやってみた【コーパスとベクトル空間】
    LDA 実装の比較
    Jupyter notebookにMatplotlibでリアルタイムにチャートを書く
    Inferring the number of topics for gensim’s LDA – perplexity, CM, AIC, and BIC
    Select number of topics for LDA model
    47の心得シリーズをトピックモデルで分類する。 – 驚異のアニヲタ社会復帰への道

    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

    分散表現を特徴量として文書分類するための方法について調べてみた

    以前、テキストアナリティクスシンポジウムに参加した際に登壇者が機械学習のタスクにおいて分散表現を特徴量に使ったと言っていて、実務で使えるようにしたいと思ったので、調べた手法について記します。

    先行研究

    海外のブログ(Text Classification With Word2Vec)では、以下の手順で文書分類のための特徴量としてWord2Vecが用いられていました。

    • STEP1:ロイターのコーパスをもとにWord2Vecを求める。(先行研究では100次元に圧縮しています。)
    • STEP2:テキストごとに属する単語に対して、STEP1で求めた100次元の分散表現の平均値をとる。あるいは、TF-IDFのスコアで重み付けしたものを作る。これで100次元の分散表現が各テキストごとに用意できる。
    • STEP3:STEP2で作った100次元の分散表現を用いて、テキストごとのラベルについてExtra Treesによる分類器を学習させる。

    ざっとこんな感じのアプローチになっていました。”ベクトルの足し算が意味の足し算に対応する「加法構成性」”という考え方からのアプローチと言えるのでしょうか。

    そのあと、ベースラインとの比較をしていましたが、結論としては、ラベル付きのトレーニングデータが非常に少ない場合において有利である傾向があったものの、SVMなどの既存手法より精度が出ているとは言えないような結果でした。

    今回の事例におけるタスクではうまくいかなかったようですが、テキストアナリティクスシンポジウムにおいてはアツいとされていたので、自社のデータで適用するなどしておきたいです。

    今回取り上げたブログやGithubにはPython2.X系のコードしかなかったため、3.X系で動くように一部変更するなどをしました。
    以下で3系で動き、同様の結果が出ているものを載せています。

    コード

    コードの概要としては
    ・訓練データの作成
    ・モデルの定義
    ・モデルのベンチマーク
    ・結果の描写
    です。

    事前にテキストデータをダウンロードして手に入れておく必要がありますが、それに関してはターミナルで実行できるものなので、ここでは載せていません。参考文献のblog_stuff/classification_w2v/benchmarking.ipynbを参照ください。

    このようにSVCに負けている結果が出ます。

    比較の棒グラフはこんな感じ。

    自社のテキストデータで是非とも試したい。

    参考文献

    岩波データサイエンス Vol.2
    blog_stuff/classification_w2v/benchmarking.ipynb
    分散表現(単語埋め込み)
    Text Classification With Word2Vec

    人工知能学会全国大会2017のWebマーケティングで参考になりそうな研究9選

    はじめに

    今更ではありますが、2017年5月に開かれた人工知能学会全国大会2017の公開資料の中から、私の本業であるWebマーケティングで役に立ちそうな研究を独断と偏見で9本ほど集めてみました。思っていたよりもWebマーケティングぽい領域が多かったので、社内での分析業務におけるアイデアに直結しそうな気がしています。

    ちなみに、全ての資料はこちらにあります。

    基本的に各研究ごとに
    ・目的と結果
    ・対象となるデータ
    ・手法の概要
    ・PDFのリンク
    について記していきます。

    紹介する研究

    今回は以下の研究を紹介したいと思います。
    「オンライン広告におけるスパース性と遅れコンバージョンを考慮した予測モデル」
    「テキストマイニングを用いた転職サイトの会員離脱予測」
    「インターネット広告におけるスパースなユーザー行動ベクトルからのユーザー特徴抽出モデル」
    「ユーザーのページビュー系列からのコンバージョン予測」
    「SNSにおけるユーザの行動のモチベーション要因の分析」
    「状況に応じた楽曲推薦に向けたソーシャルデータ分析」
    「テキストマイニングを用いた口コミ分析による点数評価の信頼性確認手法」
    「不動産仲介マーケティングのためのユーザ行動予測」
    「SUUMOでの不動産データ活用の取り組みと未来」

    オンライン広告におけるスパース性と遅れコンバージョンを考慮した予測モデル

    目的と結果

    オンライン広告のCVR予測の精度向上を目的としている。
    これまでの課題としては、
    「質的変数による特徴量のスパース性」
    「広告クリックからのCVまでの期間の長さ(期間が空いてからCVしたりするケースがあるので正例だったはずが負例と扱われる可能性がある)」
    などがあった。提案手法により従来手法に比べ高い精度でCVR予測が可能であることが示された。

    対象となるデータ

    過去3週間分の広告配信データでテスト期間は7日間

    手法の概要

    • 次元圧縮
      • Factorization Machine(FM)を用いて、従来のロジスティック回帰では考慮できていなかった交互作用をモデリングし、低次元のベクトル内積に分解して表現している。
    • 遅れCV問題の対応
      • 遅れてCVが発生する事象に関しては、指数分布を用いて遅れてCVする事象をモデリングするDelayed Feedback Modelを構築することで、本当は事後的にCVしそうなユーザーの推定を行っている。
    • 予測
      • これらの手法を合わせた、Delayed Feedback Factorization Machineを構築し、SGD(確率的勾配降下法)やAdaGradを用いてパラメータを推定している。

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/110.pdf

    テキストマイニングを用いた転職サイトの会員離脱予測

    目的と結果

    登録情報や履歴書のテキスト情報を用いて特徴量とし、転職サイトの登録会員の離脱予測を行っている。ブラックボックスでは無い形での結果の解釈ができ、予測精度も高いことが示された。

    対象となるデータ

    • 2009年10月1日〜2016年9月28日までの履歴書、職務経歴書、自己PR書、希望条件
    • 離脱会員の定義は「登録して1ヶ月以内に一度も応募しない会員」としている。

    手法の概要

    • STEP1:Pythonのmojimojiというライブラリを利用してカナを全角に、数字とアルファベットは半角に変換。
    • STEP2:MeCabを用いて名詞のみ抽出
    • STEP3:「職務」「経歴」「業務」「内容」などを不用語(stop word)とした。
    • STEP4:Grid Searchでパラメータチューニングしたランダムフォレストを用いて変数重要度(Feature Importance)を出し、重要度の上位90%を占める単語以外を削除
    • STEP5:登録情報のデータ(年齢、転職回数、住所)を数値データに変換
    • STEP6:選定した特徴量を用いて決定木アルゴリズムを適用

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/949.pdf

    インターネット広告におけるスパースなユーザー行動ベクトルからのユーザー特徴抽出モデル

    目的と結果

    広告のCTR予測を行う際の特徴量が非常にスパースであることから、ユーザーをクラスタリングして広告配信に効果的なユーザーを抽出することを目的としている。研究ではCVRの高いユーザー群の抽出を可能にしている。

    対象となるデータ

    • 2016年6月1日〜2016年6月21日の間のクリックやコンバージョンのデータ(株式会社アイモバイルが提供)
    • クリック実績のある広告数、コンバージョン実績のある広告数、クリックされた広告番号、コンバージョンが発生した広告番号、ユーザー番号など

    手法の概要

    • 高次元スパースデータを低次元に落とし込むために、オートエンコーダを用いている。
    • オートエンコーダにより得られた特徴量をもとにユーザーのクラスタリングを行っている。(オートエンコーダは入力された情報をなるべく欠損しないように、効率的に圧縮する構造を持たせたニューラルネットワークのこと。)
    • データにおけるゼロの成分を確率的に欠損とみなして計算処理を早めている。
    • 学習モデルはAdaGrad(学習率を学習に合わせて最適化する手法)
    • 訓練データ(特徴量の数がクリックで23339個、コンバージョンで5619個)にスパースデータ許容型オートエンコーダで500次元まで圧縮し、さらに通常のオートエンコーダで146次元まで圧縮している。
    • 次元圧縮して獲得したデータに対してk-means法でクラスタリングを行い、CVRなどを比較している。

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/12.pdf

    ユーザーのページビュー系列からのコンバージョン予測

    目的と結果

    Web広告において、ユーザーの閲覧履歴からコンバージョンを予測することを目的に、Recurrent Neural Network(RNN)を用いた結果、非時系列のSVMよりもわずかばかりかの精度向上が観察された。データ数が少ない場合はSVMに軍配があがる結果となっている。

    対象となるデータ

    2016年7月1日〜2016年10月31日の広告の接触履歴データなど(広告の業種別データやユーザーのページビュー数)を特徴量に用いて、2016年11月1日〜11月30日までの期間を予測対象とした。データは株式会社マイクロアドが提供している模様。

    手法の概要

    • Long Short-Term Memory RNN(LSTM)
      • ソフトアテンションモデル
        • 可変長の系列に対して内積で重みを算出し、足し合わせることで一部から情報を取り出すモデル。途中の層まで複数業種のデータを用いることで、複数の業種などの情報を共有することができる。(最後の隠れ層には業種別の特徴量を用いている。)
        • 勾配の計算に関してはAdamを用いて、実装はKerasを用いている。活性化関数はTanh、ドロップアウトはGaussianDropout
          としている。
      • RNNで用いる特徴量としては、特定のWebページを640種類に分類して、1日のうちに各トピックにページビューがあったかなかったかを1-0の変数にするなどの前処理を行っている。

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/765.pdf

    SNSにおけるユーザの行動のモチベーション要因の分析

    目的と結果

    SNSユーザーのモチベーションの要因(一ヶ月先に投稿するかどうか)をユーザー同士の関係性(staticな関係)と、そのユーザーの周りのインタラクション(dynamicな関係)という観点から分析し、ユーザー同士の関係性とユーザー周りのインタラクションを同時に用いたモデルにおいて、それらがモチベーションの要因につながりうる傾向が観察された。

    対象となるデータ

    • RoomClipという部屋の家具やインテリアの様子の写真を投稿するSNSのデータ
      • 気に入った写真に「いいね」を付けたり、コメントを送れる。
    • 2015年3月の一ヶ月間を学習期間とし、2015年4月の投稿の有無を予測対象とする。

    手法の概要

    • ネットワーク特徴量
      • 各ユーザーに対して、
        • 中心性(次数中心性、媒介中心性、近接中心性)
        • クラスタ係数、PageRank、フォロー数とフォロワー数の比率、フォローしているユーザのアクティブ度
    • フィードバック特徴量
      • 特定期間中にユーザが周りのユーザから自身の投稿に対してもらった「いいね」「コメント」に対して
        • 反応の数
        • 反応を行ったユーザの数
        • 反応を行ったユーザのうち、相互フォロー関係にあるユーザからのものの割合
    • 予測器としてSVMを利用

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/534.pdf

    状況に応じた楽曲推薦に向けたソーシャルデータ分析

    目的と結果

    ユーザへの楽曲推薦システムの構築を目的に、楽曲とその再生時の状況の関係を収集したソーシャルデータより分析している。取得したデータのうちの7%ほどではあるが、ツィート情報から楽曲と再生時の状況との関係を抽出可能であるということが示された。

    対象となるデータ

    2016年8月10日〜2016年9月3日の間に投稿されたツィート(66879件)

    手法の概要

    • ハッシュタグ#nowplaying付きのツィートを収集して、アーティスト名や楽曲名や楽曲再生時の状況(同一ユーザの5分前後の投稿内容)を収集
    • 取得したツィートからアーティスト名、楽曲名を除去して再生時の状況を取得
    • 取得したデータからデータベースを作成

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/102.pdf

    テキストマイニングを用いた口コミ分析による点数評価の信頼性確認手法

    目的と結果

    製品などの口コミの評価レビューに関する信頼性を確かめることを目的としている。レビューデータに対して感性評価を行い、さらにその結果に対して総合評価点数別に感性表現(Goodなど)の伴った表現の頻出ランキングを作成することで、点数が高い理由を把握しやすくなった。

    対象となるデータ

    ソニーの製品サイトにおける、ユーザの製品に対する評価とコメントのデータ(1406件)

    手法の概要

    • テキストマイニングスタジオによる感性評価(ポジティブ、中立、ネガティブ)
    • 総合評価点数別(5段階)の「ポジティブ、中立、ネガティブ」の割合の調査
    • 総合評価4の口コミかつ中立な表現にフィルターをかけて、感性情報を有する単語と係り受け関係となった単語の頻度ランキングのTOP10を抽出

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/1115.pdf

    不動産仲介マーケティングのためのユーザ行動予測 Prediction of user behaviors for real estate brokerage marketing

    目的と結果

    不動産紹介業において、顧客の属性情報と来店初期の行動から、来店者が最終的に商品を購買するかどうかの予測モデル(不均衡データにおける予測タスク)を構築することでマーケティングの広告効果測定に適用することを目的としている。結果として、顧客の来店後30分間という短い時間における行動だけでも識別力のある予測が可能であることが示されている。

    対象となるデータ

    • オンライン不動産賃貸仲介店舗iettyの顧客データベース
      • 希望物件の情報
        • 引っ越し希望日
        • 住みたいエリアの駅
        • 間取り
        • 広さ
        • 家賃
      • 顧客属性
        • 在住の地域
        • 性別
        • 年齢
      • 行動データ
        • 登録時
          • フォームの記入にかかった時間
          • フリーコメントの長さ
          • 利用デバイス
        • 登録後
          • 初回チャット発言までの経過時間
          • 初回物件評価までの経過時間

    手法の概要

    • STEP1:顧客の属性および登録初期(30分以内)の行動から特徴量を作成し、2ヶ月以内に契約すれば正例、それ以外を負例とする。(正例は619件、負例は33212件)
    • STEP2:検証用データを無作為に20%取り置く
    • STEP3:残り80%のデータに対して負例に対する、ランダムアンダーサンプリングと、正例に対するSMOTE(Synthetic Minority Over-sampling Technique)を用いたオーバーサンプリングによりサンプル数を調整する。
    • STEP4:ランダムフォレストを用いて、無効な特徴量の取捨選択や離散化のレンジ調整する。
    • STEP5:全特徴量(83次元)を二値化して、RBFカーネル(Gaussian カーネル)のSVMを適用し、様々なCやγの組み合わせを試行して、二値分類を行う。
    • STEP6:評価を予測確率の平均とAUCの2種類で行う。

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/466.pdf

    SUUMOでの不動産データ活用の取り組みと未来

    目的と結果

    物件検索ユーザーが比較検討を行いやすくすることを目的に様々な取り組みをしている。

    対象となるデータ

    • 不動産ポータルサイトSUUMOのデータ
      • 行動履歴(Webサイト、アプリ)
      • 物件情報(不動産情報)
      • 街情報(独自で収集)
      • アンケート

    手法の概要

    • 実活用
      • 相場推定
      • 単純な加算平均ではなく、外れ値や時系列変動、データ量などを考慮して推定している。
      • リアルタイム物件レコメンド
      • ランキング学習により推定したモデルを利用し、リアルタイムに計算を行っている。個人ごとにパーソナライズしたランキングも用いている。
      • バンディットアルゴリズムによる配信施策の最適化
      • メールやプッシュ通知などで件名やデザイン、配信時間など様々な選択肢があり、その最適なパターンを見つけるために、バンディットアルゴリズムを適用している。
    • 実験段階
      • 間取り画像の分析
      • ユーザーの求めている間取りが何なのかを画像から抽出しようとしている。
      • ユーザーの検索行動、嗜好の推定
      • ユーザーの検索行動から、嗜好性を掴み取り、レコメンドする際の理由付けができるようにモデルを作ろうとしている。

    PDFのリンク

    https://kaigi.org/jsai/webprogram/2017/pdf/743.pdf

    感想

    • 特徴量の削減のためにランダムフォレストを適用する流れ
    • 高次元スパースデータに対するニューラルネットワークの適用
    • CVの時系列予測のためにRNNの適用
    • SNS分析におけるネットワーク特徴量とフィードバック特徴量という概念
    • 口コミデータ分析の作法(点数別に感性表現の係り受けを見る)
      など勉強になりました。Kaggleと違って日本語なのが読みやすかったですね。

    参考文献

    初めてのディープラーニング –オープンソース”Caffe”による演習付き
    SMOTE で不均衡データの分類