未定の部屋

主にデータサイエンス関係の記事を書きます

因果推論とビジネス適用について考えてみる

こんにちは。

最近『統計的因果推論の理論と実装』という書籍を一通り読み終わったので、書籍の感想+ビジネス適用というテーマで思うところを書いてみます。
新卒二年目の視点なので、現場の感覚・観点になると思います。



書籍の感想

因果推論についてはちょこちょこ勉強していて、今までに岩波DS vol.3効果検証入門を読んできました。
なので基本的な知識はある程度持ち合わせた状態で読んだのですが、それを踏まえても『統計的因果推論の理論と実装』はかなりボリュームのある書籍だと感じました。因果推論という分野の中での手法を広く紹介しているだけでなく、最新論文から引用していたり理論面も抜けなく書かれている印象があったり、各手法について読者の負担になりすぎない範囲でしっかりと解説されていたので、とても満足感がありました。

この本は前半:回帰分析での効果推定→後半:因果推論の各手法での効果推定という流れなのですが、前半の回帰分析のパートも丁寧で、重回帰分析に必要な仮定についても詳しく言及されています。重回帰分析は実務では良く使うので、「多重共線性は禁則事項ではない」「迷う場合は、不要な変数は入れた方が良い」などの、分析や解釈をする際に役立つ知見がちりばめられていたのはすごく貴重だなと思いました。重回帰分析をちゃんとやるのは難しく、奥が深いなと改めて感じられました。
後半は因果推論の各手法についてで、傾向スコア、操作変数、回帰不連続デザイン、欠測データ処理といったトピックが含まれています。傾向スコア、操作変数法、回帰不連続デザインあたりは何となく知っている程度だった理解が深まりましたし、欠測データの処理は初見だったので勉強になりました。個人的に、回帰不連続デザインは局所で無作為割付けが成立していることは納得できたのですが、そこから回帰モデルをあてはめる部分はあまり納得できなかったので、再び勉強する機会があればちゃんと考えたいと思います。
全体(特に後半)を通して思ったこととして、実務よりは研究視点の内容だなと思いました。因果推論の各手法は前提条件が厳密なので、ビジネスシーンでは仮定を満たすデータがなかなか手に入らない印象があります。また、分析手法の中にはかなり難しい部分もあり、因果推論を適用した分析結果を上手く伝えるところにもハードルがあると思います。ですが、因果推論の考え方は分析屋としてしっかりとおさえたい内容だし適用できたら強力なツールだと感じるので、ビジネスへの応用ができないか考えながら仕事していきたいなと思っています。

因果推論のビジネス適用

書籍に加え、こちらのスライド内容も踏まえつつ話したいと思います。

「因果関係」をとらえるために / To grasp causal relationship

こちらのスライドにも「アカデミックな場では広く使われているが、ビジネスにおける直接適用は難しいかもしれない」といったことが書かれており、自分の感覚とも概ね一致していました。一方で「因果を考える際の基本的なフレームワークとしてはビジネスの場でも非常に有用だと思われる」と書いてあったのですが、具体的にどう有用なのかまでは言及されておらず、少しモヤっとする部分もありました。
なので、自分なりにビジネス適用について少し考えてみたのですが、以下のことが思いつきました。

  1. 分析結果について、数値の見かけの正負にごまかされなくなる
  2. 厳密な効果検証をするような場面があった時に、分析設計時に手持ちの武器になる

1については分析手法が因果推論かどうかに限らず言えることかなと思います。大体の分析は何らかの定量評価を行うことが多く、アウトプットされてくるのも定量的な数値であることが多いと思います。例えば効果検証の文脈だったら「CMを打ったことで売上が○○円上がった」みたいな結果が出たりしますが、因果推論を学ぶことでこの数値がどれくらい妥当なのか、一度立ち止まって考える癖が身につくような気がします。見かけ上の数値の大小だけでなくその数値の信頼性を加味して考察するのはとても重要ですが、信頼性についてはどうしても見かけの数値の二の次になってしまう傾向があるので、ここを踏まえて考察できるようになるのはメリットだと思います。信頼性について考察するときに、因果関係の洗い出し、交絡因子の影響、個体や処置が仮定に矛盾しないといった因果推論の考え方を持ち合わせている方が考察の筋が良くなると思います。ビジネスの分析では手法の使い方が正しくてもデータに不備があったり仮説が不適切だったりすることも多いので、分析結果を鵜呑みにしないスキルというのは大切だと感じています。

2については、実際に因果推論を適用できそうな時に武器になるというイメージです。といっても上述の通り、直接適用できる場面はなかなか少ないと思うのですが、例えば簡易的な分析を行った時に結果の信頼性が低い・妥当性が低いなどで納得感が得られず追加分析のような文脈で厳密性が重視されるようなときや、データ収集の段階から絡んでいけるようなプロジェクトでは因果推論の手法も候補に入ってくるのかなと思います。コストや難解さといった観点から、なかなかここまでの厳密性を要求されることはないと思いますが、要求されるような場面では間違いなく因果推論の知識がある方が良いと思います。

自分の中ではこれくらいしか思いつかなかったのですが、これでも結構メリットはあるのかなという感じがします。やや拙い内容になってしまったかもしれませんが、このあたりで終わります。

では。

BERT論文解読

こんにちは。
以前BERTを実務で使った際に論文を読んだのですが、その時のメモを公開しようと思います。
ググれば日本語の論文解説はいくらでも出てくるのでアレですが、備忘録的に残そうと思いブログに載せました。自然言語処理系の論文をちゃんと読むのが初めてだったので当時かなり苦労しながら解読した記憶があります。

