機械学習ジャーニーのお供に

気になったことを書き溜めただけで一貫性のない弊ブログですが、「機械学習」というキーワードを入れた記事を出すと、アクセス数が増えるというのが最近の傾向です。それだけ機械学習熱が上がっていて、自分でも試してみようという人が増えているんでしょうね。

 

機械学習を進める上でのストレス要因

先日もCourseraの受講のことだったり、オススメ本の話を書いたりと、自分自身でも機械学習について学ぶという事は相変わらず続いているものの、いつもモヤっとした部分が残ります。

 

ライブラリの使い方とか、基本的なコンセプトは分かっても、その足元の部分、つまりデータを用意したり、そのデータを加工して大まかな傾向を掴むと言った機械学習の最初のステップのところの足元が弱いなあと思う今日この頃です。

 

仕事として機械学習を使っているプロの皆さんは置いておいて、私のように仕事とはあまり関係なく、機械学習に興味を持って飛び込んで、まずは機械学習の入門書から入った皆さんの場合、例えばPandasのデータフレームの使い方だったり、Matplotlibで自分の思うようにプロットしてみるという部分がうまく使いこなせていなくてストレスを感じているってことはないですかね?

 

私は結構ストレスになっていて、機械学習じゃなくて、データサイエンスのE-Learningでも受けようかと真剣に検討していたぐらいです。

 

こういうのを待っていた

そんな中、こんな本がつい最近出たのを見つけてしまいました。

 

この領域の本、これまでもあるにはあったのですが、日本語の本だと内容的に少し古くなったなと感じるものが多かったので、個人的には良いタイミングで出て来てくれました。

 

最終章のscikit-learnのところは手持ちの本でカバーできているものの、最初の4章分はまさにブラッシュアップしたかった内容でドンピシャです。結構分厚い本ですが、やりたい事がリファレンス的に参照できて重宝しそうです。

 

ちなみに英語版はテキスト含め全文Githubで公開されているので、中身をちょい見してから、日本語で深く読みたい!となれば購入してみるのはいかがでしょう?

 

お世話になった本たち

色褪せたみたいな事を書いてしまいましたが、自分の中ではいろいろなきっかけを与えてくれた名著です。

 

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

 

この本でNumpyとpandasの存在を知りました。

 

この本からJupyter Notebookにたどり着きました。



 

 

 

Coursera : Machine Learning with TensorFlow on Google Cloud Platform修了

4月の末から取り組んでいたCourseraのMachine Learning with TensorFlow on Google Cloud Platformの全5コースですが、週末や朝晩の通勤時間なんかも使いながら、約1ヶ月と少しで全5コース修了しました。一応、自腹でちゃんと受講したよという意味を込めて、修了証も晒しておきます。

f:id:deutschina:20180527111917p:plain
※ブログなので、一応名前のところはマスクしてあります。

自分なりにCourseraのこのコースを使って学んで良かったところ、そうでもなかったところを残しておきます。

良かったところ

講義形式の方がアタマに入る

やっぱり手を動かしながらとは言え、本を読むだけなのと、実際に講師の人が話しているのを聞きながらでは、後者の方がアタマに入りますね。どこが重要なのかだとか、しゃべり方のトーンとかでも伝わってくるので。色んなアクセントの英語が聞けて、聞き取りの強化にも役立ったかもしれません。

ちゃんと聞いていないとQuizは意外と難しい

演習形式には2つあって、1つは、Jupyter notebook的なDatalabを順に実行していきながら結果を確認するもの。もう1つはQuiz形式で、一定の割合の得点を取らないとコース終了出来ないというタイプのもの。Quizは時々すごい難しい(ちゃんと内容を理解して聞いていれば難しくないはず)ものがぶっ込まれてきて、8時間以内に3回トライできるところを3回失敗してというのが1カ所だけありました。つまり、そのぐらい真面目に聞いていないとダメなので、真面目に講義を聴くモチベーションが上がりました。

資料は結構充実

コードなどは、Githubのレポジトリから、自分用の使い捨てのDatalabへ毎回コピー(clone)して使う事になっているので、必要最低限の労力で、必要なところを学べるようになっているのは便利でした。ただ、githubにおいてあると言うことは、ファイル自体はコース受講しなくても手に入れることが出来r(以下省略)

改善して欲しいところ・難しいところ

裏では自転車操業だった?

