kakakakakku blog

Weekly Tech Blog : Keep on Learning 👍

現場の視点で機械学習に必要な知識を学べる「仕事ではじめる機械学習 第2版」を読んだ

「仕事ではじめる機械学習 第2版」を読んだ.実は「第1版」を買ってずっと積読をしていたところに「第2版」が出たので書い直した📖書名に「仕事ではじめる」と書いてある通り,現場の視点で理解しておくべき「機械学習」の知識がまとまっていて良かった.そして,本当に読みやすく挫折させないように工夫して書かれているのも素晴らしかった!読書メモを見返しながら書評記事をまとめる.

目次

「第I部」では幅広く知識を学び「第II部」ではケーススタディから学ぶ.流れるように最後まで読み進めることができる.「第1版」と比較すると「MLOps」や「解釈性」など,重要なトピックが追加されているため,間違いなく「第2版」を読むべきだと思う.

また本書を読んでいて個人的に感じたのは「関連するけど詳しくは扱わないトピック」に関しては注釈などを使って関連情報(ドキュメントやブログなど)にうまく誘導していた.よって,興味があったら追加で調べることにより,本書を超えて知識を獲得できる仕組みになっている点も良かった.

  • 第I部
    • 1ç«  : 機械学習プロジェクトのはじめ方
    • 2ç«  : 機械学習で何ができる?
    • 3ç«  : 学習結果を評価するには
    • 4ç«  : システムに機械学習を組み込む
    • 5ç«  : 学習のためのリソースを収集する
    • 6ç«  : 継続的トレーニングをするための機械学習基盤
    • 7ç«  : 効果検証:機械学習にもとづいた施策の成果を判断する
    • 8ç«  : 機械学習のモデルを解釈する
  • 第II部
    • 9ç«  : Kickstarter の分析、機械学習を使わないという選択肢
    • 10ç«  : Uplift Modeling によるマーケティング資源の効率化
    • 11ç«  : バンディットアルゴリズムによる強化学習入門
    • 12ç«  : オンライン広告における機械学習

なお「第2版」の誤植は以下にまとまっている.載っていないものだと以下を発見した.

  • P.81
    • 真陽性率と縦軸、偽陽性率を横軸にプロット → 真陽性率を縦軸、偽陽性率を横軸にプロット

github.com

前提

本書の冒頭に「二冊目として活用する」と読者層が紹介されている.具体的には「Coursera : Machine Learning」を受講したり「ゼロから作る Deep Learning」を読んだ次に読むべしと書いてある.僕自身は「機械学習図鑑」や「Pandas ライブラリ活用入門」を読んだり,Kaggle Courses を試したりしているため,ピッタリ読者層だった.実際に「第1版」を買って積読をしてしまった理由は「前提知識が足りなくて理解しにくかった」となるため,今はより自信を持って読めるようになったと感じる.

機械学習プロジェクト

1章「機械学習プロジェクトのはじめ方」は,技術職に限らず「機械学習に興味のある人なら」誰もが読むべき内容になっていた.機械学習を導入することを「目的」にせず,あくまで「手段」としてビジネスに活用するべきという視点が重要で「機械学習をしなくて良い方法を考える」というのはまさに!という感じだった.例えば,9章「Kickstarterの分析、機械学習を使わないという選択肢」も Excel でここまで深く分析できる!ということに気付かされる内容になっている.そして「システム設計を考える」では「具体的な目標性能と撤退ラインを決めておく」とも書いてある.サンクコストを考慮しつつ「撤退する判断」も現場では重要になりそうだと感じた.

  • ビジネス課題を機械学習の課題に定式化する
  • 類似の課題を、論文を中心にサーベイする
  • 機械学習をしなくて良い方法を考える
  • システム設計を考える
  • 特徴量、教師データとログの設計をする
  • 実データの収集と前処理をする
  • 探索的データ分析とアルゴリズムを選定する
  • 学習、パラメータチューニング
  • システムに組み込む

試して学べるサンプルコード

本書は読者を挫折させないように工夫して文章が書かれているだけではなく,図解や簡単なサンプルコードを使った解説も充実している.サンプルコードは GitHub に Jupyter Notebook として公開されているため,「1周目」は本書をザッと読んで「2周目」は気になったところを試しながら学ぶこともできる.

