機械学習クソ素人の俺がプロダクトをリリースするまでの2ヶ月で覚えたこと


scikit-learnでちょっとした機械学習をするのは、LAMPでちょっとしたWebアプリをつくるよりも簡単です。
下記に自分が入門してから2ヶ月間で覚えたことをまとめました。


##ハイライト
1. 重要だと思ったこと3つ
2. 機械学習の概要
3. scikit learnについて
4. Google Prediction API,Mahout,Spark,Cythonについてそれぞれ一言所感

##重要だと思ったこと3つ
###1.機械学習に明るい友人をもつこと
どんな技術でもそうだけど、友人に聞いて概要を先に掴んでおくと自信を持って進めることができます。この自信を持っていると心が折れにくくなります。
@fukkyyに「入門サイトは難しい用語つかってビビらせてくるけど、ライブラリを使えば機械学習はこわくない」と教わり、巷にある入門サイトを無視してライブラリをたたき始めたので入りやすかったです。
@ysks3nに次元削除や各アルゴリズムの使い分け等、いろいろアドバイスをもらいました。
基礎の基礎でよければ私がハンズオンで教えることができるので、[興味がある人がいたら声をかけてください](http://qiita.com/puriketu99/items/7370901978887fe59a49).

\#両名ありがとう！


###2.学習用データの縦と横のサイズダウンをすること

######縦と横なら、程度の問題もあるが、横を削る方がパフォーマンスに貢献することが多い

思うままにライブラリにぶちこんで捌けるデータ量は自分の想定よりも遥かに低かったです。
30GBくらいのデータなら何の加工もせずにいけるだろうという根拠のない思い込みがありました。
次元圧縮(横のサイズダウン)をするライブラリがscikit-learnにあるので、それを使うとよいです。下のサンプルコードに次元圧縮の仕方は書きました。
少ない次元から始めて、増やしていくと正解率がサチるところがあるので、そのへんでやめるとよいです。
縦のデータも、学習に関係ないなら削った方がいいです。


###3.理論を勉強するよりもコードを書いた方が速いということ

上記にも書いたとおり、巷には小難しい入門サイトがあるが、入門者は理屈の勉強よりも先にサンプルコードでいいと思います。あと、機械学習は様々なモデルを適宜用いて学習を行いますが、各モデルを細かく勉強すると小難しいことが書いてあって熱を無駄に浪費しがちなので、scikit-learnを使うなら、モデルを全部試して正解率が高かったやつを使えばいいと思います。一行書き換えるだけでモデルを切り替えられます。下の方にサンプルコードを書きました。
もっと精度が必要かつその余裕があるなら勉強しよう。



##機械学習の概要

(教師ありの)機械学習は、大きくわけて2つあります。

###1.回帰
データから数値を予測するための手法です。
たとえば、下記のように、過去の天気、場所、日付から気温との関係を学習し、次に天気と場所を入力したときに気温を予測するときなどに使います。

####まず、次のようなデータを学習し、特徴(天気と場所と月日)と気温の関係を学習します
|気温|天気|場所|月日|
|-----------:|:------------|:------------|:------------:|
|19|晴|東京|111|
|29|雨|大阪|311|
|19|曇|福岡|121|
|29|晴|熊本| 11|
|39|雨|京都|311|
|29|曇|愛知|131|
|19|晴|奈良|211|
| 9|雨|石川|141|
|49|曇|地獄|151|

####次に、学習結果を利用して、特徴が与えられたときの気温を予測します

|気温|天気|場所|日付|
|-----------:|:------------|:------------|:------------:|
|?|雨|東京|111|


###2.分類
データから分類を予測するための手法です。
たとえば、読んだ本と男女の分類の関係を学習し、次に読んだ本の情報を入力したときにその人物の男女を分類するとき等に使います。

####まず、次のようなデータを学習し、特徴(各漫画を読んだか読んでないか)と性別の関係を学習します
|性別|最強伝説黒沢|ハンターハンター|ガラスの仮面|
|:-----------|:------------|:------------|:------------|
|男|読んだ　　|読んだ　　|読んでない|
|男|読んでない|読んだ    |読んでない|
|女|読んでない|読んだ　　|読んだ    |
|男|読んでない|読んだ　　|読んでない|
|女|読んでない|読んだ    |読んだ    |
|男|読んだ　　|読んだ　　|読んでない|
|男|読んだ　　|読んだ　　|読んだ    |
|女|読んでない|読んだ    |読んだ|
|男|読んだ　　|読んだ　　|読んでない|


####次に、学習した結果を利用して、特徴が与えられたときの性別を予測します

|性別|最強伝説黒沢|ハンターハンター|ガラスの仮面|
|:-----------|:------------|:------------|:------------|
|?|読んだ|読んだ|読んだ|




\#教師なし学習のクラスタリングというものもありますが、それは自分が扱っていないので、今回は除外します




##scikit learnについて

どんな人でも一応機械学習ができる夢のようなライブラリです。


```python:sk_learn_sample.py
# -*- coding: utf-8 -*-
from sklearn.svm import LinearSVC
from sklearn.ensemble import AdaBoostClassifier,ExtraTreesClassifier ,GradientBoostingClassifier, RandomForestClassifier
from sklearn.decomposition import TruncatedSVD
from sklearn import datasets
from sklearn.cross_validation import cross_val_score


# 学習データを用意する
iris     = datasets.load_iris() #ライブラリ付属のサンプルデータ
features = iris.data            #特徴量のデータ 
                                #上記の分類の例でいうと、天気、場所、月日や各マンガを読んだかどうかに相当します
labels   = iris.target          #特徴量に対する正解データ
                                #上記の分類の例でいうと、気温や性別に相当します

#特徴量の次元を圧縮
#似たような性質の特徴を同じものとして扱います
lsa = TruncatedSVD(2)
reduced_features = lsa.fit_transform(features)

#どのモデルがいいのかよくわからないから目があったやつとりあえずデフォルト設定で全員皆殺し 
clf_names = ["LinearSVC","AdaBoostClassifier","ExtraTreesClassifier" ,"GradientBoostingClassifier","RandomForestClassifier"]
for clf_name in clf_names:
  clf    = eval("%s()" % clf_name) 
  scores = cross_val_score(clf,reduced_features, labels,cv=5)
  score  = sum(scores) / len(scores)  #モデルの正解率を計測
  print "%sのスコア:%s" % (clf_name,score)

#LinearSVCのスコア:0.973333333333
#AdaBoostClassifierのスコア:0.973333333333
#ExtraTreesClassifierのスコア:0.973333333333
#GradientBoostingClassifierのスコア:0.966666666667
#RandomForestClassifierのスコア:0.933333333333

```



##Google Prediction API,Mahout,Spark,Cythonについてそれぞれ一言所感

###Google Prediction API
導入はsk-learn以下の学習コストだが、捌けるデータ量少ないところが難点です。

###Mahout
Hadoopを利用した分散型の機械学習ができるツールっぽいが、日本語でMahoutの連載を書いていた人にMahoutよりもSparkを薦められました。Apacheのプロジェクトです。

###Spark
Mahoutとの違いをあまりわかっていませんが、偉い人にこっちを薦められました。scikit-learnで概ねうまくいったので、ちょっとさわってすぐにやめました。同じくApacheのプロジェクトです。

###Cython
爆速ですが、Pythonで動いたコードがCythonで動かないとか並列処理ししたプロセスが生き続けてるとかたまにあります。ローレベルっぽいところで問題がおきたら、まずは普通にPythonで実行してみるとよいかもしれません。



##まとめ

詳しい友人がいるならその人に聞ききましょう。友達がいないなら私に聞いてください。[技術交換しましょう](http://qiita.com/puriketu99/items/7370901978887fe59a49)。
とりあえずscikit-learnをインストールして、上記のサンプルコードを貼りつけて実行してみてほしいです。


\#今回自分がつくったプロダクトは受託なのでオープンにはしていません。悪しからず。
\#[こんな感じの課題](http://qiita.com/puriketu99/items/3c6325673f876bb49370)を解決するWebアプリでした。