分析結果を現場で使ってもらう技術まとめ

　今年も書きます、アドベントカレンダー。去年は分析の技術的なことを書きましたが、今年は視点を広げて、私がデータサイエンティストとして分析を現場に使ってもらうために工夫したこと、用いたツール等をつらつらと書いていきたいと思います。「分析結果を現場で使ってもらう技術」という壮大なタイトルを付けましたが、あくまで私の経験ベースで、こんな方法もあるよといった感じです。
　年の終わりに、ゆる～い気分で見てもらえれば幸いです。

# はじめに～「使わせる」を科学する～
　データサイエンティストのスキルセットは**「見つける」「解く」「使わせる」**と言われます。[最強のデータ分析組織](https://www.amazon.co.jp/%E6%9C%80%E5%BC%B7%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E7%B5%84%E7%B9%94-%E3%81%AA%E3%81%9C%E5%A4%A7%E9%98%AA%E3%82%AC%E3%82%B9%E3%81%AF%E6%88%90%E5%8A%9F%E3%81%97%E3%81%9F%E3%81%AE%E3%81%8B-%E6%B2%B3%E6%9C%AC-%E8%96%AB/dp/4822258912)

　私はこの定義をとても気に入っています。特に「使わせる」が入っていることが良いと思っています。これによって、単に予測精度を上げたりといった研究者的な側面だけでなく、後に述べるようにユーザーインターフェースをどうするかといったSIer的な側面を持たせてくれたと感じます。私自身、SIer寄りのデータサイエンティストをしているのですが、この「使わせる」を科学的に考えることが、最近非常に楽しくなっています。意外と、この「使わせる」にフォーカスした技術本ってあまり見かけないなと思ったりもしています。
　はじめに、「使わせる」と「見つける、解く」をデータサイエンティストのメンタルに焦点を当てて、比較してみようと思います。データサイエンティストにこの３つのどれが一番好きですか？という問いを投げると、「使わせる」が３位になると勝手に予想してます。（１位：解く、２位：見つける、３位：使わせる）
何と言っても１位の「解く」に関しては、
・宇宙の画像から新しい天体を検知する。
・ユーザーの口コミから、その人の購入アイテムの確率を予測する。
・機械の消費電力の総和が最小化されるように、機械の起動順序をスケジューリングする。

等々、どれも知的好奇心が湧くものばかりです。ほとんどのデータサイエンティストがこれらの問題を解きたくて、データサイエンティストになったのではないでしょうか。２位の「見つける」に関しても、
・商品画像の不正投稿を検知する。
・ニュース記事の内容から、その記事のタグ付けを自動化する。
・スタッフの満足度が最大化されるように、スタッフのアサインをスケジューリングする。

等々、過去に解いたものを使って、同じ技術でこんな問題も解けそう、、という発想が湧きます（実際に解けるかは別として）。これぞ、「見つける」の醍醐味であると言えます。これも知的好奇心が湧きます。新しい研究テーマを見つけるような感覚です。

さて、３位の「使わせる」に関しては、解くの例に対応させて考えれば、
・実験担当者に実際に、そこに天体があるか実験してもらう。
・マーケターにユーザーの購入確率（スコア）から、Webのコンテンツを出しわけてもらう。
・現場のスケジュール担当者に結果を渡して、そのスケジュールで実行してもらう。

.....なんというか、急にサイエンスから距離が離れたように感じないでしょうか。。。極端な人なら、自分の役割は果たしたのだから、「使う使わないは、おれの知ったことではない」という人もいてもおかしくないかと。。（仕事としてそれはダメなのだが）
　最近はこういったアルゴリズムは開発したが、それが現場に接続されずに腐っていくケースに対して**「POC貧乏」**というワードが名付けられています。私は、長年データサイエンティストをしていますが、非常によく見たケースです。
　以下では、これに対して私なりに解決してきた方法をメンタル面と技術面の両面から解説していきたいと思います。前提として、使わせたい分析結果が出ている状況であることはご容赦ください。


# 「使わせる」に知的好奇心を持とう！
　「解く」に関する事柄をもう一度並べてみます。
・最近流行りのDWHで、高速SQLを実装する。
・最近流行りのニューラルネットワーク-アーキテクチャをpythonで実装する。
・最近流行りの最適化ソルバーをpythonで実装する。

等々、テクニカルなワードたっぷりです。しかし、「使わせる」という話になった途端、使う側は上に挙げた３つとも知ったこっちゃありません。それよりも、現場担当者の考えに沿うか、業務オペレーションに合致するか、などなど「人の考え」や「実業務」にフォーカスする話であるためです。しかも人とはpythonとは程遠い、実業務を行っている方々（マーケター、現場の実業務者）です。そういった人の話に興味を持たないといけません。
　そこで、私がおすすめする方法は、**あくまでテクニカルな方法で「使わせる」と向き合えば良い**ということです。より具体的には、**pythonを使って、アプリを作ることで「使わせる」を実現すればよい**ことです。そうすることで、自身の知的好奇心を逸脱せずに（テクニカルな分野から離れずに）、これらの問題に向き合うことができると考えます。
　敢えて対局的な考え方と挙げるとすれば、**社内政治を駆使する**とかでしょうか。例えば、担当者の部長に先に報告して、トップダウンで結果を使わせるように促してもらうというプロセスも考えられます。これは一般論として、そういったスキルが求められる場面もあるのでしょうが、データサイエンティストにそれを求めるのは酷だと思います。
　後半では、データサイエンティストの得意技であるpythonを用いて、より具体的に「使わせる」を実現する方法を述べていきたいと思います。

# pythonで、小規模アプリケーション開発のススメ。

## 1. パワポは大事だが、一方通行になりがち。
　私の経験上、いくら、難しく精度よく問題を解いたとしても、そのプロセスの出口として、
**・結果の表やグラフをパワポに貼って、プレゼンテーションをする**
にとどまっていることが多く見られます。如何に、うまく、早く最新のアルゴリズムを駆使して問題を解いたとしても**出口はパワポ**であることがほとんどです。私はこれは、学会発表といったアカデミック文化に起因していると考えます。**アカデミックな世界では動くものは求められません**。論文の執筆なら、表とグラフと文章でよく、学会では静的なスライド（パワポ）で良いとされるためです。データサイエンティストには元々アカデミック（大学院修士以上）な方が多く、ほとんどがアプリケーションの開発経験がないように思います。パワポ業務自体を完全否定するわけではありませんが、私はパワポの致命的な弱点として、
・分析者の一方通行なメッセージになってしまうこと。

が挙げられると思います。どんなにわかりやすく論理立てて作ったとしても、聞き手が介入する余地がないのです。私の経験上、これは経営層といった上位層には評価されやすいのですが、実際に実業務を行っている現場の方々には、残念ながらあまり評価されずらいように思います。


## 2. 「実行ボタン」を作り、双方向のコミュニケーションを作る。
　現場層に受け入れてもらうためには、現場の実務を深く理解しているというのが伝わる必要があります。すなわち、双方向のコミュニケーションが必要です。加えて、私が重要視していることは
・相手にも手を動かしてもらう

ということかなと思います。後半にも示しますが、アルゴリズムへの入力ファイルを現場の方に準備していただき、そこから何かしらの「実行ボタン」を押して、結果が返ってくるというのを体験してもらうことです。こういった一連の**体験を提供する**ということが現場とアルゴリズムが結びつくポイントではないかと思います。これにより、準備するデータを変えれば、結果も変わるため、未来のシミュレーションをアルゴリズムを知らない人自身が体感できます。そして何より**面白いと思ってもらうこと**です。こういった双方向のコミュニケーションを作り出すことが、アルゴリズムへの抵抗をなくし、人間と機械の調和を生むと考えています。


## 3. アプリ開発＝データの可視化の延長と捉える
　２で書いたように、アプリ開発は重要だとは思いつつも、「データサイエンティストがそこに知的好奇心を持てるか、モチベーション高く取り組めるか」という問題は残っています。これに対し、私がおすすめしたいのは、**アプリ開発をしているのではなく、インタラクティブなデータの可視化をしている**と思うことです。
　対局として、「エンジニアがやるべきタスクをわざわざデータサイエンティストがしている」と思ってしまうかもしれません。ただ、これは極論です。ここで言っているのは、iPhoneアプリを作っているわけでもなく、BtoC向けのプロダクト開発をしているわけではないのです。すなわち、**１企業のin-houseで使われるツール**を指しています。なので、エラーが出たら1000万円の損失を被るようなものを作っているわけではないのです。あくまでインタラクティブな可視化の延長としてアプリケーションがあると捉えてみると、「やってもいいかな」となるのではないでしょうか。


## 4. エンジニアにお願いするでは、ダメなのか？
　多くの人がアルゴリズムはデータサイエンティストが作って、アプリケーションはエンジニアが開発すれば良いのでは？と思うのではないでしょうか。もちろん、その考えも否定はしません。ただ、上でも書いた通り、ここで議論しているケースは、BtoC向けアプリではなく、１企業のin-houseで使うもので、利用ユーザーは多くても１０人程度です。そして、さらには研究開発が発端となっているサービスであって、ウォーターフォール開発のように要件定義書や詳細設計書が用意されているわけでもありません。ただ、データサイエンティストが作ったアルゴリズムを体感したいというだけです。すなわち、クオリティよりもスピードが求められる話ともいえます。正直、１週間～１か月くらいでちゃちゃっと作ってといった話です。例えば、エンジニアが考えるWebアプリケーションとは以下のようなプロセスを踏むのが一般的ではないでしょうか。

１. docker-composeを用いて、フロントとサーバーサイド、およびDBをそれぞれコンテナとして管理する。
２. サーバーサイドはflaskを用いて、APIを作る。特にGet, PostといったHttpのリクエストで管理し、レスポンスはJsonとする。
３. フロント側はVue.jsがReact.jsを用いて、画面を作り、AjaxでAPIサーバーをたたく。
４. 開発サーバーとデプロイサーバーを分ける。必要に応じてテストサーバーも立てる。
５．gitのmasterへのマージはGenkins（CIツール）を用いて管理する。テストツールはpytestかnosetestsを用いる。
６. ロードバランサーを立てて、リクエストをさばく。
７. 開発サーバーはflaskだが、Webサーバーは、ApachかNginxを用いる。
８. 非同期処理としてWorkerにはCelery、BrokerにはRedisを用いる。
９. ログイン認証には、クラウドの認証機能を使う。
１０. データベースはO/Rマッパーを用いてDDLを定義し、直接クエリを書くのではなく、Daoクラスを作成し、そのメソッドからクエリを実行する。

　私はこれらを否定しているわけではありませんし、批判しているわけでもありません。Webアプリケーション開発の教科書的には正しいのでしょうし、その手の人らからしたら当たり前の話か、足りない話で、なんなら古い話なのかもしれません。私が強調したいのは、**まだ取り組むのは早い**ということです。研究寄りのデータサイエンティストからすると、何語話していますか？と思うかもしれません。数週間でちゃちゃっと作るっていうのは、遠う温度感を感じないでしょうか。さらにアルゴリズムとも関係性もよくわかりません。どの部分がどうアルゴリズムと関係しているかもわかりません。そして、何しろこれをデータサイエンティストが学び取るのは、骨が折れます（もちろん、学ぶことを否定はしません）。ですが、研究的にアルゴリズムを作成した後に、これらに取り組むのは、急に話が変わりすぎているように思われないでしょうか。
　私はのおすすめは、こういう世界があるんだなぁと知りつつも**これらは後回しで良い、あるいは、そもそも必要か？**と考えることです。もちろん、将来的にこういった開発は必要になる可能性は年頭に置きつつ、敢えて一歩引いて、ユーザーに体験を提供することに主眼を置きます。


# データサイエンティスト向け-アプリ開発の方法
　さて、抽象論はこのくらいにして、ここからは「具体的に何をすれば良いの？」という問を考えていきたいと思います。ここまで読んでくださった方、ありがとうございます。
　ここからは、データサイエンティストの右腕であるpythonの世界です。pythonを使って、「使わせる」という問いを「解きに」行きます。
難易度と使ってもらえる度は私の主観です。ゆる～く見てもらえると助かります。

##方法1. jupyter-notebookのリンクを送る（難易度★☆☆、使ってもらえる度★☆☆）
　最初は、超小規模です。データサイエンティストが書いたjupyter-notebookのURLをそのまま、現場担当者に送ります。もはや、何も作っていないに等しいです。.ipynbファイルには、書き込み権限だけは、排除しておくのが良いでしょう。
　例えば、一番上のセルにパラメータの一覧を記述しておいて、ユーザーにそれを変更させて、上から順番にセルを実行してもらいます。その過程で、いろいろなグラフや表が見えてきます。そして、パラメータを変えれば、結果が変わるといった体験ができます。これもユーザーに体験を提供したという意味では、パワーポイントを超える価値があると思っています。しかし、問題も多くあります。

・セルに書いてあるpythonコードなんて知ったこっちゃない。
・自分でデータを用意できない。（ファイルのアップロードができない）。
・結果のファイルのダウンロードをするには、別のフォルダを見に行く必要がある（jupyterを理解してもらう必要がある）。

他にも考えられると思いますが、これは現実的ではないでしょう。。

##方法2. BIツールに結果を表示する（難易度★★☆、使ってもらえる度★☆☆）
　２つ目は、BIツールを使って、ダッシュボードとしてアルゴリズムの出力結果を表示するというものです。BIツールは、グラフを社内に共有するのに非常に便利なツールです。URLをチャットに流すだけで、誰でも見てもらえます。しかし、私はBIはマーケターといった方々向けには良いのですが、データサイエンティストが積極的に使う必要はないと思います。それは、

・python環境が装備されていないため、アルゴリズムはBIとは切り離されて実行される必要がある。
・自由自在にWebアプリケーションをデザインできない。

という点です。BIツールはGUIとしてデータをハンドリングできたり、簡単なSQLは使えたりするのですが、python環境が装備されていないのです。すなわち、scikit-learnやpandas, lightgbmといったデータサイエンティストお馴染みのツールを使うためには、BIツールとは別にpython環境が構築できる仮想マシンをオンプレかクラウドに用意する必要があります。
　さらには、「実行ボタン」を配置したり、結果のグラフが表示される場所を変えたりといったいわゆるフロント開発にも、自由自在に行えるわけではありません。「実行ボタンを押したら結果が返る」といった体験を提供するのには、不向きです。集計値をリアルタイムにモニタリングできたり、サクッと共有できたりするのは良いのですが、データサイエンティストが開発したアルゴリズムを組み込むといった高度化することにあまり長けていないように思います。

##方法3. pyinstallerで.pyを.exeにして配布する（難易度★☆☆、使ってもらえる度★★☆）
　３つ目は[pyinstaller](https://www.pyinstaller.org/)を使って、pythonファイルそのものを固めてしまうという方法です。
　後に述べるStreamlitやDashが登場する前は、私はこれを愛用していました。今でも、私がこれで作成したexeで、現場で動いているものは多数あります。何より画面を作らなくて良い、python環境を用意しなくて良いという大きなメリットがあります。特にpython環境を用意しなくて良い効果は絶大です。社内の共有フォルダに置いておくだけでアプリとして完成するのです。私が良く作っていた開発時のファイル構成は以下です。

```
src・・・pythonのファイルもろもろ
main.py・・・実行ファイル
input.xlsx・・・入力データ、パラメータを格納したファイル
```
これでコンパイルするときはには、

```
pyinstaller main.py --onefile
```
とします。--onefileをつけておくと余計なファイルが作成されずに済むので良いです。コンパイルしたあとは、

```
main.exe
input.xlsx
```
の２ファイルだけが出来上がり、main.exeをダブルクリックした後は、

```
main.exe
input.xlsx
output.xlsx
```

という具合に結果のエクセルファイルが作成されます。input.xlsxにユーザーが入力するパラメータやデータを格納しておくというのがポイントです。そして、各シートにはこの列には、このデータを入れるといったルールをこちらで設定し、現場の方々にそのルールに沿うようにデータを用意してもらうのです。こういったように**エクセルファイルでデータを準備していただく**というのは非常に重要です。これが上に述べた相手にも手を動かしてもらうという部分に対応します。相手にも手を動かしてもらうことで、一緒に物を作り上げる感覚を共有するのです。
　さらに、ポイントとしては、**input.jsonやinput.yamlではなく、input.xlsxであること**です。jsonやyamlは一般人が編集できるフォーマットではないためです。私はこれで、アルゴリズムだけでなくマーケ部署の月次の締めレポートを自動化したり等もしました。使ったpythonのライブラリはpandasのみです。そしてそれは長らく使われました。私はこれでデータサイエンティストでありながら、「問を解く」もいいけど、「使わせる」もそこそこ楽しいなと思うようになったきっかけでした。

ただ、欠点としてはやはり、、、
**・見栄えが良くない**

という点です。。やはり、画面があった方が作った感が出るというわけです。。

##方法4. StreamlitでWebアプリを作る（難易度★★☆、使ってもらえる度★★★）。
　４つ目は、最近めでたくversion1.0になった[Streamlit](https://streamlit.io/)です。これは知ったとき感動しました。
　streamlitの説明の詳細は他記事に多くあるので、割愛しますが、htmlの知識がなく、画面のデザインとjavascriptの知識がなくイベントの
ハンドリングを行うことができるのは非常に魅力的です。（いくつか強い制限があるのですが。）
私は**データサイエンティストがhtmlとjavascriptとcssを覚えるのはハードルが高い**と思っていました。右腕でpythonで、左腕はSQLで、できてしまっているので、もう新しい言語を覚える空きはないのです。。そういった壁を見事に解決してくれました。
ここでは、私がよく使うコンポーネントを紹介します。

```python
import streamlit as st

st.uploader()#・・・input.xlsxをアップロードする
st.selectbox()#・・・パラメータを選ぶ。学習する期間と予測する期間等。
st.button()#・・・アルゴリズムの実行。
st.download_button()#・・・アルゴリズム結果（output.xlsx）のダウンロード。
```

方法３のpyinstallerでやっていたことをWebで提供できるようになりました。さらに必要に応じて、結果のグラフをWeb上に表示する。
このWeb上に表示できる点がpyinstallerではできなかった良い点だと思います。
ただ、欠点としては
・高度化しようとすると、Dockerを用いて実行環境を整備する必要がある
・非同期処理ができない

などかなと思います。
　１つ目の実行環境に関しては、最近streamlitのCloud版が登場し、外部にデプロイできるようになったようですが、やはりセキュリティ的にも、自社サーバーの中にデプロイしたいという場合が多いです。そういった場合、Dockerで環境構築する必要が出てきます。Dockerなんて簡単じゃんと思うかもしれませんが、**データサイエンティストにDockerFileはハードルがある**と思っています。その理由は、純粋にpythonではないからです。やはりpythonを逸脱しないことが重要に思います。
　２つ目の非同期処理とは、機械学習でモデルを学習するといった長い計算の処理を裏で回しておく処理です。そういった場合、実行ボタンを押した後に、例えば、ブラウザを誤って閉じてしまったり、F5ボタンを押されたりしても影響を受けずに、裏で回り続けている必要があります。実行ボタンを押した後に、F5ボタンを押されると死ぬ、、、というのは悲しいです。こういった非同期処理の扱いは、Streamlitの標準機能としはまだまだ用意されていなく、今後を期待する必要があるような気がしています。


##方法5. DashでWebアプリを作る（難易度★★★、使ってもらえる度、**未知数**）。
　最後に紹介するのは、Dashです。こちらも、かなりメジャーになってきたのではないでしょうか。Dashにはオープンソースとして使えるものと、Dash-Enterpriseという有料版があります。オープンソース版だけであれば、streamlitの方が使いやすいように個人的には思います。
　特に、dash-html-componentsはpythonでhtmlを記述できるというものですが、これもpythonとはいえ、やはりhtmlの仕組みを覚えることに変わりないためです。その代わり、enterprise版であれば、[dash-design-kit](https://plotly.com/dash/design-kit/)というものが使えるようです。
　これを使うことで、streamlitと同様にhtmlを知識を用いることなく、コンポーネントを配置するだけで、フロント部分は作成できるようになるようです。さらには、
[dash-snapshots](https://plotly.com/dash/snapshot-engine/)という非同期処理を行えるライブラリが追加されます。
これにより、機械学習を30分回すといった、重たい計算を裏でずっと回しておくことができます。
　さらには、[デプロイ環境](https://dash.plotly.com/deployment)として機能もあることです（こっちがメイン説）
herokuにWebアプリをデプロイするのと似たような感覚でデプロイできます。これでおそらく、データサイエンティストがDockerFileを記述する作業から解放されます。
　さらに、公式からいろんな[アプリケーションのテンプレート](https://dash.gallery/Portal/)が提供されているのも興味深いです。ソースコードが見れるものと見れないものがありますが、こういったテンプレートが充実しているのも、アプリ初心者なデータサイエンティストにとっては非常にありがたく思います。

ただ、欠点としては私が感じたのは、
・callbackにはじめは慣れない
・layout（DOM）を定義することは慣れない

というのはあるかなぁと思いました。ここはStreamlitの方が書きやすいなぁと思っていますが、まぁ慣れの問題ではあるし、pythonから逸脱しないという意味では、許容範囲かなとも思います。

# まとめ
　いかがだったでしょうか。本記事では、データサイエンティストのスキルセットから始まり、アプリを作るモチベーション的な話を述べて、具体的にpythonを用いて、楽にアプリを作る方法をつらつらと書いてみた次第です。もちろんこれらだけが全てではないと思いますし、この領域はまだまだ発展途上なので、今後大きな進展があるような気もしています。「使わせる」に対して、どの手段を取ろうか迷っているデータサイエンティストの少しでも助けになれば幸いです！
　それでは、皆さん良いお年を！