機械学習概論:考え方と枠組み†
1. 機械学習の考え方†
機械学習とは†
学習 (learning)†
大辞林より
- まなびおさめること.勉強すること.「新しい教科を―する」
- 〔生〕 生後の反復した経験によって,個々の個体の行動に環境に対して適応した変化が現れる過程.ヒトでは社会的生活に関与するほとんどすべての行動がこれによって習得される.
- 〔心〕 過去の経験によって行動の仕方がある程度永続的に変容すること.新しい習慣が形成されること.
- 〔教〕 新しい知識の獲得,感情の深化,よき習慣の形成などの目標に向かって努力を伴って展開される意識的行動.
図1: ヒトの学習
機械学習 (machine learning)†
- 統計的手法を使用して,明示的にプログラムされずにコンピューターが学習して意思決定できるようにする人工知能のアプリケーションの1つ 【Great Learning】
- コンピューターが新しいデータから学習してタスクの実行方法を変容していくプロセス; この時,人間がプログラムの形で明示的な指示を与えることがない 【Camridge Dictionary】
- データを分析する方法の1つで,データから,「機械」(コンピューター)が自動で「学習」し,データの背景にあるルールやパターンを発見する方法.近年では、学習した成果に基づいて「予測・判断」することが重視されるようになった.【野村総研】
- 機械学習とは,AIが人間のような高度な判断を実行するに必要な「法則」を、コンピュータに探させる方法(アルゴリズム)の総称 【スッキリわかる機械学習】
- 観測センサーやその他の手段で収集されたデータの中から一貫性のある規則を見つけだそうとする研究です.数学の統計の分野と強い関連があります.また,機械学習はAIの他のほとんどの分野で利用されています.【人工知能学会】
プログラミングと機械学習†
従来,機械(コンピュータ)に仕事をさせるには,人間が情報処理の手順や法則をプログラムとして記述し,機械に与えて実行していた
- プログラムは人間の英知によって書かれるもの
- 【メリット】100%指示した通りに動作する.テスト可能である
- 【デメリット】人間の経験と勘の域を出ない.仕事が変わればプログラムを書き直さなければならない
図2: プログラミングによる情報処理
一方,機械学習による情報処理では,機械(コンピュータ)がデータから法則を自動的・統計的に学習する
- 学習によって得られた法則に基づいて,機械は新しいデータに対する予測・推論ができる
- もちろん,データの前処理や学習の手順は人間がプログラミングする必要がある
- 【メリット】人間には見つけられない法則・パターンを見つけてくれる.
- 【デメリット】100%の正しさを保証できない.データの品質が悪いと使い物にならない
図3: 機械学習による情報処理
機械学習の種類†
教師あり学習 (supervised learning)†
データにおける入力X(特徴量)と出力y(正解データ)の関係f (y = f(X))を学習する.
機械学習の最も代表的なアプローチ.回帰と分類の2タイプに大別される.
- 回帰 (regression)
- yを数値(連続値)として,Xから予測するモデルを構築する
- 応用例:売上予測,需要予測,リードタイム予測,収穫量予測
- モデル:線形回帰,リッジ回帰,ラッソ回帰,回帰木
- 分類 (classification)
- yをカテゴリ(離散値)として,予測する問題
- 応用例:故障予測,文字認識,感情認識,スパム判定
- モデル:決定木,ロジスティック回帰,k近傍法,サポートベクタマシン(SVM)
教師なし学習 (unsupervised learning)†
正解データを指定せず,データそのものがどのような性質を持っているかを学習する.
代表的な方法に次元削減,クラスタリングがある.
- 次元削減 (dimensionality reduction)
- 変数(列)同士の関係に着目して,情報をなるべく失わないように変数の数を削減する
- 応用例:可視化,データの圧縮,特徴量の抽出
- モデル:主成分分析(PCA)
- クラスタリング(clustering)
- サンプル(行)同士の関係に着目して,似た性質を持つデータをグループに分ける
- 応用例:顧客のセグメンテーション(類型化),ブランド・商品イメージのカテゴリー分析,画像・音声分類
- モデル:k-means,階層的クラスタリング
その他†
- 強化学習 (reinforcement learning)
- ある環境の下で,行動の結果が最も良くなるように,適切な行動を学習する
- 応用例:ゲーム,ロボット制御
- 深層学習 (deep learning)
- 学習モデルに多層ニューラルネットワークを使用
- 重要な特徴量を機械が自動的に学習し,データから結果までを一気通貫で行う(end-to-end)
- 応用例:画像認識,音声認識,自然言語処理,異常検知
機械学習を使うべきか使わざるべきか?†
- 機械学習はあくまで目的を実現する手段に過ぎない.使うことを目的としてはいけない
- 機械学習はコストの高い手法.解決したい課題に対して本当に使うべきかどうかを吟味する必要がある
- ちょっとしたデータ分析で済む問題に対して,無理やり使おうとしていないか?
- プログラム(ルール)が書ける問題に対して,データで説明しようとしていないか?
目的・問いを明確化する†
- まず初めに,やりたいこと,目的,問い(Research Question)を明確化する
- なるべく具体的(Sharp)な質問を考える
- ×売り上げがどうなるか?
- △明日の売上個数はどうなるか?
- ○商品Aの翌日の売上個数が何個になるか予測できるか?
- よく似た文章でも,RQとして考えると全く別物になる
- 商品Aの翌日の売上個数は何個か?
- 商品Aのこの先1週間の売上金額はいくらになるか?
- 商品Aの売上個数の傾向に似た別の商品をどれか?
- 商品Aに対する広告の効果があったか・なかったか?
- 商品Aが既存の商品Bに比べてどれだけ売れているか?
- 商品Aはこれまで何曜日に一番多く売れたか?
- 商品Aに適用する消費税率はいくらか?
機械学習向いている問題†
- 目的に関連する質の良いデータが豊富にある
- 自明・既知のルールがない,あるいは,ルール化できない問題
- 既存のアルゴリズムでは性能に限界がある問題
機械学習とPython†
- scikit-learn (サイキット・ラーン)
- 機械学習のための強力なライブラリ
- 基本的な教師あり学習と教師なし学習に対応
- 強化学習,深層学習,シーケンス予測には対応しない
- データ操作・可視化のためのライブラリ
- Pandas
- Numpy
- Matplotlib
- Seaborn: Matplotlibより高級な描画ライブラリ
- 他のライブラリ
- Tensorflow: Googleが開発した深層学習のフレームワーク
- Keras: ニューラルネットワーク向けのライブラリ.Tensorflowと組み合わせて動作する
- 画像認識,音声認識,文章の生成,botシステムの作成などの応用
- PyTorch: Facebookが開発した深層学習のフレームワーク
2. 機械学習の体験(教師あり学習・分類)†
アヤメ(Iris)の分類問題†
- 教育目的によく用いられる古典的な分類問題.アヤメ(花)の「花びら」と「がく」の長さ・幅から3種類の品種を見分ける
- RQ:アヤメ(花)の観測データから,その品種を見分けることができるか?
- 特徴: がくの長さ(cm),がくの幅(cm),花びらの長さ(cm),花びらの幅(cm)
- 品種:以下の3種類
- データ
図3:分類するアヤメの品種
Google Colabでやってみよう†
Google Colabの起動†
データのロード†
データを眺める†
- データをよく眺めてみよう
- 「表のマーク」アイコンを押すと,表データを見やすく操作できる
- 表のサイズ
iris_data.shape
- 各列の統計量
iris_data.describe()
- それぞれの品種のサンプル数
iris_data["品種"].value_counts()
- 散布図行列 (詳細は第4回で)
#Seabornのペアプロットを使う
sns.pairplot(data=iris_data, hue="品種")
#Pandasにも機能がある.ただし,色分けするのに手間なので,Seabornを使おう
pd.plotting.scatter_matrix(iris_data)
アヤメ問題の定式化†
- がくの長さ,がくの幅,花びらの長さ,花びらの幅から 品種を当てる問題
- 【入力 X】: 4つの数値 ex: 4.8, 3.3, 1.4, 0.2
- Xは特徴量(feature),説明変数などと呼ばれる.予測のための手がかり
- 【出力 y】: Iris-setosa, Iris-versicolor, Iris-virginicaのいずれかの品種
- yは正解データ,ラベル,目的変数 (target)などと呼ばれる.予測の答え
- この問題において,機械学習で行うこと: y=f(X)のfを見つけること
- データを読み込んで,入力Xと出力yの関係を学習し,法則 fを発見する
- fはモデル(model)と呼ばれる
- モデルfには,最初は値が決まっていない変数(パラメータ (parameters))が1つ以上入っている
- 学習とは,大量のデータを読み込んで,Xとyの対応関係にもっとも当てはまる( フィット(fit) する)ようなパラメータの値を自動的に探すこと
- パラメータの探し方には,様々な 手法(アルゴリズム) が存在する
- アルゴリズムを動かす際に,人間が設定するパラメータを ハイパーパラメータ (hyper parameters)と呼ぶ
- 決定木の深さの上限:max_depth,葉ノードの数の上限:max_leaf_nodes

