湯豆腐

個人用の落書きです

scikit-learnの使い方 [ML:1日目]

チュートリアルでおなじみのirisを使ってscikit-learnの基本的な使い方を学びます。

データの確認

まずはseabornを使ってデータの内容を確認してみましょう。

import seaborn as sb
%matplotlib inline

# データフレームの読み込み
iris = sb.load_dataset('iris')

# 先頭のデータを表示
iris.head()

irisはアヤメの3種類の品種について計測したデータです。

  • sepal-length: がく片の長さ
  • sepal-width: がく片の幅
  • petal-length: 花びらの長さ
  • petal-width: 花びらの幅
  • species: アヤメの種類

となっていて、speciesが予測する目的変数です。

次に可視化して傾向を見てみます。

sb.pairplot(iris, hue='species', markers=["o", "s", "+"])

f:id:zoo_200:20180322151054p:plain

versicolorとvirginicaが似ているようですね。

分類してみる

よく使われる以下のアルゴリズムをそれぞれ試してみます

  • ロジスティック回帰
  • SVM
  • ランダムフォレスト

前準備として説明変数、目的変数をそれぞれ訓練用データとテストデータに分割します

from sklearn.cross_validation import train_test_split
import seaborn as sb

iris = sb.load_dataset('iris')

x_train, x_test, y_train, y_test = train_test_split(
    iris.drop('species', axis=1),
    iris.species,
    test_size=0.2
)

基本的な使い方は下記です。

  1. 分類器のインスタンスを作成
  2. fitで訓練データを当てはめ
  3. predictでテストデータの予測
  4. scoreで精度の表示

ロジスティック回帰

from sklearn.linear_model import LogisticRegression

clf_lr = LogisticRegression()
clf_lr.fit(x_train, y_train)

accuracy = clf_lr.score(x_test, y_test)
print(accuracy)

SVM

from sklearn import svm

clf_svm = svm.SVC()
clf_svm.fit(x_train, y_train)

accuracy = clf_svm.score(x_test, y_test)
print(accuracy)

ランダムフォレスト

from sklearn.ensemble import RandomForestClassifier

clf_rf = RandomForestClassifier()
clf_rf.fit(x_train, y_train)

accuracy = clf_rf.score(x_test, y_test)
print(accuracy)

結果

分類器 スコア
ロジスティック回帰 93.33%
SVM 96.66%
ランダムフォレスト 93.33%

何もチューニングしていない状態だと SVM > ロジスティック回帰 = ランダムフォレスト となりました。

ロジスティック回帰は線形分類器なのに対し、SVM・ランダムフォレストは非線形データも分類できるので、
ロジスティック回帰とランダムフォレストが同じ結果になったのが意外でした。

とはいえ十分な精度は出ているので、データ量が増えると変わるのか、それともチューニングで変わるのか・・・
経験則がないのでこのあたりの判断ができませんね。
次回はチューニングについてもう少し調べてみたいと思います。

機械学習の学習 [ML:0日目]

転職が決まり、有給消化期間になったので、 今まで勉強する暇が無かった機械学習などの勉強を始めたいと思います。

現状の知識レベル的には下記のような感じ

  • 文系出身・・・数学とかは大学でほとんど使ってない
  • 基本的な用語に関しては知っている(≠理解している)・・・標準偏差正規分布過学習、各アルゴリズムの名前、etc
  • マーケター→エンジニアへ転向して半年くらい。独学でPython、仕事ではRubyをやっていた

自分用のアウトプット先として記事を投稿していくつもりですが、 同じぐらいのレベル感の人にも参考になればと思います。

方向性

  • scikit-learn
  • chainer

の理解を深めながら、機械学習自体の理解を深めていきます。

正攻法的には基礎数学からやった方が捗ると思いますが、 あくまで"ライブラリを使えるようになること"に焦点をあてて勉強していきます。

理由としては、例えば標準偏差は数式で書くとこうなりますが

  {\sqrt{
    {\frac{1}{n}}} {\sum_{n=i}^{n} (x_i - {\bar{x}})}
  }

数学に馴染みのないエンジニアとしては下記の方が圧倒的にわかりやすいですね

import math

def sd(array):
    mean = sum(array) / len(array)
    tmp = sum([(i - mean)**2 for i in array])
    var = tmp / len(array)
    sd = math.sqrt(var)
    return sd

最初にプログラミングを勉強し始めるときも、理論からガチガチにやっていくより
まずはコピペで動くものから、少しずつ理解を広めて行く方が多くの人にとって理解しやすいのではないかと思ってます。

ゴール

まだ深く考えていないので、今のところ決まったゴールはなし・・・
やりながら考えていこうと思いますが、今のところは

  • Chainerかscikit-learnで独自課題に挑戦
  • Kaggleでコンペに挑戦する

みたいな感じになるのかな。
とりあえずがんばろう