内容

アブスト

  • BERT:Bidirectional Encoder Representations from Transformersの略
  • 直訳:双方向のトランスフォーマーによるエンコーダー表現
    文脈を前後両方から条件付けてラベルの無い文書を双方向的に事前学習する
  • 1層加えてファインチューニングするだけで、様々なタスクに対応したモデルを作ることができる
    大幅なモデルの変更が要らない
  • 11のタスクでSoTA(State-of-The-Art:最先端レベル)の結果を出した。

イントロ

  • 事前学習は自然言語処理のタスクに有効
    単語レベルのタスクだけでなく文章レベルにも有効
  • 事前学習にはfeature-basedとfine-tuningのタスクがある
    • feature-based:ELMoなどがそうで、タスク固有のアーキテクチャを使う
    • fine-tuning:OpenAIGPTなどがそうで、最小限のタスク固有パラメータを導入する/事前学習されたパラメータによる下流タスクの上に学習される
      →どちらも一方向の言語モデルの事前学習に使用される
  • 現状、事前学習の特にfine-tuningにおいて表現力が制限されている。
    一方向の学習にしか使わないのは参照するトークンが前だけであり、制限されてしまう

  • BERTはmasked language model(MLM)を用いることで一方向の制限を緩和

    • masked language model:ランダムにトークンをマスクし、元の単語を予測することを目的とする
      MLMは前後両方の文脈から表現できる
    • MLMに加え、next sentence predictionによるテキストぺアの表現も利用

  • 結果として、
    • 双方向のmasked language modelを使用している
    • ヘビーなタスク固有のアーキテクチャの使用を以前より少なくできた 
      →最初のfine-tuningベースのモデルで、トークンレベル・センテンスレベルのタスクで最先端のパフォーマンスを達成

自然言語処理の変遷についての内容

1.教師なしのfeature-basedアプローチ

  • word embeddingや単語表現といった手法は文単位やパラグラフ単位のembedding(埋め込み)のような、粗い粒度に使われるようになった。
    ※おそらく単方向の事前学習モデルが主語

  • ELMoとその前任のモデルは文脈依存の特徴を双方向の言語モデルから抽出した

    • 文脈を前後双方向の連結で表現
    • これをタスク固有のアーキテクチャと統合したことで、ELMoはSoTAになった。
  • LSTMsもELMoと類似したモデルで、feature-basedで浅い双方向性(not deeply bidirectional)という特徴を有する
    cf)BERTは深い双方向性

2.教師なしのfine-tuningアプローチ

  • 初期はラベルの無いテストから学習したword embedding
  • ラベルなしテストからの事前学習+教師ありのfine-tuningで文書のエンコードがされるようになった
  • OpenAI GPTがSoTAのモデルとなっていた(BERT以前)

3.教師ありデータからの転移学習

  • 自然言語推論や機械翻訳のような大きなデータセットを要する教師ありタスクから転移することで効果的な結果をもたらすワークが出現した

BERT

pre-trainingとfine-tuningからなる

  • pre-training:複数のpre-trainingタスクのもとラベルなしデータを用いて学習
  • fine-tuning:pre-trainingで作成されたパラメータを、下流タスクのラベル付きデータを用いてfine-tuning
  • 特徴:タスク間でのアーキテクチャに大きな差がなく、全てpre-trainingでのアーキテクチャをベースにしている

Model Architecture

  • 多層双方向Transformer Encoder

    • Transformerのベースとなった論文:
      Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez, Lukasz Kaiser, and Illia Polosukhin. 2017. Attention is all you need. In Advances in Neural Information Processing Systems, pages 6000–6010.

  • BERT_base:OpenAI GPTと同じモデルサイズだが、Transformerは双方向から解読できる

Input/Output Representations

論文Figure 1より

  • Input:ひとつのトークンで一文もしくはペアの文の両方を表現できる
    これにより、一文は任意のスパンのテキストと認識されてインプットされる(この1セットをシーケンスと呼んでるっぽい)
  • CLS:各シーケンスの最初のトーク
    final hidden vectorでCと表記(これ以外のトークンはTと表記)
  • SEP:シーケンスを分けるために使うトーク

  • SEPで分けた後、各トークンがAとBのどちらに属するかを示すlearned embeddingを追加する(上図のEに相当)

  • BERTのInputは各単語をトークン、セグメント、ポジションのembeddingで表現する(下図)

    論文Figure 2より

Pre-training BERT

二つのタスクからなる

1.Masked LM

  • BERTは双方向から学習するが、普通は双方向から学習するとモデルは自明にターゲットの単語を予測できてしまう
  • インプットしたトークンをランダムにマスキングして、マスキングされたトークンを予測するようにした(Masked LM; MLM)

    • マスクされたトークンに一致したfinal hedden vectorがアウトプットとして出される
    • 15%の単語がマスクされ、その単語だけを予測する
  • これだけだとマスクされたトークンがfine-tuning時に出現しないためpre-trainingとfine-tuningでミスマッチが起こるので、80%の確率でマスキング、10%の確率でランダムなトークンに、10%の確率でそのままトークンを使用するようにした。

2.Next Sentence Prediction(NSP)

  • 文脈を理解するモデルを作るために、単一の言語コーパスから生成できるNext Sentence Predictionタスクを事前学習

    • 50%の確率で隣接した2文、50%でランダムな2文になるように2文の組をコーパスから抽出
    • 最初にあるCのトークンが該当
  • 以前のNSPでは文章粒度のベクトルしか下流タスクに転送できなかったが、BERTは全てのパラメータを転送して、エンドタスクのモデルパラメータを初期化できる

