教師あり機械学習の基本
教師あり機械学習の基本
機械学習はいろいろな場面で役立つ仕組みを紡ぎ出せます。その中で、実用的な成果を得られる教師あり学習のしくみを見ていきましょう。
目的は何の法則か
例えば、「今日は猫が顔を洗うか」を予想したい、と考えます。そうした場合、法則にしたいので、これまで、猫が顔を洗ったかを観察日記を付けていたら可能です。何もないところからは分析できません。実績になるデータが必要です。「朝顔がいつ咲くか」の予想をしたいなら、それも観察日記を付けて、多くの個体の観察日記があったら、分析することが可能です。こうしたものは気候の変動といつその事象が起こったかが記録されていればできそうです。カメラでずっと撮っておいて気象データを合わせてデータ化したら出来るかもしれません(出来ないかもしれません)。何にせよ、目的が明確になってることは必要です。それが監修しながら法則を導く学習をする、教師あり学習です。
教師あり機械学習の基本工程としくみ
教師あり学習とは、用意されたデータを観察して、答え合わせをすることで法則を見出す、自分用法則発見器を作ります。基本的な手順は以下になります。
- データの準備:学習する元を用意
- データの学習:学習し、学習モデルを作る
- 検証:学習モデルの性能を検証
人間が代わりにやっても出来ますが、かなり面倒なので機械にやらせます。
学習の単純な例

電車が線路を走っているとします。測りだした場所から何メートルす進んだかを時刻と距離で表にします。
| 時刻 | 進んだ距離(m) |
|---|---|
| 10:10 | 0m |
| 10:20 | 13m |
| 10:50 | 39m |
| 11:30 | 52m |
このとき、12:00には何メートル、進んでいるでしょうか。この命題を機械学習でやる場合、
- 目的変数(目的の値):進んだ距離
- 説明変数(算出でヒントになる変数):時刻
として、学習させると、例えば時刻を変数x、目的変数をyとしたら、
として、数式を作り出します。そうしたら、12:00を与えたら、答えが出ます。
この数式の関数がどの様になっているかは、明確にできるものとむずかしいものがあります。また、出てくる答えは必ず正確ではなく、確率的に高い値になることに注意しましょう。
1.データの準備
先ず、学習するためのデータを用意します。数値化されていないものは数値にして、解析させます。
前期の例では時刻になっていますが、こうした場合は相対的な時刻にすることが多いです。他、様々なデータは数値化できれば何でも可能です。つまり、パソコンで観たり聴いたりしているなにかは全て、数値化されているので、可能です。これを、表の形にします。
説明変数をx~1~〜x~10~、目的変数をyとした場合、以下のようになります。
先程の電車の場合、距離に他の要因が影響しそうなら、それらを加えます。
| x~1~ | x~2~ | x~3~ | x~4~ | ... | x~10~ | y |
|---|---|---|---|---|---|---|
| 20 | 13 | |||||
| 50 | 39 | |||||
| 30 | 52 | |||||
これをプログラミングでやる場合、CSVで読み込んだりデータベースのAPIを呼び出すなどするでしょう。
学習させる
用意したデータを指定したモデルに学習させます。モデルにはいろいろな種類があり、また、それに合わせてデータの加工も必要です。基本的に数値化するのは必然ですが、どのような数値にするかは場合によります。前記の電車の場合は、単純にどれでも適合できそうです。
データの分割
データは一部を学習のテスト用に、一部を検証用に用います。学習は答え合わせをしながら目的変数を導く仕組みを構築し学習モデルが成果物として書き出されます。