今回のspecializationは全5コースで、例えば1週間という設定でコースが終わると、その次の週に次のコースが始まるというような流れになっているのですが、開始予定の日付にコースを始められるという事はほぼ皆無でした。例えば、5/11に開始するというコースに、日米の時差を考えて5/12にEnrollしよう思っても、Coming soonというお知らせが表示されて、コースがlaunchされたらメールで連絡するとのこと。実際にコースが始まったのは5/14、launchのお知らせは5/15に届くという感じ。自分は気が長い方だから良いですが(どこが?)、気の短い日本人のオジサンだと、1週間遅れじゃないか!とか因縁付けそうです。これは、コース立ち上げ直後にジャンプインしたいわゆる「1期生問題」だった可能性もありますね。

コースによって1週あたりの分量が結構違う

コースの長さが違うのは仕方ないと思うんですが、その量に応じて期間をもう少し柔軟に調整してくれた方が嬉しいかなと思います。例えば、Feature Engineeringは1週間で収めるには相当な分量だったのに対し、最後のArt and Science of Machine Learningは、3週間という期間にしては講義の長さも課題の多さも少なすぎたりというのは感じました。(これはフィードバック出しておきました)

これは、Feature Engineeringの真ん中ぐらいのタイミングで呟いたもので、1週間にしては分量が多すぎない?と心の叫びですね(笑)

ずぶの素人がいきなりこのコースは厳しいかも

今回、英語でコースを受講して、もちろん字幕が用意されている部分で助かっている部分もあったけど、これまでに英語での入門書を何冊か読んでいたおかげで、内容が理解できたという部分もかなり大きかったかと。自分の場合は、あまりアカデミックに行くつもりはなくて、使う方に興味が向いているので、アカデミックな日本語で書かれていて脳内変換が大変だった日本語版よりも、英語版の方がスーッと入ってく感じがしました。

scikit-learnとTensorFlowによる実践機械学習

scikit-learnとTensorFlowによる実践機械学習

Hands-On Machine Learning With Scikit-Learn and Tensorflow: Concepts, Tools, and Techniques to Build Intelligent Systems

Hands-On Machine Learning With Scikit-Learn and Tensorflow: Concepts, Tools, and Techniques to Build Intelligent Systems

ちなみにまだ続きがあるらしい

ネガティブっぽいことも書いていますが、結果的には投下したコストに見合う内容だったかなと、比較的満足度高かったです。一連のコースも最終盤になっても、そういえば自然言語だとか、画像解析とかあまり出て来ないなと思っていたら、「そこら辺は次のSpecializationでやるよ。See you around!」てなオチになってました。なので続編のspecializationが出たら、また受講しちゃうんだろうな。。。

iPhoneのHealthデータをエクスポートしてゴニョゴニョしてみる その5

この記事の続きです。

deutschina.hatenablog.com

iPhoneのHealthデータの加工の流れがあらかた出来たので、Nokia Healthから持ってきた歩数(activity)データとぶつけてみるところから。

いざ突合へ

イメージとしては、Nokia Health側のデータにiPhoneのデータをぶっ込む感じにしたいので、Nokia Health側のファイル(activity.csv)にレシピを追加していきます。最終的に追加したのはこんな感じ。

f:id:deutschina:20180523153739p:plain

最初にUnionして、合計しながらいらない列を消していくというイメージになってます。Nokia Health側の分析を省いてしまっていますが、簡単に言うと日ごとの歩数が既にファイルに用意されているので、iPhone側のファイルのように下処理はやっていません。

UnionとJoinは違う!

お恥ずかしい話、これをきちんと理解していなくて、何が起こっているのかに小一時間かかったのは、ここだけの話です。何はともあれ、2つのテーブル(正確にはcsvファイル)を1つに統合するために、Unionを使ったわけです。実際の設定内容はこんな感じ。

f:id:deutschina:20180523153734p:plain

Union Data(2)と書いてあるように、activities(.csvNokia)とexport20180520211840(.csviPhone)をガッチャンコさせています。日付の項目(Date)を共通にして、歩数が入る項目はStepsとmax_sum_valueはそれぞれ独立させて持たせています。後で出てきますが、両方の値が入っている場合は、Nokia Health側の値を優先とする関数を後で仕込むつもりです。

Unionを設定した後にレコードイメージ(画面に出ているのはあくまでサンプリングされた一部データというのは前回書いたとおり)を見てみたのですが、イメージ的には日付1レコードに対して、Stepsとmax_sum_valueの両方にそれぞれ値が入っていることを期待したのですが、実際にはどちらか片方にしか値が入っておらず、同じ日付のエントリが複数ある状態。なんで?と小一時間考え込んで達した結論としては、