3.Pre-training data

  • BooksCorpus (800M words)とEnglish Wikipedia (2,500M words)から学習
Fine-tuning BERT
  • TransformerのselfattentionメカニズムによってBERTは多くの下流タスクをモデル化できるため、fine-tuningが容易

    • BERTにタスク固有のインプットとアウトプットを流し込み、全パラメータをend-to-endでfinetuneする
  • 一般的な手法はテキストの組に対するエンコードとbidirectional cross attentionを別々に行うが、BERTは同時に行う

  • pre-trainingに比べるとfine-tuningは短時間で処理される

Experiments

GLUE
  • GLUE:The General Language Understanding Evaluation benchmark
    様々な自然言語理解のタスクのコレクション
  • GLUEのテストにおいて、BERT(BASEとLARGE)は全てのタスクにおいて他の手法を上回るスコアをたたき出した
    • BERTBASEとOpenAIGPTはモデルアーキテクチャにおいてはほぼ同一
    • LARGEの方がBASEよりもすべてのタスクで優れている(特に訓練データが少ない時に顕著)
SQuAD v1.1
  • SQuAD v1.1: The Stanford Question Answering Dataset
    10万件のQAペアデータ
    Question Answeringタスクにあたる
  • SQuAD+TriviaQAでfine-tuningしたBERTは全てのシステムのスコアを上回った(人間のテスト結果も上回った) TriviaQAを使用していなくても既存の手法より高いスコアとなった
SQuAD2.0
  • SQuAD1.1の拡張版(長い解答のデータを含めた/答えが存在しないという選択肢が追加されている)
  • こちらも過去のF1最高値を5.1ポイント更新した(78.0→83.1)
  • ここでは人間の方がスコアが高い
SWAG
  • SWAG:The Situations With Adversarial Generations dataset
    常識的な推論を評価する11.3万件の文の組
    • 与えられた文に対して最ももっともらしい選択肢を選ぶ
  • 正解率でEDIM+ELMoやOpenAI GPTを上回った

Ablation Studies

Effect of Pre-training Tasks
  • 2種類の事前学習モデルを評価することでBERTの深層双方向性の重要度を確認

    • No NSP:MLMを使用するがNSP(Next Sentence Model)は使用しないもの
    • LTR&No NSP:MLMではなくleft-context-only model(左から右のみのモデル)を利用し、No NSPであるモデル。
      LTR(Left To Right)はfine-tuningでも適用

  • 比較↓

    • BERTとNo NSPを比較することでNSPの重要性が、No NSPとLTR&No NSPを比較することで双方向性表現の重要性が分かる
    • BiLSTMを追加してもBERTの方が良いことが分かる
      論文Table 5より



  • LTRとRTLを別々に行って結合することもできるが、時間がかかる・非直感的・各層に二つのモデルのコンテキストが存在するので双方向性モデルより性能が劣るといった欠点がある(よくわからず)
Effect of Model Size
  • fine-tuningの正解率に対するモデルサイズの影響を調査

    • ハイパーパラメータや学習手順は変えずに、レイヤー数・隠れユニット・attention headsを変えて比較
  • 大きなモデル程正解率が上がる傾向

    • すでに大きなモデルでも改善の余地があることを示唆

論文Table 6より


  • モデルサイズを大きくすれば大きなスケールのタスクを改善できることは以前から言及されていたが、モデルサイズを大きくすることで小さなスケールのタスクに対しても改善が見込まれ、これは新たな発見と言えそう

  • モデルサイズの変更に関する仮説
    • 下流タスクを直接fine-tuningし、追加パラメータとしてごく少数の初期化されたパラメータを追加する場合であれば、データセットが少ない場合でもタスク固有のモデルは事前学習された表現の恩恵を受けられる
Feature-based Approach with BERT
  • Fine-tuning Approach:事前学習したモデルにシンプルな分類層を追加し、下流タスクで全パラメータの微調整を行うやり方

    • cf. Feature-based Approach:事前学習されたモデルから固定された特徴を抽出するやり方。下記の利点がある
    • すべてのタスクを簡単に表現できないので、タスク固有のモデルアーキテクチャを追加する必要がある
    • 学習データの高価な表現を一度事前計算し、その上でより安価なモデルで多くの実験を行えるという計算上の利点がある

  • これら二つのアプローチをそれぞれBERTに取り入れたときの結果を比較↓

    • fine-tuning>feature-basedとなった
    • BERTLARGEが最も性能良い
    • Feature-based Approach の中ではConcat Last Four Hidden(※)が最も性能が良く、fine-tuningと0.3ほどのF1値の差しかなかった
      ※事前に学習したTransformerの上位4つの隠れ層からトークン表現を連結する方法

  • BERTはfine-tuning・feature-basedのどちらのアプローチにも効果的と言える

    論文 Table 7より

Conclusion

言語モデルの転移学習による近年の実証的な改善は、教師なしの事前学習が多くの言語理解システムに不可欠な部分であることを示した。
特に、これら結果は低リソースのタスクでも深い一方向性のアーキテクチャの恩恵を受けることを可能にした。

この研究によって、深い双方向性のアーキテクチャにも一般化され、同じ事前学習済みモデルを用いて幅広い自然言語処理のタスクに対応できるようになった。