github.com

例えば,3章「学習結果を評価するには」では,分類と回帰それぞれの評価指標が解説されている.分類の評価指標として「F 値」以外に使うことができる「ROC 曲線と AUC」もあり,scikit-learn のサンプルコードを書き換えながら試行錯誤ができる.

import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve

#
# AUC = 0.8333333333333333
#

y_pass = [0, 0, 0, 1, 0, 0, 1, 0, 1, 1]
y_score = [0.1, 0.2, 0.4, 0.45, 0.5, 0.65, 0.7, 0.8, 0.85, 0.95]

fpr, tpr, thresholds = roc_curve(y_pass, y_score)

plt.plot(fpr, tpr, marker='o')
plt.xlabel('FPR: False Positive Rate')
plt.ylabel('TPR: True Positive Rate')
plt.grid()

#
# AUC = 1.0
#

y_perfect = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
y_score_perfect = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

fpr, tpr, _ = roc_curve(y_perfect, y_score)

plt.plot(fpr, tpr, marker='o')
plt.xlabel('FPR: False Positive Rate')
plt.ylabel('TPR: True Positive Rate')
plt.grid()

f:id:kakku22:20211128192027p:plain f:id:kakku22:20211128192036p:plain

MLOps

「第2版」で追加された6章「継続的トレーニングをするための機械学習基盤」では,最近特によく聞くようになった MLOps という概念を学べる.DevOps などの文脈で出てくる CI (Continuous Integration) / CD (Continuous Delivery or Continuous Deployment) に CT (Continuous Training) を追加することで,機械学習プロジェクトを継続的に進めるための心得を学べる.また本書では,以下のドキュメントで紹介されている MLOps のレベルをよりわかりやすく整理されている.

  • 共通の実験環境
  • 予測結果のサービング
  • 学習,予測共通の処理のパイプライン化
  • モデルの継続的トレーニング・デプロイ

cloud.google.com

そして,MLOps を実現するために使えるツールの選択肢は多岐にわたるため,本書では概要レベルでたくさん紹介されていた.一部を抜粋すると,Amazon SageMaker / MLflow / Hydra / Apache Airflow / Kubeflow など(正確には並列に列挙するのは正しくないけど).このあたりは興味のあるところから入門したいと思う.ツールの選択肢をポインタとして知ることができただけでも価値があった.

解釈性

同じく「第2版」で追加された8章「機械学習のモデルを解釈する」では,「Explainable AI(説明可能な AI)」とも言われるトピックで「解釈性(どの特徴量が寄与していたのか?など)」をサンプルコードを使って体験できる.今回は Kaggle に公開されている「退職予測データセット」を使って「線形回帰(回帰係数と切片)」と「決定木」と「ランダムフォレスト」それぞれで解釈性を可視化する方法を学べる.

IBM HR Analytics Employee Attrition & Performancewww.kaggle.com

例えば「ランダムフォレスト」では SHAP を使って(解釈可視化ツール)を使って,「解釈性」を可視化する.

github.com

以下を見ると,例えば「OverTime_Yes(残業の有無)」や「MonthlyIncome(月収の低さ)」が影響していることを確認できたりする.

f:id:kakku22:20211128192016p:plain

まとめ

「仕事ではじめる機械学習 第2版」を読んだ.ザッと「1周目」を読んでから「2周目」ではサンプルコードを試したりしていた.並行して Kaggle Courses なども活用しつつ,理解度が上がってきたため,読書メモを見返しながら書評記事にまとめた.この記事では紹介しきれないほどに素晴らしい一冊なので是非読んでみると良いのではないでしょうか!

train_test_split() の stratify パラメータを使って層化サンプリングをする

データセットを分割するときに scikit-learn の train_test_split() をよく使う.今回は train_test_split() に設定できる stratify パラメータを試す.stratify は「層化」という意味で「データセットの特性を考慮した分割」とも言える.特に「不均衡データセット」を使うときに重要になる.

scikit-learn.org

train_test_split() をデフォルト設定で使う