例えばデータが100行あった場合、全体の80行を学習用にして、その行での説明変数から目的変数を導くように訓練します。訓練したモデルを使って、残りの20行で答え合わせをして、できるだけ答えが合うよう、学習を繰り返します。
データ分割の種類と役割
| データの種類 | 割合の目安 | 役割 | 使用タイミング |
|---|---|---|---|
| 訓練データ(Train) | 60-80% | モデルにパターンを学習させる。このデータで答え合わせをしながらモデルを構築 | 学習時 |
| 検証データ(Validation) | 10-20% | モデルの性能を評価し、パラメータ調整に使用。過学習を防ぐ | 学習時・調整時 |
| テストデータ(Test) | 10-20% | 最終的なモデルの性能を評価。学習に一切使わない未知のデータ | 最終評価時 |
例:100行のデータを分割する場合
- 訓練データ:60行(モデルを訓練)
- 検証データ:20行(パラメータ調整・過学習チェック)
- テストデータ:20行(最終性能評価)
どの行をどれに使うか、全体を使うかなどで成果は変わります、これを試しながら進めます。
モデルの選択
入力した説明変数を判断する機構のことを学習モデルと呼びます。教師あり学習にまつわる立場は以下の人がいます。
- モデルを作る汎用的な元を学術的に開発しているひと:企業や学術機関などの研究開発部門
- モデルの元を利用して自分用のモデルをつくるひと:利活用する組織の担当
- 出来上がったモデルを利用するひと:組織の顧客、一般人
ここでKaggleのコンペに参加するための開発は、2つ目の自分用のモデルをつくるひとに該当します。そうした場合、モデルの元は何を使うか、選択が必要になります。また、自動で選んでくれる機構を用いることも可能です。
| モデル名 | どういう学習に向いているか |
|---|---|
| 線形回帰(Linear Regression) | 数値予測、説明変数と目的変数の関係が直線的な場合。データの傾向を単純な式で表現したいとき |
| ロジスティック回帰(Logistic Regression) | 二値分類(Yes/No、合格/不合格など)、データが2つのグループに分かれる場合の予測 |
| 決定木(Decision Tree) | 分類・回帰の両方、データの特徴を「もし〜ならば」のルールで分岐させて判断。解釈しやすい |
| ランダムフォレスト(Random Forest) | 分類・回帰の両方、複数の決定木を組み合わせて精度向上。過学習しにくく、安定した予測 |
| 勾配ブースティング(Gradient Boosting / LightGBM / XGBoost) | 分類・回帰の両方、Kaggleなどのコンペで高精度を目指す場合。テーブルデータで特に強力 |
| ニューラルネットワーク(Neural Network / DNN) | 分類・回帰の両方、画像・音声・テキストなど複雑なパターン認識。大量データで威力を発揮 |
とりあえずどれを選んだら良いか分からない場合、似たデータを解析しているモデルを参考にして仮で組むのが得策です。Kaggleでよく見かけるは、LightGBM,XGBoost,ニューラルネットワーク系ですね。
検証する
プログラム的に問題がなければ、時間の長短はありますが(数秒から数日)、何らかのモデルが出来上がります。出来上がるモデルは、ターゲットの変数や分類などを確率的に高い予想をたてるだけで、絶対にこれだというものになっているかは分かりません。ニュートンの力学のようにはいかないものが常です。誤差がほぼない場合、既存の統計から導く確率でも出せそうな命題かも知れませんね。
改善を試みる方法
出来上がったモデルで満足するかを観て、納得できなければ改善を進めます。出来上がるものは確率的な答えだけなので完璧になることはありません。また、訓練が完璧な場合のほうが、適切ではないモデルが出来上がっている場合があります。
過学習に注意
元の問題に合わせすぎると、想定したものと違うモデルになる場合があります。
難しい数式にすると何でもフィットしやすくなる
訓練データ:
1 → 2, 2 → 4, 3 → 6, 4 → 8, 5 → 10
これは真の関係が y = 2x(比例)である典型的な例です。
正しい(単純な)モデル:
線形(一次)モデル y = 2x を学べば、未知の x=6 に対して y=12 を正しく予測できます。
過学習の誘導:
訓練点をすべて「ぴったり通る」ように高次の多項式(例:4次多項式)で近似すると、訓練データ上は誤差がほぼ0になるが、訓練に無い入力(x=6 など)での予測が真の関係から大きく外れることがあります(=一般化できない)。何等か、むずかしいことをやり過ぎて、以下のような数式に至っても、元のデータには合います。