用語

  • タスク:自然言語処理の各ジャンルの問題のこと。質問応答や文書分類、翻訳など
  • named entity recognition:固有表現抽出
  • トークン:分割された単語
  • 分散表現:トークン同士の関係性をベクトルで定義すること
  • objective function:目的関数
  • Embedding:埋め込み。単語や文に対して固有のベクトルを与えることを指す
  • オートエンコーダ:NLの一つで入力されたデータを一度圧縮して重要な特徴量を残した後、再度元の次元に復元処理するアルゴリズム
  • コーパス:テキストや発話を大規模に集めてデータベース化した言語資料
  • シーケンス:単語データの並びのことで、いわゆる文章にあたる
  • エンコード:信号やデータを変換すること。符号化。 MLM:Masked Language Model;入力された単語のうち一部をマスキングし、文脈からマスキングされ単語を予測するようなモデル
  • bidirectional cross attention:隣接する文から学習する、みたいなことだと思っている
  • EM:Exact Match;予測解と実際の解が完全に一致している割合
  • F1:適合率と再現率の調和平均
  • Ablation Studies:モデルを構成する要素をあえて削除し、その要素がモデルの性能にどう貢献しているのかを評価すること

参考

ipynbファイルをいい感じにgit管理できるツールnbdimeを使ってみた

※2021年11月に書いた記事を再投稿したものになります

こんにちは。業務では主にデータ分析をしていて、普段はJupyter NotebookでPythonを書くことが多い人です。

きっかけ

Jupyter Notebookのファイルはipynbですが、このファイルはJSON形式で、ソースコードの他にメタデータやアウトプットデータが含まれています。そのためgitでipynbファイルを管理をするとなるとコードの変更だけでなくメタデータやアウトプットデータの変更分も加味されてしまいます。gitでipynbファイルを管理してみるとわかりますが、差分がJSON形式で表示されるのでファイルの差分がごちゃごちゃしてしまい見にくくなります。
そこで色々と調べたところ、nbdimeというツールを使うとipynbファイルのソースコードの差分だけを表示してくれて分かりやすそうだったので、使ってみました。

nbdimeのインストール

インストール環境はWindows 10 64 bit、Python3で行いました。また、gitは既にインストールされています。

Pythonの他のライブラリと同様に、
pip install nbdime
でインストールできます。
その後コマンドで、
nbdime config-git --enable --global
と打てば設定完了です。これでdiffとmergeのツールとして設定されます。 .gitconfigファイルに以下の内容が追加されていればOKです。

[diff "jupyternotebook"]
    command = git-nbdiffdriver diff
[merge "jupyternotebook"]
    driver = git-nbmergedriver merge %O %A %B %L %P
    name = jupyter notebook merge driver
[difftool "nbdime"]
    cmd = git-nbdifftool diff \"$LOCAL\" \"$REMOTE\" \"$BASE\"
[difftool]
    prompt = false
[mergetool "nbdime"]
    cmd = git-nbmergetool merge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
[mergetool]
    prompt = false

自分はもともとdiff, mergeツールとしてp4mergeをconfigファイルに登録していたのですが、p4mergeとnbdimeを両方追加した状態だとうまくnbdimeでコードを見られなかったので、p4mergeをconfigから外したらうまく見られるようになりました。

簡単な運用例

コマンド上で差分を表示する

git diff [<commit ID、ブランチ名> <commit ID、ブランチ名>]
で表示できます。下の画像はPython

print('this is master')

print('this is merfe')

に書き換えた時の差分表示です。ちなみにmerfeはmergeのスペルミスです

web上で差分を表示する

nbdiff-web [<commit ID、ブランチ名> <commit ID、ブランチ名>]
で表示できます。コマンドの時と同じ例ですが、web上で見た方が分かりやすいですね。


マージの競合対処

競合が発生したときに、
git mergetool --tool nbdime -- *.ipynb
でweb上で競合対処ができます。

マージするときに不要な方にチェックをつけ、resolve conflictを押します。その後上部のsaveボタンを押し、close toolで画面を閉じると処理完了です。



こんな感じで、nbdimeを使えばipynbファイルでもいい感じにgit管理ができることが分かりました。まだ使い始めたばかりですが使用感はとてもいいです。今後も使ってみてもう少し理解を深めていこうと思います。
ではでは~


参考

  1. Jupyter Notebookの内部構造
  2. Jupyter Notebook ファイルのままdiffをとったり、マージしたり出来るツール nbdime
  3. nbdime(Scrapbox)
  4. 公式ドキュメント

Anaconda・非Anacondaのそれぞれの環境でPystanを運用できるようにしてみた

※2021年7月に書いた記事を再投稿したものになります

こんにちは。最近データ分析のスキルのうちデータエンジニアリングの重要性をひしひしと感じている新入社員です。 ここでいうデータエンジニアリングは、データサイエンスを意味のある形に使えるようにし、実装、運用できるようにする力1を指しています。当たり前なんですが、データ分析の手法や理論をいくら理解していても、実務ではPC上でそれを実行できないと意味ないんですよね(-_-;)
ということで、最近はデータサイエンスだけでなくデータエンジニアリングのスキルも意識的に身に付けていて、そこで今回はPystanを使えるようにしたよ!という備忘録を書こうと思います。



なぜAnacondaと非Anacondaなのか?

どっちかでええやん!って思いますよね?自分もそう思います...笑
じゃあなんで2つやったのかというと、社用PCと自宅PCで環境が違うからです()社用PCはAnaconda入れるなって言われたので普通にPythonインストールしてpipコマンドでライブラリを追加してます。一方の自宅PCは普通に楽なのでAnacondaをドーンと入れているわけですね。そこで今回は社用PCと自宅PCの両方でPystanを使えるようにしたという感じです。

Pystanとは