train_test_split() のデフォルト設定を抜粋すると以下のようになる.stratify はデフォルトで None になる.

  • train_size = 0.75(トレーニングデータ 75 %)
  • test_size = 0.25(テストデータ 25 %)
  • shuffle = True(ランダムに分割する)
  • stratify = None(層化なし)

例として,scikit-learn に組み込まれた「ワインデータセット🍷」を使う.正解ラベルは 0 と 1 と 2 の「計3種類」あり,それぞれの分布は以下のようになっている.ワインデータセットは不均衡ではないけど,検証には使える.

  • 178 件
    • 正解ラベル 0 : 59 件(33.1 %)
    • 正解ラベル 1 : 71 件(39.8 %)
    • 正解ラベル 2 : 48 件(26.9 %)

scikit-learn.org

train_test_split(X, y) のように「デフォルト設定のまま」実行するように以下のコードを書いた.3回実行したところ「正解ラベル 0」だと 0.34 % → 0.32 % → 0.36 % と推移した.もし不均衡データセットを使うと,より顕著に差が出る可能性がある.

import numpy as np
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

wine = load_wine()
X = wine.data
y = wine.target

def calc(i, y):
        print(str(i+1) + '回目 (' + str(len(y_train)) + '件)')
        print('・Label 0 : ' + str(np.round((y == 0).sum()/len(y), 2)) + ' %')
        print('・Label 1 : ' + str(np.round((y == 1).sum()/len(y), 2)) + ' %')
        print('・Label 2 : ' + str(np.round((y == 2).sum()/len(y), 2)) + ' %')
        print('---')

for i in range(3):
    X_train, X_test, y_train, y_test = train_test_split(X, y)
    calc(i, y_train)

# 1回目 (133件)
# ・Label 0 : 0.34 %
# ・Label 1 : 0.38 %
# ・Label 2 : 0.28 %
# ---
# 2回目 (133件)
# ・Label 0 : 0.32 %
# ・Label 1 : 0.41 %
# ・Label 2 : 0.27 %
# ---
# 3回目 (133件)
# ・Label 0 : 0.36 %
# ・Label 1 : 0.36 %
# ・Label 2 : 0.28 %
# ---

train_test_split() で stratify パラメータを使う

次にtrain_test_split(X, y, stratify=y) のように stratify パラメータを使って実行する.正解ラベル y を前提に「層化」するため,分布を維持しながらデータセットを分割することができる.なるほど💡

for i in range(3):
    X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y)
    calc(i, y_train)

# 1回目 (133件)
# ・Label 0 : 0.33 %
# ・Label 1 : 0.4 %
# ・Label 2 : 0.27 %
# ---
# 2回目 (133件)
# ・Label 0 : 0.33 %
# ・Label 1 : 0.4 %
# ・Label 2 : 0.27 %
# ---
# 3回目 (133件)
# ・Label 0 : 0.33 %
# ・Label 1 : 0.4 %
# ・Label 2 : 0.27 %
# ---

まとめ

今回は scikit-learn の train_test_split() で「層化サンプリング」ができる stratify パラメータを試した.覚えておこう!

scikit-learn の Pipeline を使って前処理やアルゴリズムをまとめて宣言する

scikit-learn の Pipeline を使うと,データセットの前処理や機械学習アルゴリズムなどを「1つのオブジェクトに」まとめることができる.

scikit-learn.org

前回の記事で紹介した「Kaggle Courses」の「Intermediate Machine Learning」コースでも使われていたこともあり,もう少しドキュメントを読みながら試していく.

kakakakakku.hatenablog.com

Pipeline に入門する

「Kaggle Courses」のコースを参考にサンプルコードを書くと,以下のようになる(重要なコードのみを抜粋している).Pipeline を使わずにコードを書くと SimpleImputer や OneHotEncoder や RandomForestRegressor など,それぞれで fit() や fit_transform() を実行する必要があるため,コード量を減らしつつ,可読性が高く実装できる.イイネ👏

from sklearn.ensemble import RandomForestRegressor
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, test_size=0.2, random_state=0)

