MLの仕事を小例で体験|データ・AI・4つの仕事を知る
このページはプロモーション(広告)を含みます。
データ・AI・4つの仕事を知る(初級・読む20分+演習30分)
この授業のゴール
- 予測の依頼を、目的変数・予測する時点・使える入力・評価期間に分けて書ける
- 時間順に学習期間と評価期間を分け、単純な基準と2つの方法の平均絶対誤差を比べられる
- 予測する時点では手に入らない入力(漏洩)を見つけて除外できる
- 誤差の大きさと、欠品・廃棄の費用を別に評価し、運用に必要な要素を挙げられる
仕事でどう使うか
機械学習(ML)エンジニアの仕事は、モデルを作ることに限りません。予測を業務で使い続けられる仕組みにすることが中心です。データの取得、予測の実行、現場への提示、誤りの監視、失敗したときの代替手順までが対象になります。
| 路線 | この授業の使いどころ |
|---|---|
| DS(データサイエンティスト) | 予測の前に、何が基準になるかを分析で示す。予測誤差と事業上の損失を並べて報告する |
| ML(機械学習エンジニア) | 予測の入力・評価期間・基準を定義し、運用できる形(定期実行・監視・代替手順)にする |
| DX(DX推進・AI企画) | 予測を使う業務手順(誰が見て、誰が発注を決めるか)を設計し、例外を処理する |
| RS(研究者) | 予測法の比較条件(同じデータ、同じ分割、同じ指標)をそろえる |
担当は職場により異なります。肩書でなく成果物(予測の仕様書・評価結果・運用手順)で確認してください。
前提
- 分析・予測・生成の区別と、平均絶対誤差(MAE)、ベースライン → 分析と予測と生成の違い
- 要素分解で入力候補を探す考え方 → DSの仕事を小例で体験
- 表の1行の単位(この授業では、1行=1週)→ 行と列と1行の単位
Pythonのリスト([1, 2, 3] のように値を並べた型)と、スライス(a[2:5] で添字2以上5未満の要素を取り出す書き方。添字は0から数える)を使います。
身近な状況:「来週の仕入れ量を決めたい」
雑貨店「ことり堂」(架空)で、人気商品Aの仕入れ量を、毎週金曜に翌週ぶんを決めています。仕入れが少なければ売り逃し(欠品)、多ければ売れ残り(廃棄や値引き)になります。店長は言います。「AIで来週の販売個数を当てられない?」
手元にあるのは、12週間の販売個数と来店者数です(架空のデータ)。
| 週 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 販売個数(個) | 100 | 104 | 98 | 110 | 108 | 115 | 112 | 120 | 118 | 125 | 122 | 130 |
| 来店者数(人) | 500 | 520 | 490 | 550 | 540 | 575 | 560 | 600 | 590 | 625 | 610 | 650 |
MLエンジニアは、いきなりモデルを選ばず、次の4点を確認します。
- 何を当てるのか(目的変数):翌週の販売個数(個)。
- いつ予測するのか:毎週金曜に、翌週1週間ぶんを予測する。
- その時点で使える入力は何か:金曜までの販売個数、来店者数、曜日の情報。翌週の来店者数は金曜には分からない。
- どう評価するのか:予測を作った後に観測された週での誤差と、欠品・廃棄の損失。
この4点が曖昧だと、「使えない予測」になります。
直感的な説明:過去で練習し、未来で試す
予測の良し悪しは、予測を作る時点では見えなかった期間で測ります。試験にたとえると分かりやすいです。
- 学習期間(練習問題):予測の方法を作ったり、調整したりするために使う期間。
- 評価期間(本番の試験):作った方法で予測し、あとで実績と比べる期間。学習には使わない。
練習問題と本番が同じ問題なら、満点が取れます。同じように、学習期間のデータで誤差を測ると、実際より良く見えます。
時間のあるデータでは順番も重要です。第5週を予測するのに第6週以降のデータを使ってはいけません。運用では未来のデータは存在しないからです。
もう1つ重要なのは、複雑な方法の前に、単純な基準を測ることです。「前の週と同じ個数にする」だけで十分当たることがあります。基準より良くならない方法は、運用の手間をかける価値がありません。
正確な定義:時間順の分割・ベースライン・漏洩
用語を定義します。
- 目的変数:当てたい値(ここでは翌週の販売個数)。
- 特徴量:予測に使う入力(過去の販売個数、来店者数など)。
- 時間順分割:データを時間の順に、前半を学習期間、後半を評価期間に分ける。ことり堂では、第1〜8週を学習期間、第9〜12週を評価期間にします。
- ベースライン:比較の基準になる単純な方法。ここでは2つ使います。
- 方法N(前週と同じ):第 $t$ 週の予測 $\hat{y}_t = y_{t-1}$。
- 方法M(4週移動平均):直前4週の平均 $\hat{y}_t = \frac{1}{4}\sum_{j=1}^{4} y_{t-j}$。
- データ漏洩(リーク):予測する時点では手に入らない情報が、入力や学習に混ざっていること。評価の誤差が見かけ上小さくなり、運用では当たらない原因になる。
評価には、L02で学んだ平均絶対誤差 $\text{MAE} = \frac{1}{n}\sum |y_i - \hat{y}_i|$ を使います。$y_i$ は実績(個)、$\hat{y}_i$ は予測(個)、$n$ は評価した週の数です。
評価期間(第9〜12週)の実績は $(118, 125, 122, 130)$ です。
方法Nの予測は、各週の前週の実績で、$(120, 118, 125, 122)$。誤差は $2, 7, 3, 8$ で、合計20、MAE は $20 \div 4 = 5.0$ 個です。
方法Mの予測は、第9週が $(108+115+112+120)/4 = 113.75$、第10週が $(115+112+120+118)/4 = 116.25$、第11週が $(112+120+118+125)/4 = 118.75$、第12週が $(120+118+125+122)/4 = 121.25$。誤差は $4.25, 8.75, 3.25, 8.75$ で、合計25、MAEは $25 \div 4 = 6.25$ 個です。
この期間では、「前週と同じ」のほうが4週移動平均より誤差が小さいです。右肩上がりのため、過去の平均は低めになるからです。
段階付き例題:基準を測り、費用で評価し、漏洩を見つける
ステップ1:基準の誤差を測る。次のコードで、2つの方法のMAEを計算します。sales[i-4:i] は、第 $i$ 番目(0から数える)の直前4週を取り出すスライスです。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
test = sales[8:] # 評価期間(第9〜12週)
def mae(actual, pred):
return sum(abs(a - p) for a, p in zip(actual, pred)) / len(actual)
pred_n = [sales[i - 1] for i in range(8, 12)] # 前週と同じ
pred_m = [sum(sales[i - 4:i]) / 4 for i in range(8, 12)] # 直前4週の平均
print("実績", test)
print("方法N", pred_n, "MAE", mae(test, pred_n))
print("方法M", pred_m, "MAE", mae(test, pred_m))
出力は、方法Nが [120, 118, 125, 122] でMAE 5.0、方法Mが [113.75, 116.25, 118.75, 121.25] でMAE 6.25です。
ステップ2:誤差を費用で見る。仕入れでは、多すぎる(廃棄)と少なすぎる(欠品)で損失が違います。仮に、1個多いと100円、1個足りないと300円の損失(売り逃した粗利)とします(架空の仮定)。予測が実績より大きい分が「過剰」、小さい分が「不足」です。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
test = sales[8:]
def mae(actual, pred):
return sum(abs(a - p) for a, p in zip(actual, pred)) / len(actual)
def loss(actual, pred, over_cost=100, under_cost=300):
over = sum(max(p - a, 0) for a, p in zip(actual, pred)) # 過剰(個)
under = sum(max(a - p, 0) for a, p in zip(actual, pred)) # 不足(個)
return over * over_cost + under * under_cost
pred_n = [sales[i - 1] for i in range(8, 12)]
pred_n5 = [x + 5 for x in pred_n] # 前週と同じに5個上乗せ
print("方法N MAE", mae(test, pred_n), "損失", loss(test, pred_n), "円")
print("方法N+5 MAE", mae(test, pred_n5), "損失", loss(test, pred_n5), "円")
出力は、方法Nが MAE 5.0・損失 5000円、方法N+5が MAE 5.0・損失 3000円です。誤差の大きさ(MAE)は同じでも、事業上の損失は違います。不足が高くつく状況では、少し多めの予測が得です。精度と事業価値は別の量です。
ステップ3:漏洩を見つける。「販売個数=来店者数の0.2倍」という関係が、この表では成り立っています。そこで、評価期間の各週について「当週の来店者数×0.2」で予測すると、どうなるでしょう。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
test = sales[8:]
pred_leak = [round(0.2 * visitors[i], 6) for i in range(8, 12)] # 当週の来店者数を使う
pred_ok = [round(0.2 * visitors[i - 1], 6) for i in range(8, 12)] # 前週の来店者数を使う
mae = lambda a, p: sum(abs(x - y) for x, y in zip(a, p)) / len(a)
print("当週の来店者数を使った予測", pred_leak, "MAE", mae(test, pred_leak))
print("前週の来店者数を使った予測", pred_ok, "MAE", mae(test, pred_ok))
出力は、当週の来店者数を使うとMAE 0.0、前週の来店者数を使うとMAE 5.0です。MAE 0.0は魅力的に見えますが、金曜の時点では翌週の来店者数は分かりません。これは漏洩です。運用では当週の来店者数が手に入らず、モデルは動かせません。来店者数の予測を入力に使うなら、その誤差が加わります。
操作して理解する:自分で基準を作り、評価期間を変える
次のコードで、評価期間と方法を変えて試します。評価期間を短くしたり、長くしたりして、結果を予想してください。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
def mae(actual, pred):
return sum(abs(a - p) for a, p in zip(actual, pred)) / len(actual)
def evaluate(start):
# start 番目(0から数える)以降を評価期間にする
idx = range(start, len(sales))
test = [sales[i] for i in idx]
n = [sales[i - 1] for i in idx]
m = [sum(sales[i - 4:i]) / 4 for i in idx]
return round(mae(test, n), 2), round(mae(test, m), 2)
for start in (4, 6, 8, 10):
print("評価開始", start + 1, "週目から: 方法N, 方法M =", evaluate(start))
出力は次のとおりです。
評価開始 5 週目から: 方法N, 方法M = (5.0, 6.62)
評価開始 7 週目から: 方法N, 方法M = (5.17, 6.33)
評価開始 9 週目から: 方法N, 方法M = (5.0, 6.25)
評価開始 11 週目から: 方法N, 方法M = (5.5, 6.0)
考えてみましょう。
- どの開始週でも、方法Nの誤差(5.0〜5.5個)が方法Mの誤差(6.0〜6.6個)より小さい。評価期間を変えても順位が変わらないので、この比較は少し信頼できます。
- 一方、同じ方法Nでも、評価期間によって5.0、5.17、5.0、5.5と値が動きます。12週間のうち数週間だけの評価では、小さな差を強く言えません。
- 方法Mの
4を2に変えて、結果を確認しましょう。
運用のためには、(1)毎週金曜の午前に実行して期限内に結果を出す、(2)入力の欠損・休業日の0・極端な値を確認する、(3)予測値と前週の実績を並べて現場に示し、最終的に誰が発注数を決めるかを定める、(4)予測と実績の誤差を毎週記録し基準より悪化したら知らせる、(5)予測が出ないときは「前週と同じ」で発注する、という要素も必要です。
発展:時系列の評価とモデルの更新
評価期間を1つに固定する方法のほかに、時間を進めながら繰り返し評価する方法があります。第8週までで第9週を予測、第9週までで第10週を予測、というように評価を1週ずつ進めて誤差を集めると、4週だけの評価より結論が安定します。scikit-learn の TimeSeriesSplit は、時間順を保ったまま分割する道具です(本授業の範囲外)。
- 傾向と季節性:右肩上がりのデータに移動平均を使うと、常に低めになります。周期があるなら、前年の同じ時期を基準にする方法もあります。
- 分布の変化:新商品、価格改定、競合の出店で、過去の規則が変わることがあります。予測と実績の誤差を継続して監視して気づきます。
- 指標の選択:欠品が高くつくなら、損失を直接評価に含める設計もあります。
手法(線形回帰、決定木、ニューラルネットなど)は、これらの設計が固まってから選びます。基準を超えられない手法は導入しません。
よくある失敗
失敗1:学習したデータでそのまま誤差を測る
誤った評価:第1〜12週すべてを使って方法を作り、同じ第1〜12週で誤差を測る。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
# 全期間の平均値を予測として使い、同じ期間で評価する
avg = sum(sales) / len(sales)
pred_all = [avg] * len(sales)
mae = lambda a, p: sum(abs(x - y) for x, y in zip(a, p)) / len(a)
print("全期間の平均", round(avg, 2))
print("同じ期間で評価したMAE", round(mae(sales, pred_all), 2))
# 本来の評価:第8週までの平均で、第9〜12週を予測
avg8 = sum(sales[:8]) / 8
print("第8週までの平均", round(avg8, 2), "評価期間のMAE", round(mae(sales[8:], [avg8] * 4), 2))
出力は、全期間の平均 113.5、同じ期間で評価したMAE 8.17、第8週までの平均 108.38、評価期間のMAE 15.38 です。同じ期間で測ると、実際の使い方より良く見えます。
直し方:学習期間と評価期間を時間順に分け、評価期間は方法を作るときに一切使いません。
失敗2:ランダムに分けて、未来のデータを学習に使う
時系列を、普通の表のようにランダムに学習用と評価用へ分けると、評価用の週の前後のデータが学習に入ります。たとえば第9週を予測するのに第10週の値を使えてしまいます。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
# 評価用の週を第9週にして、前後の週の平均で予測する(未来の第10週を使っている)
pred_w9 = (sales[7] + sales[9]) / 2
print("第9週の実績", sales[8], "前後平均の予測", pred_w9, "誤差", abs(sales[8] - pred_w9))
# 金曜時点で使える方法:前週の値
print("前週と同じ 予測", sales[7], "誤差", abs(sales[8] - sales[7]))
出力は、前後平均の予測122.5で誤差4.5、前週と同じ予測120で誤差2です(この週では前週のほうが近いですが、未来を使う方法は運用で使えません)。運用では第10週のデータは存在しないため、未来を使った評価は実際の性能を表しません。
直し方:時系列は、学習期間を過去、評価期間を未来にして分けます。評価期間のデータは、方法を決める時点では存在しないものとして扱います。
失敗3:誤差が小さいことだけで「導入する」と決める
誤った判断:「方法NもMも誤差は数個。どちらでも十分当たっているから、複雑なAIを導入しよう。」
誤差の大きさは、事業の損失と1対1に対応しません。前の例では、方法Nは MAE 5.0 で損失5000円、方法Mは MAE 6.25 で全て不足となり損失7500円でした。上乗せを加えた方法N+5は、MAEが同じ5.0でも損失が3000円でした。
sales = [100, 104, 98, 110, 108, 115, 112, 120, 118, 125, 122, 130] # 週ごとの販売個数(第1週〜第12週)
visitors = [500, 520, 490, 550, 540, 575, 560, 600, 590, 625, 610, 650] # 週ごとの来店者数(人)
test = sales[8:]
pred_m = [sum(sales[i - 4:i]) / 4 for i in range(8, 12)]
over = sum(max(p - a, 0) for a, p in zip(test, pred_m))
under = sum(max(a - p, 0) for a, p in zip(test, pred_m))
print("方法M 過剰", over, "個 不足", under, "個")
出力は「方法M 過剰 0 個 不足 25.0 個」です。常に少なめに予測しているため、欠品が続いています。誤差の平均だけでは、この偏りは見えません。
直し方:誤差の大きさ(MAE)と、偏り(過剰・不足)と、業務の損失を別々に確認します。導入の判断は、基準との比較と、運用の費用を含めて行います。
まとめ
- 予測は、目的変数・予測時点・使える入力・評価期間を先に決める。
- 時間順に学習期間と評価期間を分け、予測する時点で手に入らない情報(漏洩)を使わない。
- 複雑な方法の前に、「前週と同じ」などの単純な基準の誤差を測る。
- 誤差の大きさ(MAE)と、偏り(過剰・不足)と、業務の損失は別に評価する。
- 運用には、実行頻度・入力確認・現場への提示・監視・失敗時の代替手順が必要。
用語
- 目的変数(target variable)
予測で当てたい値。ここでは翌週の販売個数。
- 特徴量(feature)
予測に使う入力の値。過去の販売個数や来店者数など。
- データ漏洩(リーク)(data leakage)
予測する時点では手に入らない情報が、入力や学習に混ざること。評価が見かけ上良くなる。
- 時間順分割(time-based split)
時系列データを、過去を学習期間、未来を評価期間として分ける方法。
- 移動平均(moving average)
直近k個の値の平均。ここでは直前4週の平均を予測値に使った。
よくある質問
機械学習エンジニアは、毎日モデルを作っているのですか?
多くの時間は、データの取得と整形、評価の設計、運用の仕組み、監視、関係者との調整に使われます。モデルの選択は、その一部です。ただし職場により分担は違います。
なぜ最初に単純な基準を測るのですか?
基準がないと、複雑な方法が良いのか分からないからです。「前週と同じ」でも十分当たる業務は多く、その場合は運用が簡単な基準のまま使うほうが、費用も失敗も少なくなります。
漏洩はどうすれば見つけられますか?
入力の1つずつについて「予測する時点で手に入るか」を確認します。また、誤差が不自然に小さい(MAE 0に近い)ときは、漏洩を疑います。データの記録される時点(後日まとめて入力される項目など)も確認します。
評価期間は何週間くらい必要ですか?
決まった数はありません。この授業の4週は、小さな例としては十分でも、結論を強く言うには短いです。季節性があるなら、1年以上を含めたいところです。評価期間が短いときは、結論を「この期間では」と限定します。
予測が外れたときは、誰の責任ですか?
予測の使い方を決めた業務の設計に含めます。誰が最終判断をするか、外れたときの代替手順、誤差を記録する担当を、導入前に決めます。モデルの作り手だけの責任にすると、運用が回りません。
AIを導入すること自体が目的になってしまうのはなぜ悪いのですか?
基準との比較や、費用・効果の見積もりが省かれ、使わないほうがよい案を捨てられなくなるからです。目的は、廃棄や欠品などの損失を減らすことで、手段は基準のままでもよいことがあります。
確認問題
問1 毎週金曜に翌週の販売個数を予測する。翌週の来店者数(実績)を入力に使うと、何が問題になるか。
- ① 金曜の時点では翌週の来店者数は分からず、運用で使えない(漏洩)
- ② 問題はない。来店者数は重要な情報だから
- ③ 来店者数は販売個数と無関係だから
- ④ 誤差が必ず大きくなる
解答と解説
正解:①
予測する時点で手に入らない情報を入力に使うと、評価では良く見えても運用で動かせません。
問2 時系列データの予測を評価するとき、適切な分け方はどれか。
- ① ランダムに半分ずつ分ける
- ② 評価期間の一部を学習に混ぜる
- ③ 全期間を学習にも評価にも使う
- ④ 過去を学習期間、未来を評価期間にして時間順に分ける
解答と解説
正解:④
運用では未来のデータは存在しないので、評価も過去から未来への順で行います。
問3 「前週と同じ」方法のMAEが5.0個、4週移動平均のMAEが6.25個だった。ここから言えることはどれか。
- ① 移動平均は常に悪い
- ② この評価期間では、前週と同じ方法のほうが誤差が小さい
- ③ 移動平均は導入してはいけない
- ④ 前週と同じ方法は最適である
解答と解説
正解:②
評価期間と条件の中での比較結果です。傾向が右肩上がりなので、平均が低めに出ています。
問4 予測Aと予測BはどちらもMAEが5個。Aは常に5個多め、Bは常に5個少なめ(極端な例)に外れている。欠品が高くつく場合、より問題になりやすいのはどちらか。
- ① A
- ② 同じ
- ③ B
- ④ 判断できない
解答と解説
正解:③
MAEが同じでも、偏りの向きで損失が違います。不足(欠品)が高くつくなら、少なめに偏るBが不利です。
問5 複雑な機械学習モデルを導入する前に、最初にすべきことはどれか。
- ① 最新のモデルを選ぶ
- ② 予測を使わない
- ③ データを増やす
- ④ 前週と同じなどの単純な基準の誤差を、同じ評価期間で測る
解答と解説
正解:④
基準を測らないと、モデルが改善しているかが分かりません。
問6 売り切れた日の販売個数を、そのまま「需要」として学習に使うと、どんな問題が起きるか。
- ① 実際の需要より少ない値を学習し、少なめの予測が続いて欠品が増える恐れがある
- ② 問題は起きない
- ③ 必ず多めの予測になる
- ④ データが増えるので精度が上がる
解答と解説
正解:①
売り切れた日の販売個数は、売れた数であって、欲しかった数(需要)の下限にすぎません。
次に学ぶこと
次は DXの仕事を小例で体験 で、DX(業務と組織を変える仕事)を、在庫補充の承認手順の小例で体験します。予測を作っても、承認手順が遅ければ価値は出ません。予測の評価の基礎に戻るなら 分析と予測と生成の違い を、割合の計算は 比率・割合・パーセントポイント を見直してください。
この授業の確認問題だけで習得とはしません。ON03 の総合テストと、自力課題で判定します。
キャリア学習:データサイエンティスト・機械学習エンジニア・DX推進・研究者を目指す人の学習アプリ。164モジュール・984授業を、ブラウザで動くSQLとPythonの演習で。基礎と各分野の最初のモジュールは無料。全部は2,980円の買い切り。
アプリを無料で開く有料版と無料版の違い