PystanはPythonでStanを使うためのライブラリです。Stanっていうのはベイズ推定を高速で行えるプラットフォームで、記述したモデルをC++に変換し、それからコンパイルして実行するという特徴があります。2これにより高速で処理できるようになります。
入社して3か月がたち、どうやらベイズ統計はかなり実務応用に向いているということを知り、じゃあベイズ統計を実装してみよう!と思ったのですが、それにはStanが必須らしいということで、Pystanを入れました。(ちなみにRStanも入れましたが、Pythonよりはるかに楽でした...)

Anaconda環境でPystanを入れる

ググってみるとPystanのインストールはAnaconda環境で行っている記事が多く、割とすんなりと入れられました。
前提として、Anaconda+VSCodePythonを使っています。Anaconda+VSCodeの環境構築についてはここでは触れませんが、この記事などを参考にして整備しました。

基本的には下記のサイトをベースにしてPystanを入れました。

インストール環境

Windows 10 64 bit
Python: 3.8.8
conda: 4.10.1

conda-forgeリポジトリの追加

今回は多分やらなくてもよいのですが、なんかよさげだったので仮想環境を作る前にcondaのパッケージ参照リポジトリにconda-forgeというリポジトリを追加しておきました。conda-forgeはgithub上のコミュニティ主体のパッケージコレクションで、たくさんのパッケージを公開しており、condaのdefaultsでは見つからないパッケージをダウンロードすることが可能みたいです。下記のサイトを参考にしました。
Pystanのインストール(anaconda環境) - Qiita

仮想環境の構築

作業は基本的にAnaconda Powershell Pronpt上で行いました。
まず仮想環境を作成します。今回はpy38_pystanという名前の仮想環境を作りました。この部分は自分の好きな名前にして作成できます。また、anacondaという文字を入れておくと、Anacondaのデフォルト環境に入っているパッケージが全部入ってきます。
conda create --name py38_pystan anaconda
↓のようにすると、Pythonのバージョンを指定できます。
conda create --name py38_pystan python=3.8.8 anaconda

次に仮想環境を起動して、Pystanをインストールします。
conda activate py38_pystan
conda install pystan
PystanはC++コンパイラーを必要とするので、以下のコマンドでインストールします。
conda install libpython m2w64-toolchain -c msys2

この時、anaconda3のディレクトリの下層(自分の場合はC:\Users[ユーザー名]\anaconda3\Lib\distutils)にdistutils.cfgがあることを確認し、ファイルの内容が以下のようになっていることを確認します。なければ自分でdistutils.cfgというファイルを作成します。

[build]  
compiler=mingw32

自分の場合、..[仮想環境名(今回はpy38_pystan)]\lib\distutilsの方にはこのファイルができていてanaconda3の方にはできていないという状態だったので、anaconda3の方にdistutils.cfgを追加しました。cfg形式のファイルはこのサイトの.jsのところを.cfgに置き換えて読めばできると思います。

VSCodeで実行

コードを実行する前に、仮想環境を選択しておく必要があります。適当にpy形式かipynb形式のファイルを開いた状態でコマンドパレット(F1 or Ctrl+ Shift+ P)を開き、Python: Select Interpreterを押します。するとPythonの環境の一覧が出てくるので、その中から今回作った仮想環境(自分の場合はpy38_pystan)を選択します。なければEnter interpreter path を押し、そこに仮想環境のpython.exeまでのパスを入れて追加します。

Pystanを使ったコードは下記のサイトに書いてあるものと全く同じコードで試しました。
Pystanのインストール(anaconda環境) - Qiita
エラーが出なければ成功です!実行結果のプロットはこんな感じ↓

Pystan実行結果


非Anaconda環境でPystanを入れる

Anacondaじゃない環境かつWindowsでPystanをインストールしている記事が全然なくて、こちらは相当苦戦しました...自分が今まで仮想環境を作ったことがなく仮想環境とは?というところから調べ始めるレベルだったことや、時系列的には先にこっちで環境構築をしてからAnaconda環境で作業をしたこともあって、本当にきつかったです。調べているときになんとなく思いましたが、Pystanを使うならAnacondaかLinux環境がメジャーなんだろうなと感じました。Windowsでインストールするのは多分酔狂なんだと思います...笑
こちらはPython+ venv+ VSCodeで行いました。主に参考にしたサイトは下記のサイトです。
a. VSCode+ Python3の仮想環境構築について:

b. venvを用いた仮想環境構築について:

c. 非Anaconda環境でPystanをインストール:


インストール環境

Windows 10 64 bit
Python: 3.8.10

仮想環境の構築

作業は基本的にWindows PowerShellで行っています。
最初に、仮想環境を管理するためのフォルダーを作成します。将来複数の仮想環境を作ったときに、すべての仮想環境をこのフォルダー内に入れるイメージです。Anacondaは自動でenvsというフォルダーに全ての仮想環境が入ってくれるので非Anaconda環境でしかやらない作業だと思います。自分はC:\Users[ユーザー名]\AppData\Local\Programs\Pythonディレクトリ直下にvirtualenvsというフォルダーを作成しました。
次に、PowerShellディレクトリをvirtualenvsまで移動させ、そこでPythonのバージョンを指定して仮想環境を作成します。仮想環境の名前はpy38_pystan2_17にしました。
py -3.8 -m venv py38_pystan2_17
これだとAnacondaで作った場合とは違ってパッケージが何も入っていないので、ローカル環境で色々入れていたパッケージをまとめて仮想環境に複製しました。複製のやり方はbの「仮想環境のライブラリを共有」の部分を参考にしました。
その後、numpyとcythonが入っていることを確認したらPystanをインストールします。この時Pythonとの相性の良し悪しがあるのでバージョンに注意します。ここではcと同じバージョンを入れています。
pip install pystan==2.17.1.0