pipeline = Pipeline(
    steps=[
        ('imputer', SimpleImputer(strategy='most_frequent')),
        ('encoder', OneHotEncoder(handle_unknown='ignore')),
        ('model', RandomForestRegressor(n_estimators=50, random_state=0))
    ]
)

pipeline.fit(X_train, y_train)

pipeline.predict(X_test)

また Pipeline に verbose=True パラメータを追加すると fit() を実行しながら以下のように進捗を表示することもできる.

pipeline = Pipeline(
    steps=[
        ('imputer', SimpleImputer(strategy='most_frequent')),
        ('encoder', OneHotEncoder(handle_unknown='ignore')),
        ('model', RandomForestRegressor(n_estimators=50, random_state=0))
    ],
    verbose=True
)

# [Pipeline] ........... (step 1 of 3) Processing imputer, total=   0.1s
# [Pipeline] ........... (step 2 of 3) Processing encoder, total=   0.1s
# [Pipeline] ............. (step 3 of 3) Processing model, total=  10.1s

そして,以下のドキュメントを参考に set_config() を使って「ダイアグラム表示」を有効化すると,以下のように Pipeline 構成を図として表示できる.実際には枠をクリックすることができて,パラメータを表示したり,非表示にしたりできる.

scikit-learn.org

from sklearn import set_config
set_config(display='diagram')
pipeline

f:id:kakku22:20211123175045p:plain

Pipeline で前処理をカテゴライズする

さらに Pipeline の中で前処理をカテゴライズすることもできる.例えば,以下のように numeric_preprocessor(量的変数) と categorical_preprocessor(カテゴリ変数) としてまとめている(重要なコードのみを抜粋している).最終的には make_pipeline() を使って RandomForestRegressor とまとめている.今回のサンプルコード以上に前処理などが多いときに効果が出そう.

scikit-learn.org

from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestRegressor
from sklearn.impute import SimpleImputer
from sklearn.pipeline import make_pipeline
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

numeric_preprocessor = Pipeline(
    steps=[
        ('imputer', SimpleImputer(strategy='most_frequent')),
        ('scaler', StandardScaler()),
    ]
)

categorical_preprocessor = Pipeline(
    steps=[
        ('onehot', OneHotEncoder(handle_unknown='ignore')),
    ]
)

pipeline = make_pipeline(
    ColumnTransformer(
        [
            ('numerical', numeric_preprocessor, numerical_cols),
            ('categorical', categorical_preprocessor, categorical_cols)
        ]
    ),
    RandomForestRegressor(n_estimators=50, random_state=0)
)

同じく set_config() を使って「ダイアグラム表示」を有効化すると,より整理された Pipeline 構成を表示することができた.

from sklearn import set_config
set_config(display='diagram')
pipeline

f:id:kakku22:20211124095951p:plain

まとめ

scikit-learn の Pipeline を使うと,データセットの前処理や機械学習アルゴリズムなどを「1つのオブジェクトに」まとめることができる.今回はシンプルな Pipeline 構成とカテゴライズをした構成を紹介した.ドキュメントを読むと,他にも GridSearchCV と組み合わせてハイパーパラメータを探索することもできて,便利だった.

scikit-learn.org

Intermediate Machine Learning : Kaggle Courses で学びながら「住宅価格予測」コンペに参加する

Kaggle が公開している「Kaggle Courses」で「Intermediate Machine Learning」コースを受講した.Kaggle のコンペティション「Housing Prices Competition for Kaggle Learn Users(住宅価格予測)」をテーマに試行錯誤をして,実際にモデルを登録することもできる.アルゴリズムとしては「ランダムフォレスト」と「XGBoost」を使う.アジェンダを見るとわかる通り,データセットの前処理からモデルの構築評価まで幅広く体験できる.

www.kaggle.com

なお,前提コースである「Pandas」と「Intro to Machine Learning」は既に受講していて,以下にまとめてある.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

アジェンダ 🏠

「Intermediate Machine Learning」コースには「計7種類」のレッスン(ドキュメントと演習)がある.

  1. Introduction
  2. Missing Values
  3. Categorical Variables
  4. Pipelines
  5. Cross-Validation
  6. XGBoost
  7. Data Leakage