データには色々なノイズが入っていたり、何かの影響で突然、へんな値になっている場合もあります。そうした、平均値や最頻値から離れた値(外れ値)まで合わせてしまうとこうしたことがより起こりえます。そこも面倒を見る関数を作り出せば、他のハズレ値に合わないばかりか、平常と捉えられる値にも合わなくなる可能性があります。訓練データに適合しすぎることを防ぐ必要があります。
データの精査
もっと良いモデルにしたい場合、用意したデータによって改善することがあります。色々なパターンがあるので一様に全てを試すのは資源的に難しいことが多く、統計的に推論して考察することが必要です。
ラベルを考える
説明変数による表の列で、どのような構成が効果的かを探ります。
相関関係を分析する
目的変数との関係が見られるものを揃えるのは、常套手段です。直線グラフになるような相関関係は分かりやすいでしょう。分布の比較に箱ひげを使うてもあります。
以下に一部を挙げます。
| 手法 | 主な出力 | 用途 |
|---|---|---|
| 散布図 | 点の分布 | 視覚的な傾向確認 |
| 相関ヒートマップ | 相関係数行列 | 線形関係の強さ |
| 箱ひげ図 | 分布の形 | カテゴリ別のばらつき比較 |
| クロス集計 | 比率表 | カテゴリ間の関係性 |
| 回帰分析 | 係数・p値 | 影響度と有意性の定量評価 |
散布図

ヒートマップ

箱ひげ図

個々の部分のヒントは統計学になります。ヒントをLLMに尋ねるのもいいと思います。
数値が相応しい形式か
例えば与える数値が日付の場合、曜日に変換したらグラフでで傾向が見られた、という場合なら、曜日を項目として設けた方が良い結果に繋がる可能性があります。また、極端に大きい値や小さい値は正規化した方が良い場合があります。正規化にはいくつか方法がありますが、外れ値に注意した変換が必要です。
全てを数値化して演算するニューラルネットなどのモデルは正規化が効きます。
多ければ良いと限らない不思議
これはKaggleなどで実際にやってるとあるのですが、説明変数が多いことが効果的とは限らない、ということです。LGBMで何等か追加してパラメータも変えても良い結果にならない場合があります。