C++コンパイラのインストール

こちらではcのサイトと同様に、C++コンパイラとしてMicrosoft Visual C++をインストールしました。
ダウンロードページから「Build Tools for Visual Studio 2019」インストーラをダウンロードして実行します。(下の方のメニューにあります) Download Visual Studio 2019 for Windows & Mac

インストーラが起動したら「C++ Build Tool」にチェックを入れてインストールします。

VSCodeで実行

ここはAnacondaの時と大体同じです。
まずは仮想環境を選択します。適当なpythonファイルを開き、Python: Select Interpreterを押します。出てきたPythonの環境の一覧から今回作った仮想環境(自分の場合はpy38_pystan2_17)を選択、なければEnter interpreter path を押して仮想環境のpython.exeまでのパスを入れて追加します。ちなみに、aに書いてあるように仮想環境管理用のディレクトリのパスをVSCodePython: Venv Pathという設定項目に追加したのですが、なぜか実行環境選択画面に出てこなかったので、結局手動でpython.exeパスを追加しました。
最後にPystanを使ったコードを実行します。ここではcと同じコードを実行しました。0に近い値が出力されれば成功です! 


感想

とりあえず自宅PCでも社用PCでもStanでベイズ統計モデリングを勉強する準備が整ったので良かったです。初めての環境構築、めちゃくちゃ時間かかりました。特に非Anaconda環境での環境構築は鬼のようにしんどく、エラーに次ぐエラーを経験し英語のサイトなども見回って何とかインストールできました。仮想環境の知識がないだけでなく、コンパイラ、パスを通す、Pythonとパッケージのバージョンの相性、pipとcondaの違いなどなど、あまりにも知らないことが多かったので一つずつ地道に学んでいきました。おかげで学びは多かったですが、正直もう非Anacondaで環境構築をしたくない...
とはいえ、データエンジニアリングはどれだけ学んでも損はないと思うので、これからもコツコツと勉強していく所存です。

ではでは。

『機械学習を解釈する技術』を読みました

※2022年6月に書いた記事を再投稿したものになります

こんにちは、今回は『機械学習を解釈する技術』という本を読んだので、簡単な感想+αを残しておきたいと思います。

機械学習を解釈する技術』の感想

昨年の夏に出版された本で、発売当時からなんとなく気になっていたのですがなかなか読む時間が作れず、今年のGWに10連休を生成して一気に読みました。

個人的な感覚として、この本のテーマにもなっている機械学習の解釈性は近年話題になってきている印象があります。
書籍冒頭の内容とも被りますが、データサイエンスが発展してきてデータを使って予測するアプローチも多様化・複雑化してきました。機械学習を用いた手法はメカニズムが複雑なものが多く、予測精度は高くてもモデルの結果を解釈しにくいという難点があります。実務でも機械学習を使ったことがありますが、実際にモデル結果を踏まえてアクションにつなげるためには解釈が重要になることも多く、「なぜそういう結果なのか」「予測のためにどの変数(特徴量)が大切なのか」といったことが分かると納得感のある(≒価値のある)分析になるなという印象があります。機械学習の解釈性は、より複雑な手法を実用に応用するための架け橋になるようなトピックなのではないかと勝手に期待しています。

この本は機械学習を解釈する技術を各章で一つずつ紹介しており、各章ではその手法の基本コンセプト・アルゴリズム・実際のデータを用いた説明が書かれています。各章が同じ構成になっているので読みやすく、コードや図が豊富で説明が丁寧なので理解しやすかったです。全体を通してストレスなく読み進められました。

紹介されている解釈の技術は下記の4つでした。

  • PFI(Permutation Feature Importance):予測モデルにとってどの特徴量が重要かを知る
  • PD(Pertial Dependence):特徴量と予測値の平均的な関係性を見る
  • ICE(Indivisual Conditional Expectation):個別のデータごとに特徴量と予測値の関係を見る
  • SHAP(Shapley Additive Explanations):予測値が出された理由を知る 集計などで粒度を変えることで個別データにも全体のデータにも適用できる

PFI→PD→ICEの順でマクロ(モデル全体の概要を知りたい)→ミクロ(各データごとの解釈をしたい)な解釈になっており、必要に応じて使い分けることができます。また、SHAPは個別データにも全体データにも適用できるので、ミクロ・マクロの両方に対応しています。これらの技術についてロジックやコードでの説明があり、上記の解釈がどのようにして可能なのかが分かるようになっていました。この4つの中でSHAPのロジックは他トピックに比べて少し難しかったので、もう一度見直したいなという気持ちがあります。

結果の解釈と因果関係

この本を読む中で個人的に気になったのは因果関係として解釈していいのか?という話です。例えば、PFIを用いるとモデルに使用した特徴量の重要度が出てきますが、これで重要な特徴量だからといってモデルの予測値を大きく上昇・下降させるとは限らないというのは解釈の難しい一面ですね。PDから特徴量と予測値の関係を出すことができますが、ここでも因果関係とみなすには注意が必要で、本の中ではモデルが特徴量と目的変数の関係を正しく学習していないと因果関係と解釈するのは危険と書かれていました。