住宅価格予測 🏠

1460 件のデータセットに 80 個の特徴量を含んでいる.その中から今回は 7 個の特徴量を使う.このあたりは前提コース「Intro to Machine Learning」と同じ.そして,特徴量の中に予測する SalePrice(住宅価格) も含まれていることから「教師あり学習(回帰)」と言える.

X_full.shape
# (1460, 80)

X.shape
# (1460, 7)

X.columns
# Index(['LotArea', 'YearBuilt', '1stFlrSF', '2ndFlrSF', 'FullBath', 'BedroomAbvGr', 'TotRmsAbvGrd'], dtype='object')

まず 1. Introduction と 2. Missing Values と 3. Categorical Variables と 4. Pipelines では,scikit-learn の RandomForestRegressor を使って「ランダムフォレスト」でモデルを構築する.以下のように適当にパラメータを設定して比較したり(今回は model_3 の平均絶対誤差 MAE が1番低かった👌),欠損値を考慮したり,カテゴリ変数をエンコーディングしたり,一歩一歩モデル精度を向上させていく.また scikit-learn の Pipeline を使って,コード実装を改善する.

model_1 = RandomForestRegressor(n_estimators=50, random_state=0)
model_2 = RandomForestRegressor(n_estimators=100, random_state=0)
model_3 = RandomForestRegressor(n_estimators=100, criterion='mae', random_state=0)
model_4 = RandomForestRegressor(n_estimators=200, min_samples_split=20, random_state=0)
model_5 = RandomForestRegressor(n_estimators=100, max_depth=7, random_state=0)

実際に評価をしながら進めるため,今回は欠損値を平均値で埋めるよりも特徴量を削除した方がパフォーマンスが良いなど,予想とは違う気付きもあって良かった.

  • Missing Values(欠損値)
    • [1] A Simple Option: Drop Columns with Missing Values(単純に特徴量を削除する)
    • [2] A Better Option: Imputation(より良く平均値などで埋める)
    • [3] An Extension To Imputation(値を埋めつつ欠損値の有無を表現する新しい特徴量を追加する)
  • Categorical Variables(カテゴリ変数)
    • [1] Drop Categorical Variables(カテゴリ変数を削除する)
    • [2] Ordinal Encoding(順序エンコーディング)
    • [3] One-Hot Encoding(ワンホットエンコーディング)

実際に Kaggle コンペティションにモデルを登録して,Leaderboard で順位が上がっていくことも確認する🏆

f:id:kakku22:20211123120838p:plain

交差検証 🏠

5. Cross-Validation では,scikit-learn の cross_val_score() を使って「交差検証」を行う.分割数 cv を 3 や 5 に設定しながら最終的な平均値を確認する.

scikit-learn.org

そして「ランダムフォレスト」に設定するパラメータ n_estimators の最善値を探す.今回は n_estimators = 50, 100, 150, 200, 250, 300, 350, 400 で比較して,結果的として 200 のパフォーマンスが1番良かった.

f:id:kakku22:20211123122155p:plain

XGBoost 🏠

ここまでは「ランダムフォレスト(アンサンブル学習)」を使ってきたけど,次は「XGBoost(勾配ブースティング)」を適用する.以下のようにパラメータを変えて比較をするけど,重要なのはアルゴリズムを変えることも考えながらコンペティションに参加するという点になる.

my_model_1 = XGBRegressor(random_state=0)
# Mean Absolute Error: 17662.736729452055

my_model_2 = XGBRegressor(n_estimators=1000, learning_rate=0.05)
# Mean Absolute Error: 16688.691513270547

my_model_3 = XGBRegressor(n_estimators=1)
# Mean Absolute Error: 127895.0828807256

xgboost.readthedocs.io

Data Leakage 🏠