図4: アヤメ問題への機械学習の適用
機械学習を実行し,モデルを構築する†
#特徴に使う列名リスト
features = ["がくの長さ", "がくの幅", "花びらの長さ", "花びらの幅"]
#正解データに使う列名
target = ["品種"]
X = iris_data[features]
y = iris_data[target]
from sklearn import tree
#決定木による分類モデルの構築.木の深さの上限を3とする(ハイパーパラメータ)
model = tree.DecisionTreeClassifier(random_state=0, max_depth=3)
model.fit(X,y)
未知のデータで予測してみる†
- 元のデータを参考に,それぞれの品種に似たデータを3つ用意する
#未知のデータで予測してみる
new_data = pd.DataFrame([[4.8, 3.3, 1.4, 0.2],[7.3, 3.2, 4.4, 1.3],[5.5, 2.6, 5.5, 2.7] ], columns=features)
new_data
#予測してみる
model.predict(new_data)
アプリに組み込んでみる†
#ユーザから入力を受け付けて,答えを出すプログラム
print("■アヤメの品種予測アプリ")
while True:
input_str = input("がくの長さ・幅,花びらの長さ・幅を入力(0で終了):")
if (input_str == "0"):
break
vals = np.array(input_str.split()).astype(float)
if (len(vals) != 4):
print(" ×エラー:4つの数値が必要です.やり直し")
continue
df_params = pd.DataFrame([vals], columns=features)
print(f" ○AI:品種は{model.predict(df_params)[0]}と思われます")
print("終了します")
何が起きたのか?†
- 機械学習アルゴリズムの1つである決定木によって,X(アヤメの特徴量)からy(品種)を予測するモデルが構築された
- 条件分岐によって分類モデルを構築する機械学習アルゴリズム
モデルを確認する†
図5: 決定木によるアヤメの分類モデル
決定木アルゴリズムの直感的な解説†
- はじめは全体グループを表す根ノードから始める
- 特徴量に関する条件を探し,それを満たすデータと満たさないデータに分割して,2つの子ノードを作る
- この時,子ノードの不純度 (gini)がなるべく低くなるような条件を探索する
- 決定木ではこの分割条件(変数名 <= 閾値)がパラメータとなる
- 不純度が0になる,あるいは,指定された深さ(この場合3)まで到達すれば終了.そうでなければ,2.に戻る
図6: 決定木によって分割されたデータ
※アルゴリズム詳細
- このモデルってどこまで信頼していいの?
- 未知のデータに対して,アプリの出力は完ぺきなの?何パーセント当たるの?
→ モデルの評価 が必要
モデルを評価する†
- すべてのデータで学習するのではなく,学習用のデータ(訓練データ)と評価用のデータ(テストデータ)に分ける
- 訓練データで作成したモデルを,テストデータを未知のデータとして評価する
- モデルの予測とテストデータの正解がどれだけ合致するかを評価する
データを分割する:ホールドアウト法†
- 与えられたデータを2つに分割する (本当は3つに分けるのが望ましいが次回以降で)
- 訓練データ: モデルの学習に使うデータ
- テストデータ: モデルの性能評価に使うデータ
- 特徴量X, 正解データyをそれぞれ同じところで分割する
図7: 訓練データとテストデータの分割
- Pythonのコードでは,scikit-learnが提供する関数 train_test_split()を使うと便利
- パラメータ:
- X: 特徴量
- y: 正解データ
- train_size: 訓練データの割合 (デフォルト0.75)
- test_size: テストデータの割合(デフォルト0.25)
- shuffle: ランダムに分割(デフォルトTrue)
- random_state: 乱数シード
- stratify: 指定したデータの分布が均一になるよう分割 (デフォルトNone)
#X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=2:1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
#それぞれ確認してみる
print(X_train, X_test, y_train, y_test)
モデルの学習†
モデルの評価†
- 分類問題の場合,混同行列(confution_matrix) で評価することがある(詳細は次回以降の回で)
#混同行列を表示する
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
cm = confusion_matrix(y_test, model.predict(X_test))
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=model.classes_)
disp.plot()
図8: 混同行列
モデルを保存する†
- 満足のいくモデルができたら,ファイルに書き出して保存しておこう
- Pythonのpickleモジュールを使う
- Google Driveに書き出す場合は,Colabにドライブをマウントして,保存先のフォルダのパス名を取得しておく
モデルのセーブ†
import pickle
with open("フォルダのパス名/保存ファイル名", "wb") as f:
pickle.dump(model, f)
モデルのロード†
import pickle
with open("フォルダのパス名/保存ファイル名", "rb") as f:
model = pickle.load(f)
#以降,アプリでmodelを利用する
アヤメの分類問題・プログラム全体†
- 必要なライブラリのインポート
################### ライブラリのインポート #########################
#いつものPandasとNumPyをインポート
import pandas as pd
import numpy as np
#日本語化MatplotLib
import matplotlib.pyplot as plt
!pip install japanize-matplotlib
import japanize_matplotlib
# Seabornをインポート
import seaborn as sns
# Pickleをインポート
import pickle
- データの取得
########################### データの取得 ############################
#アヤメデータの取得
iris_data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/iris-sample.csv")
- データの理解・可視化
ここでは省略.様々な角度から,データを眺めてみる(探索的データ分析:次回)
- 前処理
############################## 前処理 ################################
#特徴量に指定する列名リスト
features = ["がくの長さ", "がくの幅", "花びらの長さ", "花びらの幅"]
# 正解データに指定する列名
target = ["品種"]
#特徴量
X = iris_data[features]
#正解データ
y = iris_data[target]
#X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=2:1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
- モデルの選択と学習
###################### モデルの選択と学習 #############################
#モデルの選択
from sklearn import tree
model = tree.DecisionTreeClassifier(max_depth=3, random_state=0)
#モデルの学習(訓練データを使う)
model.fit(X_train, y_train)
#モデルの表示(オプショナル)
tree.plot_tree(model, feature_names=X.columns)
plt.show()
- モデルの評価
########################### モデルの評価 ###############################
#分類精度
acc = model.score(X_test, y_test)
print(f"分類精度: {acc}")
#実際にあっているかどうかを確認してみる (オプショナル)
y_eval = pd.DataFrame()
y_eval["正解"] = y_test["品種"]
y_eval["予測"] = model.predict(X_test)
y_eval["結果"] = (y_eval["正解"] == y_eval["予測"])
print(y_eval)
#混同行列を表示する (オプショナル)
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
cm = confusion_matrix(y_test, model.predict(X_test))
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=model.classes_)
disp.plot()
- モデルの保存
with open("/content/drive/MyDrive/フォルダ名/ファイル名.pkl", "wb") as f:
pickle.dump(model, f)
3. 機械学習の枠組み†
教師あり機械学習の実装の流れ†
- 今回行った機械学習体験を振り返りながら,教師あり機械学習の実装プロセスを見ておこう
図12: 教師あり機械学習モデルの開発プロセス
CRISP-DM: データ分析の標準的な手順†
- ビジネス理解 (Business Understanding)
- 対象とするビジネスがどのようなのものなのか,課題は何かを理解する
- データ分析の具体的な目標を決める.何をどこまで解決したいのか?
- 問いを立てる
- データ理解 (Data Understanding)
- 分析するデータ(一次データ,生データ)がどのようなものなのかを理解する
- 目標達成のために必要なデータ項目があるかを吟味する
- 難しければフェーズ1に立ち返ってよい
- データ準備 (Data Preparation)
- 一次データに前処理を行い,実施するデータ分析に必要なデータセットを構築する
- 質の良いデータセットを得られるかが,データ分析の結果を大きく作用する
- モデル作成 (Modeling)
- データセットに対して分析手法を適用し,モデルを作成する
- 評価 (Evaluation)
- 分析で得られた結果が,課題解決のために十分であるかをビジネスの観点から評価する
- 配備・運用 (Deployment)
- データ分析の結果を実際のビジネスに適用するための施策を考えていく
- フェーズ1で設定した目標を達成するための具体的なアクションを起こしていく
他の教師あり機械学習アルゴリズム†
- Scikit-Learnには,他にも様々なアルゴリズムが用意されている.詳細はここでは割愛するが,興味のある人は原理を調べてみてほしい
- 同じアルゴリズムでも考え方を少し変えることで,分類と回帰両方に対応しているものもある
- ロジスティック回帰 (logistic regression)
- サポートベクタマシン (support vector machine)
- ランダムフォレスト (random forest)
- 勾配ブースティング (gradient boosting)
- リッジ (ridge)
- ラッソ (lasso)
- 最近傍法 (nearest neighbors)
- 勾配ブースティング (gradient boosting)
機械学習が抱えるチャレンジ†
- 大量の教師データ(例題と正解がペアになっているデータ)を用意できるか?
- 単純な問題でも数千個,イメージ認識や音声認識だと数百万個のサンプルが必要
- 現実を表したデータを用意できるか?
- データが現在の運用実態にあっていないとうまくいかない.例えば10年前の売上データを学習しても現在の売上をうまく予測できない
- 品質の良いデータを用意できるか?
- 欠損値や外れ値,ノイズがたくさん含まれている場合,背後にある統計,パターンを見つけることが難しくなる
- 関係のある特徴量をそろえられるか?
- 目的変数に関係のある特徴量が十分に含まれ,無関係な特徴量が多すぎないことが大事
- 特徴量選択,特徴量抽出を駆使して,目的に寄与する特徴量をそろえる
- 訓練データへの過学習を防げるか?
- 訓練データに合わせようとすればするほど,未知のデータに対応できなくなる
神戸大学のDXリカレント事業の紹介へ進む†
DXリカレント教育事業