最近因果推論の勉強をしているのもあって、このあたりの話は本当に難しいなあと感じています。
因果推論の勉強をしていると統計的に因果関係を把握するためには結構制約の強い仮定を置いているなという印象があり、完全にデータから統計的・数理的な処理を行うだけで因果関係を明らかにするのは実務では基本的に困難なのでは...?と思っています。いわゆるデータ分析の範囲ですべてを明らかにするというより、分析結果にドメイン知識や現場の人が持っている感覚といったものを組み合わせて解釈を深めていくのが(少なくとも自分が経験してきたような)実務では現実的な気がしています。今の時点では、どれくらいデータが豊富にそろっているかによって、分析結果とドメイン知識・感覚のバランスをうまく変えていくのがデータ分析の一つの落としどころかな、、と思っています。この「どれくらいデータが豊富にそろっているか」がキーで、データ量・変数の種類・時系列的な粒度(月次・週次・日次)・データの作られ方(アンケート、何かのログ、パネルなど...)などの様々な観点で「豊富かどうか」がデータ分析からどこまで強い情報が得られるかにかかってくると思います。分析手法の理解だけでなく、材料となるデータへの理解やドメイン知識への理解を踏まえて、総合的に解釈を深めていくのが大事なのではないでしょうか。
総合的に解釈というと聞こえはいいですが、分析結果とドメイン知識を組み合わせるときに示唆を恣意的に捻じ曲げることにならないかの判断は特に注意すべきだと思います。例えば分析結果と仮説や業界での常識が一致しないとき、データや分析手法側が不十分なのか実際に新しい示唆なのかを判断するのは非常に難しいです1。ビジネスの文脈だとどうしても都合のいい方に結論を持って行ってしまう傾向がありますが、分析者側としては元データや分析手法の特徴を深く理解したうえで、その示唆がなぜ出てきたのか、どれくらい確からしいのかをしっかりと説明できることが理想だと思います。解釈をしっかりと深めた状態でプロジェクトにかかわる色々な立場の人と議論を重ね、最終的な結論に到達する、という流れがきれいにできると分析者としては幸せだろうなという気がします。

おわりに

というわけで感想でした!(後半は本の内容と直接関係なくなってしましましたが...)
分析の解釈と予測という軸は、データ分析が盛んなうちはなくならない問題なのではないでしょうか。データサイエンティスト歴も1年を超え、実務をしていく中で少しずつ見えるものが変わってきましたが、技術のインプットと実務でのアウトプットを意識しながら引き続きやっていく所存です。

ではでは。


  1. 分析結果と仮説が一致するときもまた注意が必要だと思っていて、すぐ鵜呑みにせずに本当に妥当な結果なのかを考えるべきだと思います

ベイズモデリング学習記録

※2021年11月に書いた記事を再投稿したものになります

こんにちは。夏ごろからふわっとベイズモデリング関連の勉強をしてきたので、個人的な感想を交えつつ軽く振り返りたいと思います。
ベイズ統計の基礎は知っていたものの、ベイズモデリングについてはなんとなく名前を聞いたことがある程度で詳しいことは知らない状態から勉強を始めました。ベイズ統計の書籍はRのものが多く、自分はあまりRを書かないのでどことなく勉強を後回しにしていたのですが、応用の幅が広そうなのと結果の解釈がしやすい、また実務向きでもあるという話を聞いてついに手を伸ばしました。



学習記録

主に下記2冊の書籍で学びました。また、いくつか外部のセミナーにも参加しました。
書籍は『RとStanではじめる ベイズ統計モデリングによるデータ分析入門(実践Data Scienceシリーズ)』(馬場真哉)と『StanとRでベイズ統計モデリング』(松浦健太郎)で学びました。

最初は『RとStanではじめる ベイズ統計モデリングによるデータ分析入門』から読みました。この本は理論編・基礎編・実践編・応用編からなり、ベイズモデリングの基礎から実践的な分析手順、階層ベイズや状態空間モデルといった応用トピックまでバランスよく載っていました。いずれも説明が丁寧なのとRによる実践例が豊富で、個人的には大満足な1冊でした。実践部分だけでなく理論的な話も最低限を丁寧に記述している感じがあり、自分のような数式を見て納得したいタイプの人でも心地よく読み進められました。Rをあまり書いていなくても、サポートページとサンプルコードの説明が丁寧だったので苦痛なく理解できました。この本を読めばRによるベイズモデリングのやっていることを一通りは理解できると思ったので、これからベイズモデリングを学ぶ人にはぜひとも最初の1冊におすすめしたいです。

次に、『StanとRでベイズ統計モデリング』を読みました。こちらは通称アヒル本と呼ばれていて、界隈では有名な本ですね。1冊目の本に比べると、内容としてかぶっている部分もあるのですがより踏み込んだ部分もあり、こちらの本の方が読むのに時間がかかりました。内容として、ベイズモデリングの基礎的な手順、階層ベイズ、状態空間モデルといった部分はどちらの本でも記述があります。実践Data Scienceシリーズの方は、これらの手法の紹介に加え、Rでの可視化や処理の方法、rstan以外のベイズモデリング関係のパッケージについても記述があります。一方でアヒル本はR関連の記述は最小限で、その分Stanの踏み込んだ文法やベイズモデリングがうまくいかない場合の対処法といった入門書+αのような内容の記載がありました。また、多くの章に練習問題がついており、これを解くことでかなり力が付くような気がしました(時間と気力の都合ですべては解いていませんが...)。

ヒル本はベイズモデリングの入門書ではあると思いますが、Rや統計や数学の基礎についてはある程度知っている前提で書かれていると感じたので、この辺りは別の書籍などである程度学んでおかないと読むハードルが高いなと感じました。自分の場合、Rのコーディングで分からず調べることが多く、かなり時間を使いました。逆に言うと、この本を隅々まで理解できると基礎的なベイズモデリングを理解できるだけでなく、それを自分で設計して実行する力がしっかり身につくと言えそうです。


所感

