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

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をセンテンスに対して使って、平均値をとりそれを特徴量にしている
      • 全文を使わないほうが分類性能が良い可能性
      • 埋め込み層のデータで教師あり学習をして、それのスコアを用いるというアプローチ

    データサイエンティストがオブジェクト指向を学んでみた際のメモ〜scikit-learnの作法を知る

    はじめに

    エンジニアが作ったシステムの中で、データサイエンティストが開発する際に、オブジェクト指向プログラミングで書かれたソースコードに直面し、戸惑うかたも一定数いると思います。実際に私もその一人です。まだ完全に理解ができて、オブジェクト指向プログラミングができているわけではないですが、この記事を書くことを通じてより理解を深めていきたいと思います。

    今回お世話になる本はこちら(『オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識』)です。

    この本を読んで、みなさん大好きなscikit-learnのソースコードを眺めてみようと思います。

    オブジェクト指向とは

    オブジェクト指向とは、ソフトウェアの保守や再利用をしやすくする技術のことを指しています。
    個々のパーツに着目し、パーツの独立性を高め、それらを組み上げてシステム全体の機能を実現するという考え方に基づいています。

    オブジェクト指向プログラミングのキーワード

    参考にしている本によると、オブジェクト指向を理解する上での重大なキーワードとして以下の三つがあげられるようです。
    ・クラス
    ・ポリモーフィズム
    ・継承

    クラス

    クラスは同種のものの集まりを、インスタンスは具体的なモノを意味します。数学の集合論で言うところの集合、インスタンスは要素と例えられます。
    なお、インスタンスはクラスに属するので、クラスをまたぐことはできません。

    クラスの役割
    【サブルーチンと変数(インスタンス変数)をまとめる】
    メソッドの名前に関して違う名前をいちいち付けなくても済むようになる。
    .fit_logistic_regression、.predict_random_forest_regressionみたいな表現ではなく、.fitとか.predictだけで済むようにできます。

    【クラスの内部だけで使う変数やサブルーチン(メソッド)を隠したり公開する】
    変数をいろんなところで使えてしまうと、思いがけない挙動で困ることがあったり不具合の原因を特定することが困難になります。クラス内のメソッドにアクセスできる変数を限定することでそれを実現します。グローバル変数はプログラムの保守性悪化の元凶となるため避けることが推奨されています。また、変数はプライベート変数だとして、クラスやメソッド自体を様々なところから呼び出し可能にして書くことも可能です。

    【1つのクラスからインスタンスをたくさん作る】
    同時に様々な処理対象に対して、処理を行いたい場合は、クラスから複数のインスタンスを生成することでそれが実現できます。
    標準化のためのfit、教師あり機械学習モデルのfit、教師なし機械学習のためのfitなどクラスを複数複製してシンプルな書き方でそれらを実現することができます。
    ここで作られたインスタンス変数は、どこからでもアクセスできるわけではないという観点でグローバル変数とは異なり、特定のメソッド内でしか使えないわけではないという観点でローカル変数とも異なります。

    ポリモーフィズム

    類似したクラスに対するメソッドについて、共通にする仕組みのことをポリモーフィズムと呼びます。単語自体の訳としては「いろいろな形に変わる」という意味です。メソッドを使う側が楽をできる仕組みとされます。

    共通したメソッドを定める仕組みと理解してよさそうです。
    なお、ポリモーフィズムを利用するには呼び出されるメソッドの引数や戻り値の形式を統一する必要があります。
    また、入力がファイルだろうとネットワークだろうと問題なく動くように作る必要もあります。

    継承

    クラスの共通点と相違点を体系的に整理する仕組みのことで、全体の集合をスーパークラス、部分集合をサブクラスと呼びます。
    集合の話で言うと、
    動物はスーパークラス
    哺乳類、爬虫類、鳥類、魚類、両生類、昆虫類などはサブクラス
    という理解でよいです。
    共通の性質をスーパークラスに定義しておくと、サブクラスを楽に作成することができます。
    変数とメソッドをまとめた共通クラスを作り、別のクラスから丸ごとそれを拝借することで開発が楽になります。つまり、コードの重複を避けることができます。
    当然ながら、サブクラスはスーパークラスでのメソッドと同じ使い方になるように引数や返り値の型をスーパークラスのそれに合わせる必要があります。

    scikit-learnのGitHubを眺めてオブジェクト指向の観点で見てみる

    さて、オブジェクト指向で重要な概念を知ったところで、実際にscikit-learnのソースコードでそれらの概念を表しているものを眺めることでより一層の理解が深まると思います。
    そこで、https://github.com/scikit-learn/scikit-learnを眺めてみることとします。

    教師なし学習ではK-meansのソースコードとDBSCANについて見てみます。
    sklearn/cluster/_kmeans.py
    sklearn/cluster/_dbscan.py

    教師あり学習ではrandom forestとbaggingについて見てみます。
    sklearn/ensemble/_forest.py
    sklearn/ensemble/_bagging.py

    ソースコードの所感としては、手法に応じて関数(def)の記述がなされ、その後にクラス(class)の定義がなされています。手法ごとに異なるアルゴリズムの部分をこの関数部分で書き、クラス部分のメソッドに関して手法ごとでも共通になるようにしているのかなと思いました。クラスのメソッドの中に複雑な関数を書くよりかは、クラスの外に書いておこうということなのでしょうか。

    まずはK-meansのソースコードを見てみます。GitHubのリンクはsklearn/cluster/_kmeans.pyです。

    base.pyというファイルから以下のクラスを呼び出しており、クラスがクラスを呼び出している構図になっています。

    この中ではBaseEstimatorが最もメソッドの数が多く、推定量のパラメータを得たり設定したり、特徴量の数を確認したりいろいろできるようです。

    _get_param_names、get_params、set_params、__repr__、__getstate__、__setstate__、_more_tags、_get_tags、_check_n_features、_validate_data、_repr_html_、_repr_html_inner、_repr_mimebundle_

    確かに、これだけのメソッドをいちいち各手法ごとに書くのは骨が折れるので、クラスからクラスを呼び出すのはリーズナブルだなぁと思いました。

    さて、class KMeansの話に戻ります。メソッドとしては以下のものがあるようです。
    __init__、_check_params、_validate_center_shape、_check_test_data、_check_mkl_vcomp、_init_centroids、fit、fit_predict、fit_transform、transform、_transform、predict、score、_more_tags

    続いて、MiniBatchKMeansというクラスが現れますが、これは先ほど定義したKMeansを呼び出して使うため、base系のクラス→Kmeansクラス→MiniBatchKMeansクラスとより深い階層となります。

    このMiniBatchKMeansクラスでのメソッドは以下の通りですが、KMeansクラスを呼び出していることから、MiniBatchKMeansクラスかつKMeansクラスのメソッドが扱えるようになっています。
    __init__、_check_params、_mini_batch_convergence、_random_reassign、fit、partial_fit、predict、_more_tags

    続いて、DBSCANのソースコードを見てみます。GitHubのリンクはsklearn/cluster/_dbscan.pyです。

    ClusterMixinクラスとBaseEstimatorクラスを呼び出していますが、先ほど登場したので紹介はしません。
    DBSCANクラスのメソッドとしては、__init__、fit、fit_predictがあります。

    読み込んだクラスからメソッドを引き継いていることがわかります。

    続いて、random forestを見てみます。GitHubのリンクはsklearn/ensemble/_forest.pyです。

    これまでのクラスと同様にbase.pyやクラスを呼び出しています。一方で、BaseEnsembleはensemble/_base.pyのクラスとなっています。

    さて、BaseForestのメソッドですが、
    __init__、apply、decision_path、fit、_set_oob_score_and_attributes、_compute_oob_predictions、_validate_y_class_weight、_validate_X_predict、feature_importances_、n_features_となっております。

    以下、ForestClassifierとForestRegressorについて記しますが、教師なしのクラスと同じように、base系のクラス→BaseEnsembleクラス→BaseForestクラス→ForestClassifierクラスと深い階層になっているのがわかります。

    なお、ForestClassifierクラスのメソッドは以下の通りです。
    __init__、_get_oob_predictions、_set_oob_score_and_attributes、_validate_y_class_weight、predict、predict_proba、predict_log_proba、_more_tags

    ForestRegressorクラスのメソッドは以下の通りです。
    __init__、predict、_get_oob_predictions、_set_oob_score_and_attributes、_compute_partial_dependence_recursion、_more_tags

    これで終わりかと思いきや、

    などのクラスがありました。これまでのクラスを引き継ぎ、__init__の部分で手法の細かいところを変更しているようです。我々がscikit-learnで呼び出しているのはこれですね。

    最後にRandomTreesEmbeddingクラスがありました。教師なしで、スパースな行列を変換するためのもののようです。

    メソッドとしては、__init__、_set_oob_score_and_attributes、fit、fit_transform、transformがあります。

    当然ではありますが、教師ありのクラスのものとメソッドが違っているのがわかりますね。

    最後に、baggingを見てみます。GitHubはsklearn/ensemble/_bagging.pyです。

    RandomForestのものと同様に、BaseEnsembleクラスやABCMetaを呼び出していることがわかります。
    メソッドとしては以下の通りです。
    __init__、fit、_parallel_args、_fit、_set_oob_score、_validate_y、_get_estimators_indices、estimators_samples_、n_features_

    いよいよくどくなってきましたが、BaggingClassifierクラスで、これはこれまでのBaseBaggingを引き継ぎます。

    メソッドとしては、__init__、_validate_estimator、_set_oob_score、_validate_y、predict、predict_proba、predict_log_proba、decision_functionがあります。

    最後はBaggingRegressorです。これもbase系のクラス→BaseEnsembleクラス→BaseBaggingクラスと深い階層となっています。

    BaggingRegressorクラスのメソッドは__init__、predict、_validate_estimator、_set_oob_scoreです。

    ここで定義されるメソッドは少ないですが、実際に呼び出してみるとクラスを引き継ぐことで多くのメソッドを使えるようになっていることがわかります。

    以上から、scikit-learnにおいては、オブジェクト指向プログラミングが実践され、クラスを引き継ぐことで書くべきソースコードの量をできるだけ抑えながら多種多様なアルゴリズムが開発されているのだなと実感することができました。

    おわりに

    今回、オブジェクト指向プログラミングを少し学び、それがscikit-learnでどのように反映されているのかを確かめましたが、なかなか深い階層でクラスを呼び出しているものがあると思いました。理解をすればプログラミングは楽になりますが、初手で構造をしっかり理解しないと階層の深さに戸惑ってしまいますね。
    これが機械学習とかではなく、Web開発のコードとかだともっと深かったりするのでしょう。

    参考情報

    オブジェクト指向でなぜつくるのか 第3版 知っておきたいOOP、設計、アジャイル開発の基礎知識
    Get the Most out of scikit-learn with Object-Oriented Programming
    Pythonの抽象クラス(ABCmeta)を詳しく説明したい

    Flaskでイコちゃんペリー画像分類器の予測結果を返す

    はじめに

    先日の記事で作ったイコちゃんとペリー分類器ですが、今回は画像ファイルを送れば分類結果が返されるFlaskのAPIを作ってみようと思います。すごく簡単にできそうな記事を見つけたので、そこで紹介されていたコードを使います。

    前回のおさらい

    前回は、ペリーの画像27枚、イコちゃんの画像20枚を集めKerasでVGG16を使って分類器を作りました。テストデータもペリー9枚、イコちゃん7枚の計16枚と用意し、F1スコアは0.705くらいでした。画像を集めるのが面倒なのと、GPUを持っていないので更なる精度向上はいったん目指しておりません。

    Flaskとは

    FlaskとはWikipediaによると、「Python用の軽量なウェブアプリケーションフレームワークで、Djangoの次に人気がある。」とあります。学習済みモデルで推論の処理を受けつけ、その結果を返すということにしか関心がないデータサイエンティストとしては、ウェブアプリケーションフレームワークをわざわざ学びたいものではないですが、データサイエンス界隈ではしばしば見かけることから、学ばざるを得ないなと思います。
    Flaskには「処理を受け付け、結果を返す」というただそれだけの関心で向き合っていく次第です。
    公式ドキュメントはこちら(Welcome to Flask — Flask Documentation (2.0.x))になります。
    そういえば以前、「[第3版]Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)」という書籍でFlaskを用いたレコメンドAPIを時間制限のある無料のサーバ(PythonAnywhere)で実装したことはありましたが、CSSやHTMLを色々設定して面倒だなという印象がありあまり記憶に残っておりません(笑)。

    今回の処理

    この記事のソースコードはこの記事、「How to Build A Machine Learning API Using Flask」から使わせていただきました。ローカル環境で機能するAPIをFlaskで作るというものです。

    ざっくりとした処理の流れとしては、
    学習済みモデルの読み込みをした状態で、
    入力された画像を前処理し、
    推論を行い、その結果を返すというものです。

    ソースコード

    さて、学習済みの画像分類モデルで、画像を受け付けて推論し、結果を返すコードは以下の通りとなります。

    こちらのソースコードをapp.pyのファイル名で保存して、
    コンソール上で

    と実行すれば、FlaskのAPIサーバが立ち上がります。
    今回はローカル環境なので、ブラウザで
    http://0.0.0.0:5000/
    を表示すればサーバが起動しているのを見れます。
    さて、肝心の画像分類ですが、
    コンソール上で以下のようにcurlコマンドを叩けばローカルのサーバから推論結果が返ってきます。–formという引数で’file=@”/perry_image/test/ikochan_test_8.jpeg”‘みたいにローカルのファイル名を指定して実行する形となります。

    1なので、この画像はイコちゃん判定されました。過去の記事にもあるように、正解率は11/16くらいなので、69%と微妙ですけども。
    今回はローカルサーバですが、Webサーバ上で起動すれば、機械学習を用いたツール開発が実現できますね。
    なにより、思ったよりも短いコードで実現できてしまうことに驚きました。推論などの処理は基本的にPOSTのところに書く感じです。

    今後:本番運用に必要なことについて

    仕事で使うとなると、このコードを載せるサーバとかセキュリティ周りをどうするかというのが気になります。処理回数の制限とかIP制限とか認証キーとかどうするのか。
    URLが流出するかもしれないし、誰かがDOS攻撃とかしてくる人がいるかもしれないし。
    データ分析をするだけのご身分ではこういったことを考えることはないですが、データサイエンティストという職種に求められるスキルが少しずつ広がっていくのは面白いとも思えるので、粛々と向き合っていきたいです。

    最近、「Python FlaskによるWebアプリ開発入門 物体検知アプリ&機械学習APIの作り方」という書籍が出ていたので、ポチりました。本番で運用する観点でどういったリスクを潰しておくべきか、この本から学んで実装までいけるといいなと思います。

    参考情報

    [第3版]Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)
    How to Build A Machine Learning API Using Flask
    GETとPOSTの違いについて

    OpenCVで遊んだり、Kerasで「かものはしペリー」と「イコちゃん」の画像分類をするの巻

    はじめに

    正月は帰省もせずに暇だったので、普段の業務ではほとんど扱わない画像関連でブログを書いてみようと思います。
    まず、よくありそうなOpenCVの適用や、DNNを用いた画像分類などを行います。扱う画像は当然、かものはしペリーのぬいぐるみです。ブログのタイトルやドメイン名になっている通り、私はかものはしペリーの愛好家です。
    この記事の読者層は私で、いつか仕事で使うのをイメージして備忘録として残す感じです。
    説明があまりありませんが、気分次第で追記するかもしれません。あしからず。

    OpenCVで行うあれやこれや

    インストールする

    これで入ります。

    画像を読み込んでRGBにする

    明度値の書き換え

    量子化

    グレースケール

    画像ヒストグラム


    HSV変換について
    ・Hue:色の種類(例えば赤、青、黄色)
    ・Saturation:色の鮮やかさ。色の彩度の低下につれて、灰色さが顕著になり、くすんだ色が現れる。
    ・Brightness:色の明るさ。

    明度変換

    フィルタ処理

    特徴点検出

    画像の中から特徴的なポイントを抽出するアルゴリズム。

    マッチング

    特徴量抽出

    ・BFMatcher:Brute-Force matcher(総当たりで特徴点を比較している。類似度は数値が低いほど類似しているとみなす。)
    ・AKAZE:日本語の『風』から命名された手法。二つの画像のキーポイントを発見するために使われる。変化への耐性が強いとされる。非線形拡散方程式を近似的に解いて、非線形スケール空間の特徴量を検出している。

    これがベースとなるペリーの画像。

    以下では、このペリーとの類似度を計算している。

    画像分類

    ペリーとイコちゃんの画像からペリーかどうか判定したい。
    今回はペリーの画像27枚、イコちゃんの画像20枚を用意しました。

    今回はKerasにある、VGG16というモデルを使って分類を行います。ハイパーパラメータはAdamです。reluとかドロップアウト層とかは参考文献のまんまを使っています。

    ファイルの読み込みです。
    trainというディレクトリにperry_とかikochan_とかからなる画像ファイルがある想定です。

    画像からの学習用のデータの作成。

    学習の実行。


    テストデータにモデルを当てはめて推論し、精度をみます。今回はテストデータとして別に、ペリー9枚、イコちゃん7枚の計16枚の画像を用意しました。
    果たしてペリーとイコちゃんを識別することはできるのでしょうか。

    ・Accuracy:0.688
    ・Recall:0.857
    ・Precision:0.6
    ・F1:0.705

    どうなんでしょう。まずまずなんでしょうか。

    間違えたやつがどれか確認

    仕事で使う機会があるようなないような画像の世界ですが、計算資源が大事だなと思いますね。

    参考情報

    テキスト・画像・音声データ分析 (データサイエンス入門シリーズ)
    Display OpenCV Image in Jupyter Notebook.py
    Python でグレースケール(grayscale)化
    OpenCV で画像のヒストグラムを作成する方法
    HSV色空間
    色空間の変換
    画像フィルタリング
    OpenCV: 特徴点抽出とマッチング
    キーポイントとマッチの描画関数
    OpenCVのAKAZEで顔写真の類似度判定をやってみた
    総当たりマッチングの基礎
    OpenCV3でAKAZE特徴量を検出する
    KAZE Features
    小惑星画像の対応点決定を目的としたSIFTとAKAZEの性能比較
    線形・非線形拡散方程式の差分解法と解の可視化
    AI技術を魚種の画像分類に応用してみた!
    ベクトルの内積や行列の積を求めるnumpy.dot関数の使い方
    Python | Count of common elements in the lists
    [解決!Python]リストの内包表記と「if」を組み合わせるには
    Convert png to jpeg using Pillow
    ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type int) in Python
    Pythonで文字列のリスト(配列)の条件を満たす要素を抽出、置換
    ImportError: cannot import name ‘adam’ from ‘keras.optimizers’
    pandas.DataFrame
    Pythonでenumerateとzipを組み合わせて同時に使う

    各業界でのデータサイエンスの活用について調べてみた(随時追加)

    仕事で、いろんな会社でデータサイエンスってどう使われているのですか?と聞かれることがあり、自分としてはなんとなくしか掴めていないな、知ったかぶりしたくないなと思うところがあったので、やや手厚くリサーチをしてみようと思いました。

    2022/3/6の段階では11つの市場しかないですが、最終的には30市場を目指します。

    【2021/11/27追記】
    公開したところ、それなりにこの記事に関心を持ってくださった方が多かったようなので、少しずつ事例を埋めていこうと思います。

    業界別のページ内遷移

    自動車・同附属品製造業
    建設
    不動産
    医療(医薬品の卸)
    生命保険
    外食
    物流
    BtoC-EC
    電力
    電気通信
    スーパー

    業界別にデータサイエンスの事例を集めてみる

    ・業界としては、市場規模マップの上位30の市場としてみる

    事例の調べ方

    各業界の売上1~2位の企業名とデータサイエンス系キーワードを掛け合わせGoogle検索ないしGoogle Scholar検索を行う。

    • Google検索を自動で行う。
      • 「かものはし製パン 機械学習」
      • 「かものはし製パン 人工知能」
      • 「かものはし製パン データサイエンス」
    • 30業界2社の3つのキーワードごとの検索結果上位30位を取得
      • 計5400の検索結果から求人などを除外
      • 不要なものを除外したリストから目視で精査、まとめ

    検索自動化のソースコード

    一応、Google Scholarの検索自動化のためのPythonコードを置いておきます。クローリングのお作法などは「Pythonクローリング&スクレイピング[増補改訂版] -データ収集・解析のための実践開発ガイド-」のような本で身につけておくと分析関連業務で楽になります。

    総務省の白書に関してコメント

    日本企業におけるデータ活用の現状」という総務省が出している2020年3月のアンケートに基づいたレポートがあるのですが、なかなか良い統計が載っていて、日本全体の会社におけるデータ活用度をある程度掴むことができると思いました。

    どうやら大企業の半数近くは経営企画や製品企画、マーケティングにデータを活用していて、大企業の2割の企業で機械学習を用いたデータ活用を行なっており、大企業の5割の企業でデータ分析専門の部署があるようです。
    データ分析が、かなり社会に浸透しているのだなと思われました。
    そして、多くの企業の関心事がデータの質になってきているようです。データ分析で重要な観点にしっかり関心が高まっているのは良いことですね。

    業界ごとの取り組み

    以下では業界ごとに事例などをまとめていきます。結構長くなりそうです。

    自動車・同附属品製造業

    数理工学や群体数理、行動経済学など幅広い領域を研究対象としている。

    • シミュレーションを活用した制御ソフトの自動検証技術
      • サーチベーステスト(SBT):自律走行ロボットが充電ステーションへ帰還する際に、自己位置の推定に誤差が生じる課題を抱えていたが、SBTを用いることで推定誤差が生じる環境要件を特定してソフトの誤差80%減を実現していたりする。
    • 機械学習による性能テストの効率化
      • エンジンの燃焼に関するシミュレーションの実行時間の短縮を機械学習で行う。シミュレーションの効率化が積極的に行われている。
    • 歩行者保護性能の評価試験
      • ボンネットの設計効率化に向けて、CAE(computer-aided engineering)で構造解析を行う前に、ある程度の歩行者保護性能をAIで判定できるようにする取り組みが行われている。
    • Positive-confidence(Pconf)分類
      • アプローチとしては、正例の分布とその信頼度だけで、分類ミスによって生じる損失の期待値を最小化する手段。
      • ドライバーの心電情報から眠気を推定する際に用いた
    • 深層強化学習
      • 自動運転の際に、「ぶつからない」ことを学習する分散機械学習
    • 車内にカメラやマイク、脈拍センサーなどを置き、乗員の行動や会話、生体情報などを把握する開発
      • 自動運転車からデータを集めてAIで解析すると、人の行動や嗜好、健康状態、さらには感情まで推定
      • 感情エンジンを開発し、ドライバーの表情や声の調子からストレス状況を判断して安全運転をサポートしたり、ライフスタイルでの嗜好を学習して、状況に応じた選択肢を提案する。

    建設

    • スマートハウス
      • 既存のIoT機器やWebサービス、建物内に設置するデータ収集サーバを連携し、個々の機器・サービスを統合するシステムを構築し、家電の遠隔操作や省エネアドバイスなどの生活サービスをユーザーの好みに応じてカスタマイズできるシステムや、音声認識による機器操作、情報配信等のサービスにつなげる。温度センサとエアコンや電動窓を連動し真夏の寝苦しさを解消するなども。
      • HEMS(Home Energy Management System)の規格のもと、IoTデバイスを起動させるケースが多い。音声認識を用いたアプリケーションや気象や様々なセンサーを基にした家電の最適化などが扱われる。
    • 施設内の映像解析
      • 施設内に設置したカメラ映像から利用者のマスク着用や施設内カフェテリアの混雑度を自動で検知する実証実験を行っている。モニターでリアルタイムの映像を確認できるが、個人情報保護の観点から人物はシルエット表示されないとのこと。なお、実証実験で利用するカメラ映像は2カ月間保存・利用し、期間終了後に消去する。
    • マンションにおける電力供給システムの最適化
      • 家庭向けの発電設備の稼働を、過去の電力使用データなどから最適制御を行い、遠隔でコントロールする。生活リズムごとに家庭をクラスタリングしている。
    • 在宅健康モニタリング
      • 在宅健康モニタリングと早期発見システム(Early Detection System = EDS) の推進に特化したプログラムを構築のために大学と共同研究

    不動産

    • 不動産価格の算出のための機械学習システム
      • 所有マンションの推定成約価格を機械学習で算出して提示するシステムがWebサイトで提供されている。過去の制約事例のデータから予測している。
    • 賃料推定のための機械学習
      • 賃貸仲介データ等が少ない都心商業施設を対象に賃料を推定できるシステムが開発されている。
    • 間取りの検索システム
      • ユーザーに適した間取りの物件をレコメンドできるシステム。画像処理技術を間取りのデータに対して適用している。洋室や和室なども分類されている。

    医療(医薬品の卸)

    • 機械学習を用いた、工場における医薬品の物流最適化(医薬品の卸の会社)
      • 商品(医薬品)の保管・払い出し・仕分けなどの作業を自動化する、ピッキングロボットを開発し、人間の2〜5倍の作業量をこなしている。
    • 医薬品の出荷予測
      • 過去数年分の医薬品の出荷データをもとにGCPで機械学習を行い、余剰在庫や欠品リスクを回避させようとしている。
    • 医薬品の配送の最適化
      • 医薬品の販売、物流、商品、需要トレンドのデータを用いて機械学習を行い、注文数や配送発生確率、納品時の滞在時間を予測できるようにした。

    生命保険

    • 保障設計のレコメンドシステム
      • 保障設計予測モデルを構築し、顧客の意向に基づいて保障プランをレコメンドする。過去の大量なデータを用いて、保険において重視したい保障内容や保険料の予算をもとに、保障プランを自動生成。
    • 保険の保障見直しのためのレコメンドシステム
      • 未熟練な保険のプランナーの業務を支援するアプリケーション。年齢、性別、家族構成はもちろん、保険の保障設計書などのテキストも学習用データにしている。
    • Human in the loop
      • 機械学習システムは完璧なものではないので、人間の仕事を補助するなど、飛行機における管制システムのような存在として共存するという考え方。営業職員が多い生命保険会社では重要な観点。営業職員がベテラン層の営業職員と比肩するコンサルティングをより適切なタイミングで実施しやすくするリコメンド機能などがそれにあたる。
      • 最適な提案のタイミング、最適な活動レコメンド、最適な教材・資料探しなど、営業活動の支援のための分析に取り組む事例がそれなりになる。最適な顧客訪問、最適なメッセージなどを見つける。
    • 入院日数予測モデル
      • 保険加入時の健康状態(告知事項や健診結果など)と保険給付実績を分析し、加入時の健康状態から将来の生活習慣病における入院日数を予測するモデルを開発。このモデルを用いてリスクを評価できるようになり、これまで引き受けれなかった顧客からの申し込みを引き受けることが可能になった。
    • 営業の教育支援ツール
      • AIを相手にしたロールプレイング演習などを行い、新人の育成を支援するツールなどが作られている。
    • 保険の引き受け査定の自動化
      • 健康診断結果報告書や人間ドック成績表をもとに、OCRでデータを抽出し、それらのデータをもとに機械学習を用いて自動での医務査定を行えるように訓練。これまで2〜3日かかっていた査定業務が3分以内に完了するように。

      外食

      • 配送員向けアプリ
        • 機械学習を用いて、ベテラン配達員のデータから学習し、配送員にとって効率の良いルートを提案するアプリ。
      • 機械学習を用いたクーポン配布
        • 顧客ごとの来店確率を計算し、その確率が上位の顧客にクーポンを送付するという施策を試験的に展開している。コンバージョンレートが通常の3倍になったケースもあるとのこと。天候や気温などのデータとも連動しているとのこと。
      • 注文の需要予測
        • 過去の注文履歴を分析し、宅配需要を10分単位で予測したり、配達ルートの最適化を行う取り組み。フードロスを減らすこともモチベーションとしてある。
      • レコメンドとしてのデジタルメニュー
        • 顧客の登録情報や来店時刻や立地ないし季節・天候に応じて、客ごとにメニューが変わるようなレコメンデーションを試験導入しているとのこと。

        物流

        • 強化学習を用いた船舶の航路の最適化
          • 膨大な数の航海シミュレーションを通して、徐々に最適な避航行動を学習し、様々な状況下で安全性と経済性に優れた避航操船行動を選択できるプログラムの開発などが進められている。航路作成は人間だと3時間かかるらしい。
        • 画像解析による船舶の見張り支援システム(衝突回避のため)
          • 船上で撮影された映像に対して、サーバー上で画像を解析し機械学習を実施後、その物体との距離を求めてから、遠隔で船上ソフトウェアを更新することで、利用しながら認識率等の性能が向上する仕組み。
        • 船体の異常検知の自動化
          • IoTで航海データ・機関データを取得し、船舶の運航管理者が船舶の異常を検知できるように機械学習の導入を進めている。これまでは人間が24時間体制で管理していた。
        • 業務量の予測
          • 宅急便の拠点における、数ヶ月先の業務量を予測するため、機械学習モデルを毎月アップデートし、需要に応じた効率的な経営資源の最適配置とコスト適正化を推進することを目指している。
        • 作業員の業務日報のOCR
          • 紙の作業日報の情報のシステム入力を自動化するために、機械学習を用いたOCR技術を適用している。

        BtoC-EC

        • 商品の非構造化データを構造化データにする、あるいは商品情報の自動生成、自動判別
          • 機械学習(CNN、RNN)や自然言語処理をもちいて、商品から情報を抽出したり、レビューを分析したり、商品のカテゴリを分類したりしている。商品の画像のデータからカテゴリを予測するなども行われている。
          • 出品時に登録した商品の写真画像から、商品の内容などの入力候補を提示する機能などが開発されている。ディープラーニングとk近傍法などを組み合わせた事例がある。
        • 潜在的に購買する可能性があるユーザーの推定
          • 機械学習を用いて金融サービスを使って購買をしそうなユーザーを分類するモデルを作成し、予測スコアが一定以上のユーザーに介入するなどを行っている。
          • 機械学習を用いた独自のアルゴリズムで消費行動を解析することで、購買の見込みがあるユーザーを抽出するなどし、商品の広告配信に活かしている。
        • 動画コンテンツの翻訳
          • アテンションの伴ったRNNでの機械学習を行い、中国語を英語に変換している。
        • 商品推薦システム・パーソナライズドクーポンアルゴリズム
          • 商品データ、購買履歴データ、閲覧履歴データを対象とし、古典的な相関ルール抽出、あるいはMatrix Factorizationを適用させたり、商品やユーザなどを固定長のVector に変換して距離を計算するEmbeddingなども行い、RNNなどの深層学習アルゴリズムを適用している。
        • チャットボットによるサービス利便性の向上
          • ユーザーが知りたい問い合わせの多くにチャットボットが回答している。FAQを情報源としてNLPなどを用いてその中から一番近い答えを返している。
        • 多椀バンディットアルゴリズムを用いたABテストの最適化
          • T.B.A
        • 在庫数の最適化のための商品需要予測
          • T.B.A
        • 異常検知
          • T.B.A
        • 商品価格の推定
          • 出品された商品に対して、Factorization Machinesというレコメンドシステムでよく利用される手法の一種であるDeepFMを用いた価格の予測が行われている。機能によっては端末のアプリ側で計算を行うことから、エッジコンピューティングのためのモデル軽量化なども進められている。
        • 不正検知
          • 違反出品検知システムとして、Human-in-the-Loopを実践。人間が介入するため、判定するべき対象とその他との境界に位置するデータに対してのアノテーションを継続的に入手している。アルゴリズムとしてはDNNを用いている。

        電力

        • メッシュ単位での電力需要予測
          • メッシュ単位での気象予測データを活用して電力需要の予測精度を高めるように、スパースモデリングやアンサンブル学習の機械学習技術が使われている。解釈可能性も重視されるので、一般化加法モデルなども利用されている。なお、電力需要量は、カレンダー条件(時間帯,曜日など)と気温や日射強度などの気象条件からおおむね推定できるとされている。機械学習系の手法もあれば、周期性に着目し、状態空間モデルで予測する事例もある。
        • 機械学習による石炭火力発電所における燃焼調整の体系化
          • 運転データやオペレーションとメンテナンス(O&M)の知識をもとに、設備の燃焼効率最適化を機械学習で行う。
        • 機械学習を用いたダム操作最適化システム
          • ニューラルネットワークを利用したダム操作最適化システムの研究がされている。雨量予測、河川流量予測、ダム操作最適化の三つの領域での最適化がなされている。最適化操作のために強化学習も採用されている。学習期間の報酬を最大化するようにネットワークの重みを修正している。
        • 異常検知
          • ヘリコプターやドローンなどで撮影した送電線の動画データを基に、軽微な損傷や異物の付着といった異常を見つけ出すために深層学習が使われている。誤判定のチェックに多少の人手をかけても、十分な業務時間の短縮効果を得られるとのこと。
          • 工場設備の温度変化のデータを画像化して、CNNで特徴量を作り、不具合や異常の分析を行うなどしている。
        • 太陽光の発電量予測
          • T.B.A
          • T.B.A
        • 大量のデータを駆使しての設備の劣化予測診断
          • 高クロム鋼配管溶接部のクリープ損傷評価を深層学習(AlexNet)やサポートベクターマシンを用いて行っている。学習用のデータが少ないことから、転移学習も行っている。
          • T.B.A
        • 燃料プロセスの最適化
          • ボイラ燃焼調整の最適化等
          • 熟練技術者が半日程度かけてつくっている燃料の運用計画を数分で行えるように数理最適化などの取り組みがされている。
        • 生活リズムの変化を察知
          • スマートメーターにある電気使用量の時系列変化を捉えて、独居している人の異常を親族に通知する仕組みを構築している。
          • 高齢者を介護する負担を減らすための実証研究などが進められている。
        • 電力の需要予測
          • 特徴量としては、カレンダー情報・気象情報それらを組み合わせた相互作用項で、重回帰モデルと一般化加法モデルに対してアンサンブル手法を適用している。
          • k-nearest neighborでの距離的な離れ具合でもって、異常な需要を当てるなどの取り組みがされている。それと重回帰ベースのモデルとを合わせて予測している。

        電気通信

        • 機械学習モデルの公平性
          • 人を対象とした意思決定に関する過去の履歴(訓練データ)と、矢印(因果グラフ)によって「どんな予測が不公平か」に関する事前知識を表現したものを入力として受け取り、公平な予測を行う機械学習モデルを出力している。
        • 深層学習モデル
          • どのような条件で取得されたデータであるかがまったくわからない寄せ集めの学習データからであっても、認識モデルを学習可能な深層学習技術を実現。Data Augmentationの適用をした模様。
        • 料金未納などの連絡Bot
          • 「AI電話サービス」が対象者に対し、本人確認、支払い意思、支払日などを確認し、確認結果をCSVにて出力。電話に出ない債権者は自動で再架電話リストとして登録し、再度架電を行うとのこと。
        • 音声のノイズに関する分析
          • ロボットが受け取る人間の音声に関して、構成する音の雑音のカテゴリを機械学習で分類するという取り組みが行われている。メル周波数ケプストラム係数(MFCC)を用いて、それを元に機械学習アルゴリズムとしてDNNやSVMなどを試している。
        • 通信障害の異常検知
          • 既存の監視システムでは検知できないような通信障害を検知するために、SNSなどの情報をもとに、そのSNSの情報に機械学習を用いて分類を行い、通信に異常があるかどうかを判定する研究がなされている。アルゴリズムとしてはSVMが使われている。
        • 圧縮化技術
          • 電波の到来方向を高速で検知するために、それらに関連する情報圧縮のためにニューラルネットワークなどの機械学習を適用している。

        スーパー

        • 需要予測・発注最適化・在庫管理最適化
          • 食パン、牛乳、豆腐、冷凍食品などのデイリー品を中心に需要予測の実証実験とあり、発注にかかる時間を1/3ほど短縮できたとある。アプローチとしては機械学習に解釈可能性を持たせたものらしい。人の発注業務を支援するという観点から予測性能だけでなく、解釈可能性も大事なのだろう。
        • ATMへの機械学習の実装
          • スーパーの店内にある、各ATMの入出金予測を行っている。ここでも機械学習の解釈可能性を大事にしており、どれくらい現金を保持しておくかを人間が決めるのを支援する仕組みのようです。ちなみに、現金の補充は警備会社が行っているらしい。
        • 店内カメラの解析
          • 店舗によっては数百のカメラで解析しているらしい。売り場への立ち寄り時間などを分析して、店内レイアウトの改善に使ったり、店員の所持するアプリに困っていそうなお客さんを検知して通知を飛ばすなども行っている。また、混雑の検知などにも使われたり、映像から年齢を推定し、未成年への酒類販売を未然に防ぐなどにも活用しようとしているらしい。
        • 配送ルートの最適化
          • 運転手の割り振りや受取場所、時間を最適化するほか、注文時間などに応じて宅配料金が変動する仕組みも試しているとのこと。
        • 割引率の最適化
          • 販売実績や天候・客数などの環境条件を学習し、時間帯ごとに各商品の陳列量に応じて適切な割引率を提示するツールの開発もなされている。

        今さら”Recommendations as Treatments: Debiasing Learning and Evaluation”を読みソースコードを眺めるなど

        はじめに

        最近、『施策デザインのための機械学習入門〜データ分析技術のビジネス活用における正しい考え方』が流行っていると思いますが、私も少しずつ読んでいます。

        2019年ごろから勉強会などで知る機会のあったCountefactual Machine Learningですが、仕事で機械学習を使えば使うほどにその必要性を強く感じます。
        書籍は体系的にまとまっていて非常に良いのですが、せっかく関心を持ったのでその源流と思われる論文やソースコードを漁ってみようと思いました。

        今回、深ぼるのはこちらの論文です。
        Recommendations as Treatments: Debiasing Learning and Evaluation
        https://arxiv.org/abs/1602.05352

        情報を漁る

        arXivの方はAppendixついてなかったのでこちらの方がいいと思います。
        https://www.cs.cornell.edu/people/tj/publications/schnabel_etal_16b.pdf

        著者のスライドもありました。
        https://www.cs.cornell.edu/~schnabts/downloads/slides/schnabel2016mnar.pdf

        まずは読む

        以下に読んだ際のメモを箇条書きします。

        • レコメンドのデータは大体偏っている。偏ってアイテムの評価がされる。
        • レコメンドに因果推論のアプローチを適用する。
        • 傾向スコア(ランダムっぽさ)を用いた学習の重み付け
        • バイアスの最小化?のアプローチ
        • 行列分解による欠損値補完に対する重み付けをした。
        • 色々なデータで試した。
        • IPS(Inverse Propensity Score)で重み付けしたら誤差の不偏推定量を手に入れれる。
        • 評価方法はMAE(Mean Absolute Error)とかDCG(Discounted Cumulative Gain)など
        • 比較は一様に評価のデータが観察されると仮定したナイーブなモデルとで行う。
        • 行列分解の次元数dとか、正則化項のラムダはハイパーパラメータとして扱う。
        • 行列分解かつIPSで重みづけしたモデルはロバストに良い性能になった。

        既出の参考資料を読む

        ソースコード読む

        コーネル大学のサイトに論文のソースコードがあったので、そちらの解読を試みます。
        https://www.cs.cornell.edu/~schnabts/mnar/

        そんなにソースコードは多くなかったです。

        train.sh

        学習のバッチ処理

        train.py

        python ../bin/train.py –lambdas 0.008,25 –numdims 40 –ratings data/train.ascii –propensities data/propensities.ascii

        • コマンドライン引数たち
          • lambda:正則化パラメータ。デフォルトは’0.008,0.04,0.2,1,5,25,125′
          • numdims:行列分解の次元数。デフォルトは’5,10,20,40′
          • ratings:訓練用データの指定を行う(ASCII formatの行列)
          • propensities:傾向スコアのデータの指定を行う(ASCII formatの行列)
          • metric:デフォルトは’MSE’、MAEかMSEを選べる

        MetricsのMSE/MAE関数を呼び出し、
        Expt3のlearn関数を使って学習を実行する。

        Metrics.py

        • MSE関数
          • ITEMWISE_METRICSを呼び出している
        • MAE関数
          • ITEMWISE_METRICSを呼び出している
        • ITEMWISE_METRICS関数
          • MSEかMAEかでnumpyのデータの形式を指定している。
          • SET_PROPENSITIES関数を呼び出している
          • 観測された評価と予測した評価の差分にIPWを掛け、観測誤差とする
          • 累積の観測誤差を出す
          • IPWの合計値で累積の観測誤差を割ったglobalNormalizerを計算して返す
          • ユーザー単位での観測誤差の推定値をユーザー数で割ったuserNormalizedMetricを計算して返す
          • アイテム単位での観測誤差の推定値をアイテム数で割ったitemNormalizedMetricを計算して返す
        • SET_PROPENSITIES関数
          • IPWがあればそれを使い、ない場合は出現割合を返している
          • 観察されたデータを考慮して補間を行う(numpy.ma.arrayのmask)

        Expt3.py

        Expt2のINIT_PARAMS、MF_TRAIN、FINAL_TRAINを実行する
        MFのPREDICTED_SCORESを実行する

        • 処理の流れ
          • もろもろの引数で学習の際の設定を受け取り
          • 傾向スコアの逆数からIPWを計算し
          • そのスコアを学習用データで補間し
          • ランダムに並び替える
          • 4-foldsでのクロスバリデーションを行う
          • 学習を並列処理を行う
          • 予測スコアから一番いいスコアのモデルを選ぶ
          • 行列分解での機械学習を行う
          • 行列分解での予測値を計算する
          • 予測結果を返す

        Expt2.py

        MFのGENERATE_MATRIX、PREDICTED_SCORESを実行

        • MF_TRAIN関数
          • IPWを受け取って、上限下限などを調整
          • それをMFのGENERATE_MATRIX関数に適用
        • FINAL_TRAIN関数
          • MF_TRAIN関数と似たような処理
          • 交差検証してベストだったパラメータに適用する想定
        • INIT_PARAMS関数
          • 評価行列の欠損値を補間している
          • 行列特異値分解を行っている
          • その結果をstartTuple(初期値)として与えている

        MF.py

        • PREDICTED_SCORES関数
          • バイアスがあるかどうかで分岐
          • バイアスがあれば、元のスコアにユーザーのバイアス、アイテムのバイアス、グローバルなバイアスを足し合わせる
          • バイアスがなければそのまま返す
        • GENERATE_MATRIX関数
          • 指標がMSEかMAEかで分岐
          • MetricsのSET_PROPENSITIES関数を実行
          • ユーザー単位での標準化やアイテム単位での標準化、全体での標準化のための計算をする
          • 標準化の方法で分岐、傾向スコアを標準化する
          • バイアスのモードで分岐
          • 学習のための初期値としてのデータを設定
          • 目的関数の最適化(最小化)を行う
          • その結果を返す
        • Mat2Vec関数
          • 行列をパラメータのベクトルにする
        • Vec2Mat関数
          • パラメータベクトルを入力する
          • ユーザーベクトル、アイテムベクトル、ユーザーバイアス、アイテムバイアス、グルーバルバイアスを返す

        test.sh

        テストのバッチ処理

        test.py

        python ../bin/test.py –test data/test.ascii –completed completed_ratings.ascii

        • コマンドライン引数たち
          • test:テスト用の評価データを指定する(ASCII formatの行列)
          • completed:評価を埋めたい行列のファイル名を指定

        MSEやらMAEの結果を返す。

        所感

        まず論文の内容ですが、大体のビジネスデータはRCTな状況で生み出されたものではないので、偏って観測されるのは当然ですが、その結果としてレコメンドのアルゴリズムの性能が落ちてしまうということが論文に記されていました。性能を落とさないためにも、傾向スコアを用いた重み付けによる機械学習が大事に思いました。ただ、傾向スコアの推定自体の精度も大事に思われるので、銀の弾丸ではないですが、バイアスから抜け出るヒントをいただけたという気持ちです。
        そして、思ったよりもソースコードが長いと思ったのと、普段あまり使わないNumpyの関数を知ることができたのもよかったです。
        理論の理解だけでなく、それを実現するためのソースコードを眺めるのも大事ですね。今後も論文をただ読むだけでなくソースコードの海に飛び込んでみようと思います。

        参考リンク

        numpy.reciprocal
        maskedarray.generic
        numpy.ma.getmask
        numpy.clip
        scipy.sparse.linalg.svds
        numpy.ma.filled
        scipy.optimize.minimize

        警察庁オープンデータの前処理と死亡事故発生予測のための機械学習について

        はじめに

        先日、近所の幹線道路の信号付き横断歩道を横断しようとした際に、2メートルほど先で回避不能な速度で車が赤信号を無視して横断歩道を突っ切きるという非常に恐ろしいイベントに遭遇しました。
        そこで、私は「このイベント、何回かあったら死亡事故が起きるぞ」と思いました。警察署に近隣道路の不満について電話をしてみたのですが、「警察もちゃんと考えて取り締まっていたり対策してますので」と言われ、何の成果も獲れない電話となりました。
        そのようなモヤモヤの中、私は民間でできることは「客観的なデータでもって、エリア、曜日、天候、時間帯ごとの、死亡事故のリスクを見積もり、それを公開して注意喚起していくこと」なのではないかと思うに至りました。
        よって、警察庁が公開している交通事故のオープンデータについて、その前処理と機械学習によるエリアの死亡事故の発生予測などについて記していきます。

        前処理のためのデータやコードはこちらのGitHubにあります。
        https://github.com/KamonohashiPerry/traffic_accident_analysis
        スターを10個以上いただけて、データ作って良かったなと思いました。

        目次

        ・データについて
        ・先行研究について
        ・前処理について
        ・EDAからわかること
        ・機械学習
        ・さいごに

        データについて

        2019年と2020年の交通事故に関するデータが警察庁よりオープンデータとして公開されています。
        オープンデータ 2020年(令和2年)
        オープンデータ 2019年(平成31年/令和元年)

        どのようなデータかというと、
        それぞれ2019年と2020年の間に発生した全国の事故について、発生した状況(時、場所、天候)やその結果に関するデータからなり、項目の数としては58個とオープンデータとしてはかなり豊富な情報量となっています。

        データは本票、補充票、高速票の3つからなるのですが、今回は本票だけを用います。
        高速道路の精緻な分析をしようと思うと、高速票を繋ぐ必要がありますが、私の目的は一般道にあるので、繋がないものとします。

        先行研究について

        事故の予測に関する先行研究

        交通事故の分析に関する研究は以下のものがあり、参考にしました。
        死亡事故を予測するという問題設定として、その特徴量としては場所、時間帯、曜日、場所かつ時間、場所かつ曜日かつ時間、天候、季節、風速・風向き、車線の数、歩道の有無、制限速度などを用いていることがわかりました。
        そして、データをクラスタリングするためにDBSCANを用いたり、不均衡データであることから、アンダーサンプリングを行ったりしているようです。
        最後に、アルゴリズムはSVMやロジスティック回帰、深層学習と色々と使われているようです。

        ・Live Prediction of Traffic Accident Risks Using Machine Learning and Google Maps

        ・Data-Driven Urban TrafficAccidentAnalysis and Prediction Using
        Logit and Machine Learning-Based Pattern Recognition Models

        ・A Deep Learning Approach for Detecting Traffic
        Accidents from Social Media Data

        ・A BASIC STUDY ON TRAFFIC ACCIDENT DATA ANALYSIS USING
        SUPPORT VECTOR MACHINE

        ・Predicting Crash Injury Severity with Machine Learning Algorithm Synergized with Clustering Technique: A Promising Protocol

        ・Comparison Analysis of Tree Based and Ensembled Regression Algorithms for Traffic
        Accident Severity Prediction

        その他

        ・Taxi Demand Prediction System

        ・2019年04月号トピックス 警察庁のオープンデータを活用した独自AIによる犯罪発生予測

        前処理について

        ソースコードに関しては、GitHubに上げておりますので、
        .pyなら
        https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/src/preprocess.py
        https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/src/preprocess_second.py

        .ipynbなら
        https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/Traffic_Accident_Analysis.ipynb
        を参照ください。

        基本方針

        ・天候、時間帯、曜日、平日、道路の形状、スピード制限など、事故の結果(死亡の有無)を明らかに予測できそうなもの以外を特徴量にします。
        ・メッシュ単位での過去の事故に関する情報に関する特徴量の作成(学習を行う時点よりも過去の時点のデータのみ利用)

        詳細

        ・事故の発生日時のdatetime化(列で年・月・日・時・分が分かれているため)
        ・マスタ情報(PDF)をもとにマスタのIDを名前に変換
        ・緯度経度のデータについて、度分秒から度への変換を行い、3次メッシュ(1km四方)のデータを作成
        ・メッシュ単位での特徴量として、過去の事故発生件数、死亡数などを集計
        ・メッシュ単位での特徴量として、過去に発生した事故に関するもろもろのデータの集計(そのメッシュで事故を起こした平均年齢や事故が発生してきた時間帯など)
        ・もろもろの変数のダミー変数化

        EDAからわかること

        EDAに関しては.ipynbのみで行っております。
        https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/Traffic_Accident_Analysis.ipynb

        私がよく分析で使うのは、データの該当件数とカテゴリごとの率の可視化なのですが、以下の図の見方としては、青の棒グラフが各カテゴリの件数、赤の折れ線グラフが死亡率となっています。

        都道府県


        福井県、鳥取県、秋田県、島根県、岩手県などは死亡率が高そうです。

        道路種別


        農道(815件)や林道(88件)で起きる事故非常に死亡率が高くなるようです。

        時間帯


        夜間や明け方は死亡率が高くなるようです。

        天候


        霧の天候(294件)では死亡率が高くなるようです。

        人口密集地かどうか


        市街地ではないところでは死亡率が高くなるようです。

        道路の形状


        踏切-第一種(254件)はかなり死亡率が高くなるようです。カーブも死亡率が高くなります。そういえば実家の近くにも魔のカーブと呼ばれるところはありますし、事故も起きていました。

        信号機のタイプ


        点滅-3灯式(2566件)や点灯-押ボタン式(7703件)は死亡率が高いようです。

        道路の幅


        大きな交差点では死亡率が高い傾向にあります。単路に関しては一様な傾向ではないですが、小さい方が死亡率が高そうです。

        道路の区切り


        道路の区切りがペイントだけのケースは、中央分離帯がある場合よりも死亡率が高い傾向にあります。あと、中央線がポストコーン(チンアナゴみたいなやつ)だと死亡率が上がるようです。

        歩道との区別


        道路について歩道との区分がない場合に死亡率が高くなるようです。

        速度制限


        速度域が高くなるにつれ、死亡率が高くなるようです。あと、速度規制がされていないところも高くなっています。

        曜日


        土日の死亡率が高い。

        祝日・その前日


        祝日とその前日の死亡率は高い傾向にある。

        以上のことから、得られた考察としては、
        ・土日や祝前日の道路はいつもより危ない
        ・夜間や明け方の道路は危ない
        ・制限速度の高い道路は危ない
        ・大きな交差点は危ない
        ・点滅信号は危ない
        ・カーブは危ない
        ・霧は危ない
        でした。普段、出歩く際に意識しておくといいと思います。

        機械学習

        教師データを事故発生からの死亡有無(1or0)、特徴量を先行研究を参考にオープンデータから作れるものとして、
        基本的には、LightGBMでの学習、ハイパーパラメータ探索、モデルの訓練(メッシュ番号でグループ化したクロスバリデーション)、テストデータ(学習は2020年11月まで、テストは2020年12月以降としている)での予測、日本地図への可視化を行っています。

        ソースコードはGitHubに上げてあるので、ここでは記しません。

        .pyなら(学習のみ)
        https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/src/train_model.py

        .ipynbなら(学習だけでなく、予測と日本地図への可視化もしている)
        https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/Traffic_Accident_Analysis.ipynb

        10-foldのCVをメッシュ番号でグループ化して学習させた際のAUCです。高い部類に入りますが、今回は不均衡データなので、抜群に当たっている感じではないです。


        事故の死亡率は、0.9%なので、この予測の場合、2.2%が死亡すると当てれているということになります。また、予測から、全体の72%の死亡事故を当てているという結果です。
        この性能に関しては今後、もっと高めていく余地はいくらでもあると思います。

        こちらは、テストデータでの予測スコアの階級値(青い棒グラフ)と実際の死亡率(赤い線グラフ)を示したものです。スコアが高いものは信じてもいいかなぁと思いました。

        特徴量重要度の上位10件は以下の通りです。

        時間帯とか、防護策とか、信号機のタイプとか、市街地かどうかなどが予測に役立っているようです。

        死亡事故発生を予測した確率を日本地図の関東エリアにプロットしたものが以下の図になります。

        市街地のほうが死亡事故が起きやすいように見えますね。

        東京都だけに絞ってみましたが、危険なエリアは都心に点在はしていますが、郊外のほうが死亡率が高そうです。

        さいごに

        交通事故にあいかけて、その怒りの感情を警察庁のデータにぶつけてみましたが、死亡事故が起きやすい条件などがある程度見えてきたと思いました。もちろん、なんとなく思っていた傾向もあったのですが、数字でハッキリと出せるのは良いですね。今後、旅行などをする際に、確率の高いエリアを警戒して行動するようにしたいです。
        そして、地図への可視化は普段の仕事でほとんど行わないのですが、こうしてデータに触れて可視化の練習ができたのも有意義に思いました。
        この警察庁のデータは分析するまでに工数がかかるデータとも言えるので、この記事をとっかかりとして、オープンデータの分析に挑戦して安全な生活を送る上での知見をシェアしていけると良いな、というか民間としてはこれくらいしかできないなと思っています。

        参考情報

        ・[第3版]Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)
        ・Pythonでプロットした地図を出力する
        ・Pythonで度と度分秒を相互に変換する

        Recommender Systems: The Textbookの要点まとめ(随時更新)

        はじめに

        レコメンド関連の書籍を探していた際に、
        Recommender Systems: The Textbook (English Edition)の無料公開されているPDFを見つけたので、それについて読んでは追記するスタイルでメモを残していこうと思います。(すごく長くなる予感)

        これまで読んできたレコメンド関連の本の中では、説明が丁寧だったり事例が豊富に思います。数式はあまり出てこないですが、言葉でちゃんと説明しようとしているのが感じられます。『AIアルゴリズムマーケティング 自動化のための機械学習/経済モデル、ベストプラクティス、アーキテクチャ (impress top gear)』のレコメンドの章もわかりやすく幅広いトピックが扱われていますが、それに匹敵する本にも思います。

        第1章(An Introduction to Recommender Systems)

        Goals of Recommender Systems

        • 1.ユーザーとアイテムの組み合わせの評価値の予測問題
          過去のユーザーのプリファレンスデータを使って学習する。未知のアイテムに関しては行列補完問題とも見なせる。
        • 2.上位k個の推薦問題
          あるアイテムに対して、あるユーザーの上位k個のアイテムを推薦する。

        推薦システムの第一の目的はプロダクトの売上向上。

        • 推薦システムの運営上ないし技術的な目的
          1.関連性(Relevance)
          2.新規性(Novelty)
          3.意外性(Serendipity)
          4.推薦の多様性(Diversity)
        • 推薦システムの例
          1.GroupLensの推薦
          2.Amazon.comの推薦
          3.Netflixの映画推薦
          4.Googleニュース推薦
          5.Facebookの友達推薦

        Basic Models of Recommender Systems

        • 協調フィルタリング(Collaborative Filtering)
          1.メモリーベース
          ・ユーザーベース協調フィルタリング
          ・アイテムベース協調フィルタリング
          2.モデルベース
        • コンテンツベース(Content-Based)
        • ナレッジベース(Knowledge-Based)
          滅多に買われないようなアイテム(自動車、不動産)の際に考える。評価は使わない。その代わり、ユーザーの要望とアイテムの近さや、ユーザーの制約などを用いる。
          1.制約ベースの推薦システム
          2.条件ベースの推薦システム
        • デモグラフィック(Demographic)
        • ハイブリッド、アンサンブルベース(Hybrid and Ensemble-Based)
        • 評価の種類
        • 明示的な評価と暗黙的な評価
        • 欠損値分析との関係性

        Domain-Specific Challenges in Recommender System

        • コンテキストベース(Context-Based)
          時間や場所、ソーシャルデータを使う。季節性を考慮したりする。
        • 時間依存(Time-Sensitive)
          1.時間と共に評価は変わる。流行りすたりがある。
          2.特定の時期だけ、特定のアイテムの評価があがることはある。(レインコート、ダウン)
        • 位置情報(Location-Based)
        • ソーシャル(Social Recommender System)
          ネットワーク構造やソーシャルでの繋がり、タグ、組み合わせに基づいている。

        Advanced Topics and Applications

        • コールドスタート問題(Cold-Start Problem)
        • 攻撃耐性(Attack-Resistant)
          アルゴリズムをハックされると情報推薦の効率性が阻害される。本来、上がってくるべきものが上がらないので。
        • 集団への影響(Group)
          推薦アルゴリズムは個々人よりも集団のプリファレンスに影響を与える。
        • 複数の基準(Multi-Criteria)
          ユーザーは単一の基準でアイテムを評価はしない。
        • アクティブラーニング(Active Learning)
          ユーザーが評価をしやすいようにするための取り組み、たくさん過去に評価したユーザーがいた場合は、新しい映画に関して評価をしやすいように予測するとか色々。
        • プライバシー(Privacy)
        • 様々な適用領域
          小売、音楽、コンテンツ、web検索、クエリ、デジタル広告

        第2章

        TBD

        第3章

        TBD

        第4章

        TBD

        第5章(Knowledge-Based Recommender Systems)

        • コンテンツベースは新しいアイテムの推薦には良いが、新しいユーザーには推薦できない。協調フィルタリングやコンテンツベースは過去の履歴といったデータをベースに扱うが、ナレッジベースはユーザーが何を求めているのかに基づいている。
        • 不動産や自動車、旅行商品などは滅多に購入しないため、評価のデータは十分に得ることができない。
        • 映画はレコメンドされた際に、その理由が明示されなくとも受け入れるが、不動産や自動車は詳細な情報抜きには、そのレコメンドを受け入れることは難しい。
        • ナレッジベースのレコメンドが有効なケース
          1.ユーザーの要望が明確なケース。協調フィルタリングやコンテンツベースでは満たせない。
          2.選択肢が幅広く商品の複雑さが大きい商品のケース。詳細な評価を得にくい。
          3.商品の評価が時間と共に大きく変わるケース。パソコンとか車はすぐ新しいものが出てきたりして評価が変わってしまう。
        • ナレッジベースのレコメンドにおけるユーザーとのコミュニケーション
          1.対話システム
          対話でのフィードバックループのコンテキストからユーザーのプリファレンスを把握する。
          2.検索ベースシステム
          質問に答えることでプリファレンスを把握していく。
          3.ナビゲーションベース
          ユーザーがアイテムに対して反応をしてしていき、その結果に応じて望んでいるアイテムに到達できる。

        Constraint-Based Recommender Systems

        • アイテムの属性に関する強い要望や制約を識別する。
        • 制約ベースのレコメンドシステムにおける3つのインプット
          1.ユーザー固有の情報(デモグラ、リスク嗜好)、必須要件(バストイレ別とか)
          2.ナレッジベースの属性情報。アイテムに応じた属性を顧客の属性にマッピングする。
          直接:都心か郊外か→郊外→近隣のものを推薦
          間接:家族の人数→5人以上→寝室が2つ以上のものを推薦
          3.アイテムに関するデータを全部使う
        • 関連した結果を返す際の3つのアプローチ
          1.ユーザーの回答をもとに条件を類推し、ユーザーの要望に加える。(例えば、家族の人数が5以上と回答された場合に、寝室の数は3以上必要だろうとして要望に加える。)
          2.要望をもとにデータベースのクエリを生成
          3.ユーザーの要望に関連したカタログを抽出する
        • 対話のアプローチ
          1.インターフェースを通してユーザーのプリファレンスの初期値を得る。
          2.マッチさせたアイテムを並べてユーザーに示す。なぜそれを表示したのかの理由も付ける。
          3.条件緩和や追加の要望を受け付ける。レコメンドの件数が多すぎたら要件を増やして、少なすぎたら要件を減らす。
        • マッチしたアイテムの並べ方
          効用関数を使ったりする。
          $$ U( \overline V ) = \sum_{j=1}^{d}w_j \cdot f_j(v_j) $$
          \( w_j \)は評価のウェイト、\( v_j \)はマッチした属性の値。
        • 受け入れられない結果や空集合への対応
        • 制約の追加

        Case-Based Recommenders

        • 制約ベースのレコメンドとは違い、強い制約がない。良いレコメンド結果になるまでユーザーの要望を繰り返し修正していくアプローチとなる。
        • ケースベースのレコメンドの場合の重要な要素
          1.類似度の指標

          $$f(\overline{T}, \overline{X}) = \frac{\sum_{i \in S}w_i \cdot Sim(t_i, x_i)}{\sum_{i \in S} w_i} $$

          Sは属性の集合で、属性ごとに重みが違う。tはターゲット。xはあるアイテム。

          ・対称
          $$ Sim(t_i, x_i) = 1 – \frac{|t_i – x_i|}{max_i – min_i} $$
          ・非対称

          $$ Sim(t_i, x_i) = 1 – \frac{|t_i – x_i|}{max_i – min_i} + \alpha_i \cdot I( x_i > t_i ) \cdot \frac{|t_i – x_i|}{max_i – min_i} $$

          ・多様性
          1から類似度を差し引いたものが多様性の尺度となる。
          $$D(\overline{X}, \overline{Y}) = 1 – f(\overline{X}, \overline{Y})$$
          2.批評
          ・推薦結果がユーザーに示されてから、批評を通じてフィードバックを受ける。
          ・単純な批評:特徴の一つを変更してもらう
          ・複合的な批評:複数の特徴量を変更してもらう
          ・動的な批評:データマイニングからフィードバックを掴み取る(アソシエーション分析とか)

        Persistent Personalization in Knowledge-Based Systems

        • ナレッジベースのレコメンドでの過去ログの蓄積があれば、効用関数や類似度関数、制約の提案、動的な批評に関してパーソナライズすることが可能。

        第6章

        TBD

        第7章

        評価の目標に正確度がよく使われるが、ユーザー体験において重要な指標は目新しさや信頼度やカバー範囲やセレンディピティなど、それ以外の指標によるところが多い。正確度は大事な指標ではあるが、それだけでは良いレコメンドシステムを作ることは難しい。

        Evaluation Paradigms

        レコメンドシステムの評価方法にはユーザースタディ、オンライン評価、オフライン評価の3つがある。

        • ユーザースタディ
          特定のタスクを行い、レコメンドシステムを触ってもらい質問をするなどして、ユーザーからのフィードバックをもらう。ただし大規模に行うとコストもかかるし、参加する時点でユーザーの性質が違う可能性もあり、バイアスが含まれる可能性がある。
        • オンライン評価
          レコメンドシステムを実装したサイトなどで、ユーザーのグループをAとBに分け、アルゴリズムAとアルゴリズムBをそれぞれ用いて、その結果としてコンバージョンレートなどを比較する。バンディットアルゴリズムを使うのも良い。ただ、オンライン評価は実装含めコストがかかる。
        • オフライン評価
          レコメンドアルゴリズムにおいて最もポピュラーな評価方法で、過去のデータにおける評価を行う。当然、オンライン評価のほうが望ましいが、統計的にロバストであろうと観点で非常によく使われる。ただし、セレンディピティや目新しさを評価することは難しい。

        General Goals of Evaluation Design

        • Accuracy
          モデルの訓練にも、評価にも使われる。レコメンドシステムにおいても、機械学習の分類や回帰タスクと同様に、ホールドアウトや交差検証などを行って評価する。
          あるユーザーのあるアイテムに対する評価の誤差を以下の式で表す。
          \(e_{uj} = \hat r_{uj} – r_{}uj \)
          なお、Eは評価対象の集合とする。その際、正確度の評価は以下のようになる。

          $$ MSE = \frac{\sum_{(u, j) \in E} e_{uj}^2 }{|E|} $$

          $$ RMSE = \sqrt{ \frac{\sum_{(u, j) \in E} e_{uj}^2 }{|E|} }$$

          なお、他にもランキングベースの評価方法もある。
          ただ、精度が高くても、ユーザーが絶対に買うであろうアイテムしかレコメンドできない場合は、レコメンドシステムの意味合いとしては薄れる。

        • Coverage
          レコメンドシステムが精度が高すぎる場合、一部のアイテムは一部のユーザーに全く推薦されなくなる。
          k点以上の評価を付けるであろうと予測したユーザーの割合は、ユーザー空間でのカバレッジと呼ばれる。
          一般的に、近傍ベースの手法を考えた際に、近傍を広げた場合、精度は落ちてしまうが、カバレッジは高くなる。ようは、精度とカバレッジはトレードオフの関係にある。
        • Confidence and Trust
          予測した評価の範囲として信頼区間が与えられる。予測した値の誤差が信頼区間にマッチしているかどうかで測る。同じアルゴリズムにおいて、信頼区間が狭いものほど良いと判断する。ただし、予測が正確だとしても、評価をユーザーに信じてもらえないと役に立たない。推薦理由がロジカルかどうかが重要となる。
        • Novelty
          ユーザーがこれまで気づかなかったような推薦ができているかどうかを表す指標。オンライン評価として画面上でユーザーに回答してもらうという方法で測るケースが多いが、いつでもその評価を実行することはできない。
          一方、オフラインであれば、それが可能となる。現時点よりも将来に選びそうなアイテムを推薦できるようになれば、それがノベルティに繋がる。
          過去に評価されているアイテムを、正しく推薦されてしまうとノベルティに関するペナルティが与えられるとする。将来時点で評価されるアイテムを正しく推薦できたらノベルティに関してリワードが与えられると考える。ようは将来と過去の予測の正確度の差分でもってノベルティを測ることとなる。
        • Serendipity
          セレンディピティは幸運な発見を意味する。レコメンドの成功における驚きのレベルを測る。セレンディピティはノベルティよりも強い条件で、セレンディピティがある場合、そのアイテムは目新しいが、逆は真ではない。
          オンライン評価の場合、ユーザーからのフィードバックで意外性があったかどうかを測ればいい。
          オフライン評価の場合、コンテンツベースで選んだものではないアイテムがユーザーに選ばれた場合に、セレンディピティがあると見なすことができる。コンテンツベースのレコメンドとそうでないレコメンドの結果の二つを用意する必要がある。
        • Diversity
          推薦リストの中でのアイテムの多様性を測る。多様性が高まれば、ユーザーのニーズを捉える可能性が高まると考えられる。
          多様性はコンテンツを元にしたアイテム間の類似度で測る。全てのアイテムのペアに対しての平均的な類似度が多様性を表す。
        • Robustness and Stability
          偽の評価や時間とともに急激にデータが変化した際に、レコメンドシステムが影響をあまり受けない場合、そのレコメンドシステムはロバストで安定していると見なすことができる。レコメンドシステムの利用者の中には、ランキングを不正に高めることが自身の利益に繋がることがある。
        • Scalability
          近年、暗黙フィードバックも考慮すれば、レコメンドシステムを構築するためのデータは比較的簡単に入手できるようになった。そこで、データの大きさがもたらす問題に関して注意を払う必要がある。
          1.機械学習モデルの訓練時間
          2.予測(推論)時間
          3.計算の際に要求するメモリの量

        Design Issues in Offline Recommender Evaluation

        • レコメンドシステムを開発するに際して、データは3つのパーツに分割される。
          1.訓練データ(モデルの構築)
          2.検証データ(モデル選択・パラメータチューニング)
          3.テストデータ(二度漬け禁止)
        • ※豆知識:Netflix Prizeのデータは学習データとテストデータがかなり違っていたらしい。学習データに古いレーティングが入っていて、テストデータに新しいレーティングがあるという状態だったとのこと。
        • Segmenting the Rating for Training and Testing
          ・Hold-Out
          ・Cross-Validation
        • Comparison with Classification Design
          回帰や分類タスクと同様にサンプルセレクションバイアスの問題がはらんでいる。

        Accuracy Metrics in Offline Evaluation

        • レコメンドシステムの評価方法としてはランキング系のものが良いが、わかりやすさを重視するならばRMSEが良い。
        • Measuring the Accuracy of Ratings Prediction
          ・MSE
          ・RMSE
          ・MAE
          ・NRMSE
          ・NMAE
        • RMSE versus MAE
          RMSEは異常の影響を受けやすい。一方でMAEは影響を受けにくい。
        • Impacr of the Long Tail
          主要なアイテムによって評価は影響を受けるが、売り上げの大半はロングテールなアイテムであり、主要なアイテムがロングテールなアイテムに悪影響を与えることがありうる。
        • Evaluating Ranking via Correlation
          レコメンドシステムはユーザーに対しアイテムのランキングを提供し、上位k個のアイテムが推薦されることとなる。
          ランキングのための評価指標について。
          1.スピアマン順位相関係数
          2.ケンドール順位相関係数
        • Evaluating Ranking via Utility
          効用関数ベースのランキング評価指標。
          $$ F(u, j) = \frac{max\{ r_{uj} – C_{u} , 0 \}}{2^{\frac{v_j – 1}{\alpha}}} $$
          ここで、\( C_{u} \)はユーザーの平均的な評価とされる。

          $$ R-score(u) = \sum_{j \in I_{u} F(u, j) } $$

          ・DCG(discounted cumulatiove gain)
          $$ DCG = \frac{1}{m} \sum_{u=1}^{m} \sum_{j \in I_u, v_j \leq L } \frac{g_{uj}}{log_2 (v_j + 1)} $$
          \( v_j \)はアイテムjの順位を表す。
          $$ g_{uj} = 2^{rel_{uj} – 1 } $$
          ここで\( rel_{uj} \)は実際の評価が使われることが多いとのこと。

          ・NDCG(normalized discounted cumulatiove gain)
          $$ NDCG = \frac{DCG}{IDCG} $$

        Limitations of Evaluation Measures

        第8章

        TBD

        第9章

        TBD

        第10章

        TBD

        第11章

        TBD

        第12章

        TBD

        第13章

        TBD

        [Python]データ分析業務で使いそうなコードまとめ(随時更新)

        はじめに

        仕事で使いそうなPythonのコードを残しておくドキュメントが欲しいなと思ったので、よく使うものをこちらに貯めていこうと思います。まだ19個しかないですが、30個を目標に追記していきます。

        フォーマットとしては、
        1.やりたい処理
        2.コード
        3.参考情報のリンク
        の3つを1セットにしています。
        まずは、自分自身や周りで仕事をしている人が楽をできるドキュメントになればいいなと思って作っていきます。

        目次

        ・重複削除
        ・階級のデータを作りたい
        ・再起的にリストをコピーしたい
        ・ピボットテーブルでアクセスログから特徴量用のデータを作りたい
        ・データフレームのある列に対して特定の文字列で分割し、その任意のN番目のものを抽出したい
        ・データフレームの行単位で割り算を行いたい
        ・列単位で行を足し合わせて文字列を作りたい
        ・グループのレコードごとにidを割り当てたい
        ・正規表現で任意の合致した文字列で挟まれた文字列を抽出したい
        ・複数列の集計値同士で除した値が欲しい
        ・等間隔の実数の数列を作成したい
        ・スペース区切りの文字列において、ある単語の前後N個の語を抽出したい
        ・グループごとに文字列を結合したい
        ・文字列の置換をdict形式のデータで行いたい
        ・テキストを形態素解析してBoW形式のデータにして特徴量にしたい
        ・訓練データとテストデータで特徴量の数が足りない時に不足した変数を追加したい
        ・アクセスログのユーザーごとのレコードごとの累積和を計算したい
        ・選択したカラムで一気にダミー変数にしたい
        ・グループ化して平均値を計算し、プロットし、2軸でそれぞれのデータ数も載せたい
        ・参考情報

        データセット

        全体を通じて使うデータセットを生成する関数を用意しておきます。一つ目の
        データはkaggleのBoston Housingのデータセットです。

        二つ目はアクセスログのデータが欲しかったので、Google Analytics APIを使ってデータを抽出したものとなります。ここではソースコードを載せますが、皆さんは当然見れません。一応、GitHubにデータを上げておきます。

        三つ目はテキストデータです。

        前処理

        重複削除

        • やりたいこと
          重複したデータを除外したい。最初に現れたレコードだけを残したい。
        • コード
        • 参考情報
          https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.duplicated.html

        階級のデータを作りたい

        • やりたいこと
          任意の範囲に応じたラベルをつけた階級値を作りたい。
        • コード
        • 参考情報
          https://pandas.pydata.org/docs/reference/api/pandas.cut.html

        再起的にリストをコピーしたい

        • やりたいこと
          リストをコピーした際に、コピーしたものを変更した際に、もとのものも変更されてしまうので、それを防ぎたい。
        • コード
        • 参考情報
          https://docs.python.org/3/library/copy.html

        ピボットテーブルでアクセスログから特徴量用のデータを作りたい

        • やりたいこと
          集計されていないアクセスログをもとに、セッションidごとの触れたページを集計し、Bag of Words形式のデータフレームにしたい。これは機械学習の特徴量に使えるので便利。
        • コード
        • 参考情報
          https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.pivot_table.html

        データフレームのある列に対して特定の文字列で分割し、その任意のN番目のものを抽出したい

        • やりたいこと
          pandasのデータフレームである文字列の列に対して特定のキーワードで分割し、そのN番目のものをデータフレームの列として持たせる。今回はURLのパラメータの後ろについている文字列を抽出している。
        • コード
        • 参考情報

        データフレームの行単位で割り算を行いたい

        • やりたいこと
          各行の合計で、各行を割ることでレコード単位で重み付けを行いたい時や確率を計算したいときに良く使います。データはアクセスログをBag of Word形式したものを使います。
        • コード
        • 参考情報
          https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.div.html

        列単位で行を足し合わせて文字列を作りたい

        • やりたいこと
          データフレームの列の要素をつなぎ合わせて文字列を作成したい。複合キーを作らないとデータを繋げない時などによく使います。
        • コード
        • 参考情報
          https://www.kato-eng.info/entry/pandas-concat-pk

        グループのレコードごとにidを割り当てたい

        • やりたいこと
          アクセスログなどで、任意のユーザーの初回に触れたページや、N番目に触れたページなどを抽出しやすいように、ユーザーごとのログにidを付与したい。
        • コード
        • 参考情報
          https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.factorize.html

        正規表現で任意の合致した文字列で挟まれた文字列を抽出したい

        • やりたいこと
          正規表現を用いて、文字列に対して「指定した文字列と文字列の間にある表現」を抽出するための処理です。URLのデータや規則性のあるテキストデータに対して特徴量を作りたい時に使えます。
        • コード
        • 参考情報
          https://docs.python.org/ja/3/library/re.html

        複数列の集計値同士で除した値が欲しい

        • やりたいこと
          複数の列で集計した値同士を用いて、さらにそこから比率のデータを作りたい。ターゲットエンコーディングを行いたい場合に使える。
        • コード
        • 参考情報
          https://stackoverflow.com/questions/45075626/summarize-using-multiple-columns-in-python-pandas-dataframe

        等間隔の実数の数列を作成したい

        • やりたいこと
          パラメータチューニングをする際に、各パラメータについて等間隔の実数列を作りたいときがあるので、その時に使うコード。
        • コード
        • 参考情報
          https://www.pythoncentral.io/pythons-range-function-explained/

        スペース区切りの文字列において、ある単語の前後N個の単語を抽出したい

        • やりたいこと
          テキストマイニングをする際に、関心のある単語の前後N文字を抽出したい時がある。もちろん、関心のある単語の周辺の単語というものを特徴量にすることも良いと思われる。ここではMeCabによる形態素解析により分かち書きにする関数と共に紹介する。
        • コード
        • 参考情報
          https://stackoverflow.com/questions/17645701/extract-words-surrounding-a-search-word

        グループごとに文字列を結合したい

        • やりたいこと
          テキストマイニングなどで、任意のグループごとのテキストデータをスペース区切りで繋ぎたいときがあります。任意のグループごとのテキストを一気に連結できて便利です。これを形態素解析して特徴量にするのも良いと思います。
        • コード
        • 参考情報
          https://stackoverflow.com/questions/17841149/pandas-groupby-how-to-get-a-union-of-strings

        文字列の置換をdict形式のデータで行いたい

        • やりたいこと
          事前に用意した置換のリストを使って、文字列の置換を一気に行いたい。
        • コード
        • 参考情報
          http://omoplatta.blogspot.com/2010/10/python_30.html

        テキストを形態素解析してBoW形式のデータにして特徴量にしたい

        • やりたいこと
          任意の日本語のテキストとラベルの組み合わせがあるとして、テキストを形態素解析してTF-IDFを計算し、それを特徴量としてラベルを予測するということをやりたい。ここでは以前集めて、GitHubに載せてあるデザイナーズマンションのデータを使い、MeCabで形態素解析をしたあとに、TF-IDFを計算し、それを特徴量にしてsklearnで簡単に予測をし、リフト曲線を描いている。
        • コード
        • 参考情報
          https://scikit-plot.readthedocs.io/en/stable/metrics.html

        訓練データとテストデータで特徴量の数が足りない時に不足した変数を追加したい

        • やりたいこと
          訓練データとテストデータの変数の数が違う時に、そのままではモデルを使えないので、補うために使う。
        • コード
        • 参考情報
          なし

        アクセスログのユーザーごとのレコードごとの累積和を計算したい

        • やりたいこと
          アクセスログや購買データなどで、レコードごとの累積の値を計算したいときに使う。時系列に従いどんどん足されていく。
        • コード
        • 参考情報
          https://ohke.hateblo.jp/entry/2018/05/05/230000

        選択したカラムで一気にダミー変数にしたい

        • やりたいこと
          ダミー変数を一気に生成したい。名前も一気に付けたい。
        • コード
        • 参考情報
          なし

        グループ化して平均値を計算し、プロットし、2軸でそれぞれのデータ数も載せたい

        • やりたいこと
          EDAの時に、グループ化して平均値などを計算するだけでなく、該当するデータ数も2軸でプロットしたい。
        • コード
        • 参考情報
          なし

        参考情報

        前処理大全[データ分析のためのSQL/R/Python実践テクニック]
        はじめてのアナリティクス API: サービス アカウント向け Python クイックスタート
        カモノハシペリー
        ペリー|フィニアスとファーブ|ディズニーキッズ公式

        Uncertainty in Gradient Boosting via Ensembles[A4一枚まで備忘録]

        A4用紙1枚にまとめるイメージでメモを残そうという取り組み。

        今回は機械学習でとりわけ、回帰の問題を扱うことが仕事であった際に参照できるメモの一つとして残したい。
        先日、Catboostのドキュメントに参考文献としてUncertainty in Gradient Boosting via Ensemblesの存在を知った。業務において、価格の予測とか、期間の予測とかマーケティングのデータでも良く扱うものなので、分類だけでなく回帰についてもバランス良く知見を貯めたいところ。

        目次

        Abstract
        Introduction
        Background and related work
        Generating ensembles of GDBT models
        Experiments on Synthetic Data
        Experiments on classfication and regression datasets
        Conclusion
        Broader Impact

        Abstract

        機械学習のモデルは予測において点推定しかしないが、実務上は不確実性を定量化したいニーズがある。この研究では、予測の不確実性推定値を導出するためのアンサンブルベースの枠組みが紹介されている。予測における不確実性は「データに起因する複雑さとノイズの不確実性」「特徴空間において、情報がないことに起因する不確実性」に分解される。
        手法としては確率的勾配ブースティングと確率的勾配ランジュバンブースティング(SGLB)が扱われている。SGLBは一つの勾配ブースティングモデルからのアンサンブルを可能にし、モデルの複雑さを減らすことができる。また、予測性能の向上について様々なデータセットを使って示されている。

        Introduction

        一般的な勾配ブースティングについて、回帰の際に点推定しか返さないことを挙げている。NGBoostにつ