・・・あ、UnionとJoinは違う

ということ。Unionはあくまで2つのテーブルをマージするのが目的。だから脳内で勝手にキーだと思っていた日付(Date)が被っても当たり前なんですよね。自分が想像していた結果を期待するなら、むしろキーを指定して同じキーであれば1つのレコードに統合するというJoinの方だったというオチでした。

そこで、この関数をJoinに差し替えることも少しだけ考えたのですが、どうせ後でAggregateするつもりだったので、そのまま行く事にしました。この時点では日付ごとにデータがサマリされているので、件数もせいぜい数千件程度になっているだろうという読みもありました。

最後の集計

ここで、ようやくNokia側とiPhone側の歩数データを1つのレコードに入れるために、Aggregateをします。

f:id:deutschina:20180523153729p:plain

Group byがDateなので、1日につき1レコードになり、同じレコード上のStepsとmax_sum_valueに、Nokia側の歩数とiPhone側の歩数が入ってきます。次のステップでは、Nokia型の歩数がない場合に限り、iPhone側のデータの歩数を採用するように、New FormulaでIF文を仕込んでいます。

f:id:deutschina:20180523153723p:plain

これで新しい項目に、最終的に自分の取り決めに沿って確定した「歩数」が入ってくるので、最後に古い項目(Steps, max_sum_value)をドロップ。

f:id:deutschina:20180523153714p:plain

これで一連の流れが完成します。

データの出力

データのフローはできたので、これに全データを読み込ませて、最終的に1つの完成された日ごとの歩数情報のファイルをcsvとして出力してみます。

f:id:deutschina:20180523161441p:plain

デフォルト設定のまま実行しちゃうのもアレなので、設定をいろいろ見ておくことに。

f:id:deutschina:20180523161436p:plain

ファイルは、BigQueryとしても出力できるのですが、今回は素直にcsvをcloudのバケットに出力しときます。

f:id:deutschina:20180523161430p:plain

詳細な設定をみると、ファイルを小さい単位に分割するかとか、CSVファイルの1行目に列名をインサートするかみたいな設定を行うことが出来ます。隠れてしまっていますが、ファイルを圧縮するための設定もあります。

f:id:deutschina:20180523161423p:plain

設定をして、ジョブを開始して、JOBSというリンクを見ると、ジョブのフローと現在どこを処理しているのかというのが見えたります。並列的に処理できるところは複数のジョブを同時に実行していたりするんですよね。

f:id:deutschina:20180523163835p:plain

できたものは。。。

ジョブが終わると、Cloudのバケットにファイルが吐き出されるので、これを開いて中身を確認してみることができます。で、早速開いてみると・・・。

f:id:deutschina:20180523165028p:plain

分かっていたけど、地味っすね。。。

とボヤきたくもなります。これが30分値とか1時間値だと、一日のうちでどの時間帯に多く歩けば、減量に効果があるかみたいなことも分かるかもしれないので、少し残念ですね。もちろん、今回はNokia Healthを優先するという取り決めをしたため、日単位で合計するしかなかったものの、秒単位でデータの揃っているiPhone側のデータを正にすることで、時間帯ごとのデータも取れそうだと言うことは付け加えておきます。

f:id:deutschina:20180523165036p:plain

最終的に出力されたデータの統計的な情報が見えたりするのもDataprepの素敵なところかなということで、無理矢理締めたいと思います。

(たぶんつづく)

Google Cloud Platform エンタープライズ設計ガイド

Google Cloud Platform エンタープライズ設計ガイド

iPhoneのHealthデータをエクスポートしてゴニョゴニョしてみる その4

この記事の続きです。

deutschina.hatenablog.com

やりたいことはだいたい自動提案されてくる

Dataprepを使っていいなと思うのは、処理した列を選択(クリック)すると、右側に処理候補がいくつか自動提案されてきて、やりたいことが、だいたいその中に入っているということ。

列の削除

例えば、この列いらないと思ってクリックすると、

f:id:deutschina:20180523083800p:plain

右側の一番上に、Delete column (列の削除)というのが表示されて、すでに選択された状態になっている。ここでAddをクリックしたら、ステップの追加は完了。これは簡単だよね。

列を追加して新しい関数を仕込む

f:id:deutschina:20180523083806p:plain