セミナーや社内勉強会でも聞いたのですが、ベイズモデリングは精度と解釈性を両立できるという利点があるのが非常に魅力的だと思いました。ただ、これを両立させるにはベイズモデリング・実行する言語(R・Stanなど)への理解が高いだけでなく、分析対象への深いドメイン知識も必要だと感じています。また、実務でベイズモデリングを行う場合、プロジェクトにかかわる他部署の人や顧客のリテラシーも立ちはだかります。分析でお金を得る場合、たとえメリットがあっても分析結果を求める相手に価値があると思わせないとそもそも使えません。また、単純な回帰分析や集計に比べると工数が多く必要だったり分析環境をある程度整える必要があったりすることも障壁になると思います。

こういった課題はありますが、実際勉強をしてみるとそのポテンシャルの高さはかなりあるような気がしました。そしてそのポテンシャルを十分にかつ正確に引き出すにはかなりの専門性を必要とする印象があるので、もう少し掘り下げて理解を深めていきたいなと思いました。

以上です。ではでは~

Kaggle本

※2021年6月に書いた記事を再投稿したものになります

今回は、『Kaggleで勝つデータ分析の技術』という本を読んだので、概要と感想を書いていこうと思います。





購入動機

本のタイトルにもあるKaggleですが、これは分析コンペを開催している中で一番有名なプラットフォームですね。自分も存在は知っていたのですが、挑戦したことはありません。いつかやろうとは思っているのですが...

この本を買った目的ですが、「Kaggleを始めるため」ではなくPythonでモデルを作成したり評価したりする過程を実装してコードへの理解を深めるため」に買いました。というのも、今まで数理統計を勉強したりはじパタを読んでちょっと機械学習の原理を学んだりはしたのですが、プログラミングで実際に分析をした経験が乏しく、これから本格的に仕事をする上で確実にここがボトルネックになると思ったからです。一応、学生時代に前処理をするインターンはしていたのですがモデリングは本当に経験がなく、この本はちょうどその部分が豊富に書かれているので自分の需要にマッチしていました。


概要

ざっと内容に触れると、分析コンペとはどのようなものかという説明が最初にあり、その後実際の分析の流れを章に分けて説明している、といった感じです。分析の流れの説明として、どんな分析の種類(回帰なのか分類なのか、など)があってモデルや予測値をどう評価するのかといった話が最初にあり、その後以下の流れで章ごとに説明されています。

前処理

代表的なモデルの説明

モデルの評価方法

モデルのパラメータチューニング

複数のモデルを組み合わせる

それぞれの章ごとにPythonでのコードがgithub*1で配布されており、かなりのボリュームがあります。各章では本当に様々なトピックについて触れていて、ほとんどのトピックに対してコードがあるので実際に手を動かしながら理解することができます。分析の各フローの実装という面では相当網羅的かつ説明も分かりやすく、しっかりと読めば実務でも力になるような内容だと思います。

個人的に特に理解が進んだのがバリデーションの概念です。バリデーションはモデルを評価するときに使うテクニックで、学習データをすべて学習させるのではなく、一部を評価専用のデータ(=バリデーションデータ)として取っておいて、それ以外の学習データで作ったモデルをバリデーションデータで評価するというものです。こうすることでモデルの精度を確認することができます。学習データ全てを使ってモデルを作成すると、テストデータ(説明変数しか入ってなく、目的変数の情報がないデータ)で予測することはできますが、モデルの評価はできません。知ってる人からしたら超基本かもですが、バリデーションが精度の確認やモデルの改善のためにいかに重要かを実感できました。

他にも、実際にモデルを実装できたのがすごい良かったです。よく使われているモデルとして勾配ブースティング木とニューラルネットワークの説明と実装があり、今まで学んでこなかった内容だったので新たな学びが多かったです。余談ですが、ニューラルネットワークを実装するためにKerasとTensorflowの環境を作るのに苦労しました...今回はローカル環境にぶち込んでギリ回りましたが、バージョンの関係でKerasとTensorflowが競合する気配があったので、今度これらを使う時までに仮想環境を作ろうと思います。この辺も疎いので学ぶ必要がありますね...

感想

購入動機の方でも書きましたが、自分の知りたいことがたくさん書かれていたので、すごいためになりました。特に、実務という面で考えるとプログラミングを書く場面は必ずあるので、実践的な力がついたかなと思います。とはいえ、Kaggleで使うことを意識した内容なので、精度を上げることが最重視で解釈性はあまり考慮されていません。一方で実務では(業務によりますが)解釈性がかなり重視される傾向にあるので、精度をただ上げるだけではあまりビジネスに直結しないということを念頭に置く必要があると感じています。
あとこの本は参考資料が本当に充実していて、特にKaggleの上位ソリューションやコンペ関連の引用は激豊富なので、もしKaggleを始める場合は強い味方になりそうです。


本の内容とは関係ないですが、最近データエンジニアリング的なスキルの必要性をひしひしと感じています。プログラミングのスキルはもちろんのこと、その環境やコードの品質管理などの重要性も徐々に感じてきました。このあたりが整うとかなり業務が効率化されると思うので、土台となる環境についてはこの一年間のうちになるべく整えてしまいたいですね。とりあえず現時点で思いつくのは、
- Gitでコードの品質管理とコードチェックをスムーズにする
- 複雑な分析を要求されたときのためにdockerで専用の仮想環境を作れるようにする
- デバッグしやすいエディタを使う:具体的にはJupiter NotebookからVSCodeなどに移行する
このあたりでしょうか。実務をする中で他にも効率化できる部分は見つかってくると思うので、どんどん整えていきたいです。今後は分析のスキルだけでなくこういったエンジニアリング系のスキルも磨いていこうと思います。

ではでは。