7. Data Leakage では,モデルに対する考察として「Data Leakage(データ漏洩)」を学ぶ.「Data Leakage」とは,トレーニングデータセットにターゲットに関する「含まれていはいけないデータが含まれていること」と言える.よって,モデルの検証時にはパフォーマンスが高くなり,本番環境にデプロイするとパフォーマンスが低くなってしまう.「Data Leakage」として,具体的には以下の2種類が載っていた.

  • Target leakage(ターゲット漏洩)
    • 例 : 肺炎予測をするときに「抗生物質を服用しているか」という特徴量を使ってしまう
      • 本来は「肺炎である」と診断されてから処方されるため,将来の予測には使えない
  • Train-Test Contamination(トレインテスト汚染)
    • 例 : データセットを前処理する場合に欠損値を平均値などで埋める場合に検証データの精度が高くなってしまう
      • 検証データを除外して前処理をする
      • scikit-learn の train_test_split() から Train-Test という名前になっている

まとめ 🏠

「Kaggle Courses」で「Intermediate Machine Learning」コースを受講した.Kaggle のコンペティション「Housing Prices Competition for Kaggle Learn Users(住宅価格予測)」に参加することもできて,一般的な機械学習ワークフローを体験することができた.とても良かった👏

次は「Feature Engineering」コースと「Machine Learning Explainability」コースに進もうと思う.

f:id:kakku22:20211123123758p:plain

入門者でも挫折せずに読める!「機械学習図鑑」で "17種類" のアルゴリズムを学ぶ

「機械学習図鑑」を読んだので簡単にまとめる.正確には今年5月頃に読んでいたけど,まだ書評記事を書いてなかった📕

まず前提として,本書を読んだときには僕は機械学習に詳しくなく入門者だった.機械学習に関連する書籍を何冊か買ってみたけど,そのときの知識では理解できないことも多く,最後まで読めずに挫折することが多かった.そこで本当に入門者でも読めそうな本を探していたところ「見て試してわかる機械学習アルゴリズムの仕組み 機械学習図鑑」の評判が良さそうで読むことにした.素晴らしかった👏

対象読者

本書の冒頭に「対象読者」が載っている.以下は一部を抜粋しているけど,まさに僕だった.本書を読んだことにより,今までうまく理解できなかった書籍やウェブサイトを読めるようになり,本書を読んだ効果を感じることができた.

  • 機械学習に興味があり、勉強し始めている。
  • 数式があまり得意ではなく、機械学習の専門書を読むのに苦労している。
  • ある程度プログラミングの経験があり、サンプルコードを実行することができる。

本書の良いところは多くある.オールカラーだし,図表が多く載っているし,scikit-learn のサンプルコードも解説されている.そして「17種類」ものアルゴリズムが紹介されているのも良かった.

目次

  • 第1章「機械学習の基礎」
    • 1.1 : 機械学習の概要
    • 1.2 : 機械学習に必要なステップ
  • 第2章「教師あり学習」
    • 01 : 線形回帰
    • 02 : 正則化
    • 03 : ロジスティック回帰
    • 04 : サポートベクトルマシン
    • 05 : サポートベクトルマシン(カーネル法)
    • 06 : ナイーブベイズ
    • 07 : ランダムフォレスト
    • 08 : ニューラルネットワーク
    • 09 : kNN
  • 第3章「教師なし学習」
    • 10 : PCA
    • 11 : LSA
    • 12 : NMF
    • 13 : LDA
    • 14 : k-means 法
    • 15 : 混合ガウス分布
    • 16 : LLE
    • 17 : t-SNE
  • 第4章「評価方法および各種データの扱い」
    • 4.1 : 評価方法
    • 4.2 : 文書データの変換処理
    • 4.3 : 画像データの変換処理
  • 第5章「環境構築」
    • 5.1 : Python3 のインストール
    • 5.2 : 仮想環境
    • 5.3 : パッケージインストール

本書は今年5月に合格した「Python 3 エンジニア認定データ分析試験」の準備をするのにも非常に役立った.

kakakakakku.hatenablog.com

第1章「機械学習の基礎」

第1章では「機械学習とは?」という内容から「教師あり学習」や「教師なし学習」や「強化学習」の具体例までわかりやすく紹介されている.特に書籍名に「図鑑」と書いてある通り,図表が多く載っている点が素晴らしく,入門者だと単純なことでも最初はうまく理解できず悩むため,本書は本当に読みやすく書かれていると思う.

第2章「教師あり学習」