次は、startDateという日付+時刻の項目の中から、日付部分のみを抜き出す列を用意した部分(New Formula)。既存の列にDATEFORMATを被せるだけで良いのかなと思ったけど、あとで消せば良いので別項目に持って行くことに。

不要な行を消す

f:id:deutschina:20180523083810p:plain

いらない行を消すのは、Keep Rowsを使う。いらない行を消すというよりは、必要な行を残すという表現の方が合うかも。

行の合計

行を集約する場合は、Aggregateを使用する。

f:id:deutschina:20180523083815p:plain

この例では、歩数を合計するSUM関数を使い、さらにどの項目をグループ化するか(Group by)を指定してることで、各日ごとの歩数の合計が算出される。

f:id:deutschina:20180523083821p:plain

最後にもう1回Aggreageしているのは、同じ日に複数の入力系統からの歩数データがあることを確認したから。自分に甘い(笑)ので、MAX関数を使ったけど、例えば特定の入力系統だけを信頼するなら、Keep Rowsを使うという考えもあるし、採用すべき入力系統が日によって違うなら、AVERAGEを取るなり、自分に厳しい人ならMINを使うという手もあると思います。

長くなったので、記事を改めます。次はいよいよ2つのファイルをマージしてジョブを流すところまで行ってみたいと思います。

(つづく)

iPhoneのHealthデータをエクスポートしてゴニョゴニョしてみる その3

この記事の続きです。

deutschina.hatenablog.com

Google Dataprep登場!

ひとまずiPhoneのHealthデータを取り出すことが出来たので、いよいよNokia Healthのデータと突合してみます。Nokia Healthからの歩数データの記録が抜けている部分をiPhoneのデータで補完をするという話でした。pandasのdataframeでやるのも良いのだけれども、せっかくなので、最近Courseraで学んだGoogle Dataprepを使ってみることにします。

f:id:deutschina:20180522223827p:plain

これは、最終的にNokia Healthの歩数データとマージするところまでを含んだデータフローになってます。上のactivities.csvというのがNokia Health側のファイル、export20180520211840.csvというのがiPhoneからのデータの入ったファイル。最後に2本の線が1本にまとまっているのが、2つのファイルをマージするという流れを表しているわけですね。

マージすると言っても、2つのファイルが持っている項目が異なったり、そもそも歩数データ以外の(今は)必要のないデータも入っているので、そこらへんの整理からやる必要がある訳です。まずは、iPhone側のデータから。

レシピを作る

データを加工するにあたって、レシピというのを作り、その中にさらにステップを追加していくというのが基本の流れ。今回作ったレシピには、こんな感じで11ステップ含めてみました。

f:id:deutschina:20180523070902p:plain

これだけ見るとウヘーと思うかも知れないけど、やっていることはいらない項目をドロップ(Delete)しているのと、あとは日ごとに集計(Sum)して、さらにいらない行を消したりしている(Keep Rows)ぐらいで、特段難しいことはしていない。Dataprepでは、これらのステップをグラフィカルなUIで簡単に作れるのと、大量データでもきちんと対応出来る(生データは40万件以上ある)のが良いところかなと。

レシピの変更画面に入って、ハマったところなどを書き出しておこうと思います。

f:id:deutschina:20180523071709p:plain

列名とデータの間に分布の棒グラフが出るあたりが、既になんだか良い感じですよね。ここで、1つ注意しないといけないのは、ココに出ている分布だったり、画面の下にある行数というのは、全データではなくて、サンプリングされたデータであるということ。これを見落としてCourseraのテストでなかなかパスできずに痛い目に遭いました。

f:id:deutschina:20180523072633p:plain

冷静に見ると分かるのですが、40万件のデータがなぜか4万件程度になっており、自分が使ったデータの場合はだいたい10%位のデータだけが抽出されていたと言う事になります。と言っても、ここに載っていないデータが処理されないという意味ではなく、あくまでこの画面での表示上の話。ちなみに、この画面にあるInitial sampleというリンクをクリックすると、いま抽出されているサンプルの情報が表示されます。例えば、表示されているサンプルが偏りすぎているみたいな場合は、サンプリングをやり直す事が出来ます。ただ、Dataflowのジョブが流れて、それなりに時間が掛かる(そしてリソースを消費するので、わずからながらに課金される)という事はアタマの片隅に入れておいた方が良いと思います。

f:id:deutschina:20180523073818p:plain

新しいサンプルを作って選択したところ。画面に表示されているサンプルの内容、値の散らばりが変わっているのが分かる。

長くなったので、続きはまた今度。

(つづく)