こうなる理由はいくつか考えられます。 「説明変数を増やしても必ずしもモデル精度が向上しない」現象 について、LightGBM などの勾配ブースティング系で見られるケースの例を以下に挙げます。
1. ノイズや相関の影響
(1) ノイズ変数の追加
例えば、「猫が顔を洗う」データを取るときに、そのときサイコロを横で振って出目を記録したとします。絶対とは言えないですが、ほぼ関係なさそうです。でも関係あるかもしれないのでデータに入れたとすると、その数値に引っ張られて変な結果を招く可能性が高いのが、想像できると思います。有効な情報を持たない変数(ランダムノイズや無関係な特徴量)を増やすと、モデルがそのノイズに引っ張られて学習してしまうことがあります。
ブースティング系は強力に特徴量を活かせる分、ノイズにも敏感になりやすいです。
(2) 高い相関の説明変数
同じ情報を持つ特徴量を増やしても、新しい情報がほとんどないため、予測性能の改善には寄与しません。
過学習のリスクが増えるだけで、テスト精度は改善しないことが多いです。ただし、やってみないと分からないともいえるので、効果的ではなかった場合は、想定通り無駄だったという結論になりますが、そうすれば他のものを探す候補が減るので、予想したら試して実験することも大切です。
高い相関の説明変数の具体例:
| 目的変数 | 高相関な説明変数の例 | 問題点 |
|---|---|---|
| 住宅価格 | 延床面積 と 部屋数 | 延床面積が広ければ部屋数も多い傾向。ほぼ同じ情報を重複して持つ |
| 売上予測 | 広告費(円) と 広告費(ドル) | 為替レート固定なら完全に同じ情報。片方だけで十分 |
| 体重予測 | 身長(cm) と 身長(m) | 単位が違うだけで同一の情報。どちらか一方のみ使用すべき |
| 気温予測 | 摂氏温度 と 華氏温度 | 変換式で結びついており、独立した情報ではない |
| 試験の合格予測 | 模試A の点数 と 模試B の点数(同じ範囲) | 両方とも同じ学力を測定しており、相関が非常に高い |
これらの変数を両方入れても新しい情報は増えず、モデルが混乱したり過学習したりする原因になります。
2. モデルのバイアスと容量の限界
情報を増やしたとき、必要に応じてパラメータを調整する必要があります。LightGBM は決定木ベースで特徴量の分割を行うため、木の深さや葉の数には情報を処理できる限界があります。
追加した特徴量を活かすためには、木の深さを増やす、葉数を増やすなど容量を増やす必要がありますが、そうすると過学習のリスクが高まります。
実務では、追加した変数に対してモデル容量を調整しても、テストデータで精度が伸びないことがあります。
3. 特徴量選択・重要度の問題
LightGBM は自動的に特徴量を選んで使います。
追加した特徴量が既存の特徴量より情報量が少ない場合、モデルはそもそも使わないことがあります。
そのため 変数を増やしても性能がほぼ変わらない、あるいはわずかに悪化することがあります。
4. データのサイズ・サンプル数の制約
- 説明変数が増えても、サンプル数が少ない場合は 次元の呪い が発生します。
- 多くの変数を追加すると、モデルは訓練データに合わせすぎて、無用に複雑な構造になり過学習しやすく、テストデータで精度が伸びません。
5. パラメータ調整の難しさ
- 追加変数に合わせて
num_leavesやmax_depth、learning_rateを変えても、最適値の探索空間が広くなるため、局所最適に陥ることがあります。 - 特に Kaggle のようにデータが非公開の場合、公開スコアと非公開スコアの差が大きく出ることもあります。
💡 まとめの推察
- 追加変数がノイズや相関の強い特徴量だと効果がない
- モデル容量(木の深さや葉数)とのバランスが悪い
- LightGBM は特徴量を自動選択するので、追加変数が活かされない場合がある
- サンプル数が少ない場合は次元の呪いで精度が伸びない
- パラメータ調整が複雑になり、改善が難しい
こうしたことに注意して追加しましょう。
数値に置き換えるカテゴリとワンホット(LGBMなど)
文字列は基本的に受け入れられないので、何等か変える必要があります。例えばぬいぐるみの売上データで犬、猫、ひつじ、クマの種類を変数として学習をしたいとします。学習には数値化が必要なので、以下の数値を割り当てたとします。
| 動物 | 割り当てる数字 |
|---|---|
| 犬 | 1 |
| 猫 | 2 |
| ひつじ | 3 |
| クマ | 4 |
データ上では番号を変数として扱うため、大きさを比較したり、「犬を2倍にしたら猫」などの謎の法則を見出してしまいます。こうしたことを避けたい場合は、ワンホットやカテゴリのラベルであると認識させる、などの方法があります。いろいろな方法があるので、調べて検討してください。
ワンホット化の例(ダミー変数)
| 動物 | 犬 | 猫 | ひつじ | クマ |
|---|---|---|---|---|
| 犬 | 1 | 0 | 0 | 0 |
| 猫 | 0 | 1 | 0 | 0 |
| ひつじ | 0 | 0 | 1 | 0 |
| クマ | 0 | 0 | 0 | 1 |
それぞれのカテゴリを 0/1 の列に展開することで、「大小関係」という誤った仮定を避けられます。
カテゴリ定義して LightGBM で学習する(Python)
カテゴリ列をそのまま使いたい場合は、pandas の category 型にして LightGBM に渡します。One-Hot せずに扱えるため、高次元化を防げます。
import pandas as pd
from sklearn.model_selection import train_test_split
from lightgbm import LGBMRegressor # 分類なら LGBMClassifier
# サンプルデータ(target は目的変数の例)
df = pd.DataFrame({
'animal': ['犬', '猫', 'ひつじ', 'クマ', '犬', '猫', 'クマ', 'ひつじ'],
'feature1': [10, 12, 9, 20, 11, 13, 18, 8],
'target': [100, 120, 95, 200, 110, 125, 190, 90]
})
# カテゴリ型に変換(ここがポイント)
df['animal'] = df['animal'].astype('category')
X = df[['animal', 'feature1']]
y = df['target']
X_train, X_valid, y_train, y_valid = train_test_split(
X, y, test_size=0.25, random_state=42
)
# 回帰モデルの例(分類なら LGBMClassifier に置き換え)
model = LGBMRegressor(
n_estimators=200,
learning_rate=0.05,
random_state=42
)
# pandas の category 型をそのまま渡す。必要に応じて categorical_feature を明示
model.fit(
X_train, y_train,
categorical_feature=['animal'],
eval_set=[(X_valid, y_valid)],
verbose=False
)
pred = model.predict(X_valid)
print(pred[:5])
ポイント:
-
df['animal'].astype('category')にすることで、LightGBM がカテゴリ列として解釈します。 - One-Hot と比べて列爆発を避けられ、木ベースのモデルでは精度・速度の面で有利なことが多いです。
欠損値、外れ値の扱い
データは、記録に残っていない部分があったり、なにかの観測や会計記録などによる値によって構成されます。その場合、微細な誤差を含んだり、何かの理由で離れた値を刻むことがあります。そうした部分を考慮してデータを構築する必要があります。
欠損値の対応には以下の例があります。
- とにかく消す
- 行・列の削除:
dropna()(axis=0/1、subset、threshで条件指定)
- 行・列の削除:
- 何かで埋める
- 単純代入(数値):平均・中央値・最頻値・定数で埋める(
fillna()) - 単純代入(カテゴリ):最頻カテゴリ・「Unknown」などの擬似カテゴリで埋める
- グループ別代入:
groupby()単位で平均・中央値を使って補完(例:店舗ごと、カテゴリごと) - 前方/後方補完:
ffill/bfill(時系列や並びに意味がある場合) - 補間(interpolate):
interpolate(method='time'|'linear'|'spline'...)(時系列の連続量に有効)
- 単純代入(数値):平均・中央値・最頻値・定数で埋める(
- 欠損が在ることを学習の変数にする
- 欠損フラグ列の追加:
isna().astype(int)で欠損の有無を特徴量として持たせる
- 欠損フラグ列の追加:
- 補間にアルゴリズムを用いる
- モデルによる推定補完:
KNNImputer、IterativeImputer(多変量補完)や回帰・分類モデルでの推定 - 高欠損率列の削除:一定割合以上の欠損がある列をドロップ(情報量が乏しい場合)
- 整合性ベースの対応:複数列の整合が崩れる行はまとめて削除 or ドメイン知識で補完ルール化
- モデルによる推定補完:
効果的なものを予測を立て、検証して利用しましょう。
他方、外れ値は、無用なデータを取り入れない工夫です。外れ値とする基準は、統計的に見て極端に大きかったり小さいデータを省き、欠損値のように代替する値で埋めるか、その行または列を取り去ることも有効です。
しかしながら、外れ値の判定はなかなか難しいです。
例えば、何かの売上予測で、突然、値が大きくなっている場合があるとします。それを省いたら良いかは単純には分かりません。何かに相関しているかもしれません。例えばお餅がお正月だけ売れる、等です。
また、単純な値としてみたら、外れの値と思うとそうでもない、という場合もあります。
この表は3のべき乗を並べました。
| k | 3のk乗 |
|---|---|
| -5 | 0.004115 |
| -4 | 0.012346 |
| -3 | 0.037037 |
| -2 | 0.111111 |
| -1 | 0.333333 |
| 0 | 1 |
| 1 | 3 |
| 2 | 9 |
| 3 | 27 |
| 4 | 81 |
| 5 | 243 |
対数を取ると大きな値の差を圧縮でき、外れ値の見え方が変わることがあります。-5乗と+5乗では、出てきた小数をみるとかなり離れてますが、対数にしたらそうでもありません。こうした、指数・対数という数値の感覚は人間の知覚にも関係するので、よく扱う形です。例えば楽器の1オクターブの上下は、周波数の2倍・2分の1になっており、周波数の対数表現になります。音の大きさを表すデシベルも同様です。何かを観測するときに指数・対数が便利な場合は、対数による単位を使っています。
変数同士の組み合わせ・追加
何かと何かを掛け算したり引き算して絶対値をとるなどで演算し、新たな何かを生み出す方法です。学習するときに効き目のあるラベルであれば、既に意味がありますが、組み合わせたら新たな価値を生む可能性があります。何かの寸法で縦と横があったら、面積にしたら更に効果的になる可能性がある、などです。また、時系列データなら、他の行を使って前日との差を入れると変化があるかも知れません。学習する中身をあらかじめ人間がお膳立てする形ですね。
- 面積(例:不動産・製造):
\text{面積} = \text{縦} \times \text{横} - 寸法の2変数から合成して、価格や重さなどの予測に効くことが多い
- 伸び率(例:売上の時系列):
\text{伸び率} = \dfrac{\text{当日売上} - \text{前日売上}}{\text{前日売上}} - 差よりも比率で変化を表すと、規模の違いを正規化できる
- 客単価(例:小売・飲食):
\text{客単価} = \dfrac{\text{売上}}{\text{来店者数}} - 総売上の大小に引っ張られず、純粋な“1人あたり”の指標として有効
- ラグ特徴量(例:時系列の基礎):
y_{t-1},\; y_{t-7}, \; \text{移動平均} = \dfrac{1}{k}\sum_{i=1}^{k} y_{t-i},\; - $ \text{差分} = y_t - y_{t-1}$
- ラグ特徴量とは、時系列で過去の値(例:1日前・7日前など)を現在の説明変数として加える手法で、直近の動きや周期性を取り込むための基本的な特徴量です。
- 直近期の影響や季節性を取り込み、ノイズを平滑化するのに有効(ただし未来情報の混入に注意が必要)
学習データの分割を考える
学習する範囲を固定して開発すると、学習時のスコアと検証時に改善の違いが観られる場合、過学習の可能性があります。そうした場合、データ分割を見直すことも検討します。
行の範囲を考える
過学習になる場合、学習データと検証データで違った偏りがあり、それに合わせて学習している可能性があります。また、時系列での場合は連続データが乏しいと有効に使えない場合があります。それらを意識して取り除いたり、変数化します。
-
特徴量が不十分になる可能性の回避
- ラグ/移動統計の整合:ラグ・移動平均・移動分散を作る場合、学習に使う行の前方に十分な履歴がある期間だけを採用する。
- コールドスタート評価:新規顧客/新商品など“未知エンティティ”は履歴特徴が乏しいため、検証側に回して性能確認し、必要に応じてベースライン特徴(カテゴリ・静的属性)やルールを併用。
- スキーマ/計測変更境界で分ける:仕様変更で特徴量の定義が変わると学習・推論の不整合が生じるため、境界でモデルを分けるか変換を統一する。
-
特定の偏りを防ぐ
- 未来の情報を入れない:予測の基準日より後のデータや未来を含む集計は使わない。
- 季節やイベントを合わせる:学習と検証で同じ季節・曜日・キャンペーンが入るようにする。
- 異常データは扱いを決める:障害やプロモーションなど変わった期間は除外するか、フラグを立てる。
- 同じ顧客や店舗が分かれるとダメ:同一の顧客・店舗の記録が train と test にまたがらないようにする。
- 重複データを減らす:同じ内容の行が多いと偏るので間引く。
- 偏りを避けるため分ける:地域や期間ごとの比率が偏らないようにサンプリングする。
- 古いデータの影響を調整する:古い行の重みを小さくして、最近のデータを重視する方法もある。
- 過去すぎるデータは使いすぎない:制度や仕様が変わった古いデータは除外するか期間を限定する。
-
特徴量が不十分になる可能性の回避
- ラグや移動平均には履歴が必要:過去の値を使う特徴量は、その分だけ前のデータが揃っている行だけ使う。
- 新しい顧客や商品は別に評価する:履歴がないものは検証で性能を確かめ、必要なら別ルールを用意する。
- 計測やスキーマが変わったら分ける:仕様変更の前後で別モデルにするか、変換を揃える。
交差検証を検討する
テストするデータによって過学習が見られる場合、交差検証によって対象を変えていくことによって偏りを軽減するのが交差検証です。
以下は KFold(5分割)の例です。データを5つのブロックに分け、各ターンで1つを検証(V)、残りを学習(T)に使います。表は「データのご分割」とし、各行が1回分の学習ターンを表します。
| データの分割 | ブロック1 | ブロック2 | ブロック3 | ブロック4 | ブロック5 |
|---|---|---|---|---|---|
| ラウンド1 | V | T | T | T | T |
| ラウンド2 | T | V | T | T | T |
| ラウンド3 | T | T | V | T | T |
| ラウンド4 | T | T | T | V | T |
| ラウンド5 | T | T | T | T | V |
(注)V = 検証データ、T = 学習データ。これにより全データが一度は検証に使われ、偏りの確認がしやすくなります。
モデルを5つ生成し平均を取る、などで利用します。

モデルの検討
対象によってはじめに選択したモデルでは求める性能に達しない場合、他のモデルを選んだり、組み合わせで性能を追求する方法があります。
モデルを変更する
どういった問題解決をしたいのかを考えたうえで、使えるモデルを別のものに変更できます。
モデル切替の難易度マトリクス(回帰)
以下の表は行と列がモデルを表し、セルの絵文字で「データフレームをあまり変えずに別のモデルに切り替えられるか」を示します。
絵文字の意味:😄(簡単に切替可能) / 😐(可能だが前処理が少し必要) / 😢(切替が難しくデータ整備が必要)
| モデル ⇢ | Linear | Lasso | RandomForest | LightGBM | NeuralNetwork |
|---|---|---|---|---|---|
| Linear | 😄 | 😄 | 😐 | 😢 | 😐 |
| Lasso | 😄 | 😄 | 😐 | 😢 | 😐 |
| RandomForest | 😐 | 😐 | 😄 | 😄 | 😐 |
| LightGBM | 😢 | 😢 | 😄 | 😄 | 😐 |
| NeuralNetwork | 😐 | 😐 | 😢 | 😢 | 😄 |
モデル切替の難易度マトリクス(分類)
| モデル ⇢ | Logistic | DecisionTree | RandomForest | LightGBM | NeuralNetwork |
|---|---|---|---|---|---|
| Logistic | 😄 | 😐 | 😐 | 😢 | 😐 |
| DecisionTree | 😐 | 😄 | 😄 | 😄 | 😐 |
| RandomForest | 😐 | 😄 | 😄 | 😄 | 😐 |
| LightGBM | 😢 | 😄 | 😄 | 😄 | 😐 |
| NeuralNetwork | 😐 | 😐 | 😢 | 😢 | 😄 |
[注釈]
この表は一般的な前処理の容易さを示した目安です。
カテゴリ扱い(One-Hot かカテゴリ型)やスケーリング、欠損値補完の有無によってセルの難易度は変わります。
ニューラルネットはスケーリングやカテゴリ埋め込みが必要になるため、他モデルとの切替には一定の前処理が必要です。
得意分野で考える
挙げた中ではニューラルネットは全てを数値の演算と関数で繋げていくので、他のものと少し異質になります。画像のピクセルなどの同種の多次元のデータには効果的です。時系列に向いているものなど、色々在るので調べて試してみましょう。
自動で選んでもらう
選ぶのが面倒だ、という場合は、自動的に複数のモデルを試して選ぶAutoMLなどを利用する方法もあります。
調べると色々在ると思いますので、適宜、利用してみてください。一旦、最適化されたモデルが選定されますが、そこから改善を試みることができるかはまた別の話になります。
AutoML(自動機械学習)のメリット・デメリット
AutoML はモデル探索やハイパーパラメータ探索を自動化してくれる便利なツールです。以下は運用時に意識したい観点ごとに、AutoML の長所と短所(出力後の改善可否や可視化のしやすさを含む)をまとめた表です。
| 観点 | AutoML のメリット | 注意点・出力後の扱い |
|---|---|---|
| 精度探索 | 多数のモデルとハイパーパラメータを自動的に探索し、短時間で良い候補を見つけやすい | 見つかったモデルは複雑になりやすく、内部構成の理解や詳細な手動改善に工数がかかる(改善は可能だが手順の理解が必要) |
| 実装・試作速度 | 最小限の設定で短期間に候補モデルを得られる(PoC に強い) | デフォルトで出た結果をそのまま運用すると、リークや過学習を見落としやすい。結果の精査が必須 |
| 出力モデルの改善可否 | 多くの AutoML は特徴量重要度やモデルのサマリを出すため、その情報を元に改善は可能 | 一部のツールは最終モデルがアンサンブルや特殊化されており、個別モデルの微調整や再現が難しい場合がある |
| 可視化・解釈性 | プラットフォームによっては比較チャートや重要度の可視化が充実している | 可視化はできても深い因果解釈や詳細な内部差分の解析は別途ツールが要ることが多い |
| 前処理の自動化 | 欠損処理・カテゴリ変換・スケーリングなどを自動で行い準備を省ける | 自動前処理が必ず最適とは限らず、ドメイン知識に基づく処理は手動で追加する必要がある |
| 計算資源とコスト | 並列探索で効率的に候補を探せる(クラウドでスケール可) | 広範な探索は時間・計算コストが高くなる。予算や時間制約を設定することが重要 |
| 再現性・管理 | 実験ログや最終構成を保存する機能があるツールが多い | バージョンやラン設定に依存するため、厳密な再現には環境・設定の記録が必須 |
AutoML は「早く良い候補を得る」には強力ですが、出力モデルを本番利用する前に可視化・解釈、追加の特徴量改善、リークチェックなど人の介入が必要です。
パラメーターチューニング
学習する際にモデルの規模や回数など、様々なパラメータで指定します。この値を変更することで改善を試みるのがパラメーターチューニングです。
自分で試す方法
以下は LightGBM を使ったハイパーパラメータ探索の実例です。まずはランダムサーチで広く探索し、良さそうな範囲が見えたらグリッドサーチで詰める、という流れがおすすめです。
# 例:RandomizedSearchCV を使った LightGBM のチューニング(回帰)
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from lightgbm import LGBMRegressor
# X, y を用意(例として)
# X = df.drop(columns=['target'])
# y = df['target']
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=42)
param_dist = {
'n_estimators': [100, 200, 400, 800],
'learning_rate': [0.01, 0.03, 0.05, 0.1],
'num_leaves': [31, 63, 127, 255],
'max_depth': [-1, 6, 10, 16],
'subsample': [0.6, 0.8, 1.0],
'colsample_bytree': [0.6, 0.8, 1.0]
}
model = LGBMRegressor(random_state=42)
rs = RandomizedSearchCV(
estimator=model,
param_distributions=param_dist,
n_iter=30,
scoring='neg_mean_squared_error',
cv=3,
n_jobs=-1,
random_state=42,
verbose=1
)
# fit 時に検証データと early_stopping を渡すと効率的
rs.fit(X_train, y_train, eval_set=[(X_valid, y_valid)], early_stopping_rounds=50, verbose=False)
print('best params:', rs.best_params_)
print('best score:', rs.best_score_)
この例ではランダムに試していますが、それで得た良い結果のパラメータの付近を、すこしずつ値を変えて試すGridSearchCVを行い微調整するなどをしていきます。
自動でチューニング
より効率的に探索したい場合は Optuna などのチューニング用のライブラリを用いて詰めていく方法があります。
これで改善しない場合は再び、データの構造から見直していきます。
複数モデルのアンサンブル
単一のモデルであまり改善しなかった場合、交差検証で複数のモデルを利用するのと同じく、別の形のモデルを併用し、平均などを用いて合わせるアンサンブルを試します。
既存のコードを参考にする
機械学習は先人の知恵がたくさん、あります。LLMが紡ぎ出すコードを利用するのもその一つですし、ネットで検索しても良いでしょう。処理をどのように行うか=アルゴリズムには著作権はありませんがプログラムコードには著作権があるので、もし商用なら適宜、注意して利用します。
環境が違うと再現できないので注意
GoogleColabとKaggleなどの環境や、PCなどでの違いに加えて、利用するライブラリのバージョンなどで動作保証はありません。そのまま動かしたらエラーになるなどは頻発します。中身をよく見ましょう。
参加目的を考えて利用を推奨
コンペの場合、既に終わっているものはモデルやコードを公開しているものが多々、あります。同じ環境で動作するものであれば、そっくり拝借すれば、そのまま動きます。単純に高スコアを狙うだけならそれで問題ありません。
しかしながら、その内容を理解したり、自分が上位勢を上回りたいのであれば、その限りではありません。
自分が目標にされることを目指す
既存の公開されたコードは多岐にわたりますが、自分が何処に目標を置くか考えた際、自分のコードが誰かの参考になったら、同じレベルに近づけたと思えます。袖に公開されているコードは、発信者としては、どこか改善点が在るか、他の人が見たら間違っていないかが気になって公開している側面があります。それが大規模になるとOSSとして無料で享受できる色々なソフトウエアの開発につながっていきます。
LLMには細かく解説させる
同じ学習手ベルにない人が開発したものは、何となく分かるけど、細かいことは分からない状態だと思います。その学習の差分を埋めるために、LLMを有効活用しましょう。
当方は、よく以下のキーワードを入れます。
- 中学生でもわかるレベル
- 文系の大学生でもわかるように
- 初めて機械学習をやった人でも分る
アドレスをそのままコピペで解析させたり、一度、DLしてLLMにアップロードして解析して説明文をつけたバージョンを作らせる、などが可能です。
学習の第一歩は何が分からないかが判ること
色々と試行錯誤しようとするときに、適当にLLMのコードを突っ込んでいって、LLMに改善させても限界で止まることがよくあります。そのときに、自分が何がわからなくて困っているかわからず、先に進めない状況に陥ります。
質問をしないと先にいかないということは、質問ができない場合は進歩が止まります。まずは、何がわからないのかを把握しましょう。そのためには、LLMに尋ねるなら、とにかく少しでもわからない場合は判るまで掘り下げるなどが必要です。
自身が分からないことを把握することが肝要です。
Discussion