第2章では「教師あり学習」として「9種類」のアルゴリズムが紹介されている.どのアルゴリズムも基本的な考え方が図表で解説されていて,実装例は scikit-learn のサンプルコードで解説されているため,挫折することなく読み進めることができた.またサンプルコードは Jupyter Notebook 形式でダウンロードできるので,気になるところは積極的に試すようにした.

www.shoeisha.co.jp

例えば,以下は「線形回帰」を scikit-learn の LinearRegression で実装するサンプルコードを参考に Matplotlib を使って可視化まで試してみた.サンプルコードを動かすことに加えて自分で試行錯誤をしてみるとより理解が深まると思う.

from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt


X = [[10.0], [8.0], [13.0], [9.0], [11.0], [14.0], [6.0], [4.0], [12.0], [7.0], [5.0]]
y = [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68]

model = LinearRegression()
model.fit(X, y) 

print(model.intercept_)
# 切片 : 3.0000909090909094

print(model.coef_)
# 傾き : 0.50009091

y_pred = model.predict([[0], [1]]) 
print(y_pred)
# x=0, x=1 に対する予測結果

y_pred_all = model.predict(X)
# X 全体に対する予測結果

plt.scatter(X, y)
plt.plot(X, y_pred_all, linewidth=0.5)
# グラフにプロット

f:id:kakku22:20211119100437p:plain

また線形回帰の解釈の難しさとして「アンスコムの例」の紹介もあったりして,関連トピックが載っている点も視野を広げる意味で良かった.

ja.wikipedia.org

第3章「教師なし学習」

第3章では「教師なし学習」として「8種類」のアルゴリズムが紹介されている.特に入門者として最初は「教師なし学習」の理解がしにくく感じたけど,実際に PCA や t-SNE や k-means などのサンプルコードを実際に試したりもして,基本的な考え方と scikit-learn での実装を理解できるようになった.

例えば,以下は「PCA」を scikit-learn で実装するサンプルコードを参考に Matplotlib を使って「累積寄与度」の可視化まで試してみた.iris データセット(アヤメ)の特徴量4個を2個まで次元削減をした効果を確認できるようになった.

from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
import matplotlib.ticker as ticker
import numpy as np


data = load_iris()

model = PCA(n_components=2)
model = model.fit(data.data)
# 次元を 4 → 2 に削減

print(model.transform(data.data)[0:5])
# 次元削減後のデータセットの先頭を表示
# [[-2.68412563  0.31939725]
#  [-2.71414169 -0.17700123]
#  [-2.88899057 -0.14494943]
#  [-2.74534286 -0.31829898]
#  [-2.72871654  0.32675451]]

fig, ax = plt.subplots()
ax.plot(np.cumsum(np.append(0, model.explained_variance_ratio_)))
ax.grid()
# 累積寄与率をグラフにプロット

f:id:kakku22:20211119101219p:plain

第4章「評価方法および各種データの扱い」

第4章では「評価」という重要なトピックで「評価手法」や「ハイパーパラメーター」や「過学習」など,知っておくべき内容がわかりやすくまとまっている.特に「教師あり学習」で「分類」と「回帰」で使う指標は以下のように整理されていてイメージしやすく,またそれぞれの指標の使い分けなども載っていた.

  • 分類問題
    • 混合行列
    • 正解率
    • 適合率
    • 再現率
    • F 値
    • AUC (Area Under the Curve)
  • 回帰問題
    • 平均二乗誤差
    • 決定係数

そして並行して読んでいる「仕事ではじめる機械学習 第2版」の「3章 : 学習結果を評価するには」を読む前提としても役立った.

まとめ

「機械学習図鑑」を読んだ.入門者として機械学習を勉強するときには欠かせない一冊なのではないかと思う.当然ながら本書を読むだけで全てに精通できるわけではないけど,今までうまく理解できなかった書籍やウェブサイトを読めるようになったことは非常に大きな効果だったし,気付きもたくさんあった.そして,著者目線だと「本当に入門者でも挫折しないで読める書籍を書く技術」に驚いた.スゴイ!今後も何度も読み直すとは思うけど,素晴らしい一冊だった👏