🔍 1. トレンドの種類と特徴
なぜトレンドの種類を理解するのか?
💡 適切なトレンドモデルを選ばないと予測が大きく外れる
例: 急成長するスタートアップの売上予測
実績: 1年目100万円 → 2年目150万円 → 3年目225万円
線形トレンドで予測した場合:
4年目 = 275万円(毎年50万円増加と仮定)
指数トレンドで予測した場合:
4年目 = 337万円(毎年50%成長と仮定)
→ 62万円の差!
→ 設備投資や採用計画に大きな影響
正しいトレンドを選ぶことで、より精度の高い予測が可能になります。
線形トレンド(直線的な成長)
📌 一定のペースで増加または減少
数式: y = a + bx(a: 切片、b: 傾き)
特徴:
・毎期、同じ量だけ増加/減少
・例: 毎月10万円ずつ増加
・グラフは直線
どんな時に使う?
・安定成長期の企業売上
・人口増加(短期的に)
・設備の減価償却
計算例:
y = 100 + 5x(切片100、傾き5)
・1ヶ月目: 100 + 5×1 = 105万円
・2ヶ月目: 100 + 5×2 = 110万円
・3ヶ月目: 100 + 5×3 = 115万円
→ 毎月5万円ずつ一定額で増加
指数トレンド(加速度的な成長)
💡 一定の割合で増加または減少
数式: y = a × b^x(a: 初期値、b: 成長率)
特徴:
・毎期、一定の割合(%)で増加/減少
・例: 毎月5%ずつ成長
・グラフは曲線(上昇または下降)
どんな時に使う?
・急成長するスタートアップ
・ウイルス感染者数
・複利計算
計算例:
y = 100 × 1.05^x(初期値100、月次5%成長)
・1ヶ月目: 100 × 1.05 = 105.0万円
・2ヶ月目: 100 × 1.05² = 110.3万円
・12ヶ月目: 100 × 1.05¹² = 179.6万円
→ 増加額が徐々に大きくなる(複利効果)
S字カーブ(ロジスティック成長)
📌 初期は緩やか、中期は急成長、後期は飽和
3つのフェーズ:
1. 導入期: 認知度低い、成長は緩やか
2. 成長期: 口コミ効果、急激な成長
3. 成熟期: 市場飽和、成長鈍化
実例:
・スマートフォンの普及率
・SNSユーザー数
・電気自動車の販売台数
3種類のトレンド比較(視覚的理解)
# ============================================
# 3種類のトレンドパターンの比較と可視化
# ============================================
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
# サンプルデータ作成(3年分)
np.random.seed(42)
months = np.arange(1, 37)
# 1. 線形トレンド: y = 100 + 5x
linear_trend = 100 + 5 * months + np.random.normal(0, 5, len(months))
# 2. 指数トレンド: y = 100 × 1.05^x
exponential_trend = 100 * (1.05 ** months) + np.random.normal(0, 10, len(months))
# 3. S字カーブ(ロジスティック)
logistic_trend = 500 / (1 + np.exp(-0.2 * (months – 18))) + np.random.normal(0, 10, len(months))
# トレンドラインのフィッティング
X = months.reshape(-1, 1)
# 線形トレンドのフィット
model_linear = LinearRegression()
model_linear.fit(X, linear_trend)
y_pred_linear = model_linear.predict(X)
r2_linear = r2_score(linear_trend, y_pred_linear)
# 指数トレンドのフィット(対数変換)
y_log = np.log(exponential_trend)
model_exp = LinearRegression()
model_exp.fit(X, y_log)
y_pred_exp = np.exp(model_exp.predict(X))
growth_rate = (np.exp(model_exp.coef_[0]) – 1) * 100
r2_exp = r2_score(exponential_trend, y_pred_exp)
print(“【トレンドの特徴】”)
print(f”線形: y = {model_linear.intercept_:.1f} + {model_linear.coef_[0]:.2f}x (R²={r2_linear:.3f})”)
print(f”指数: 月次成長率 {growth_rate:.2f}% (R²={r2_exp:.3f})”)
# ============================================
# 3種類のトレンドの可視化
# ============================================
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# 線形トレンド
axes[0].scatter(months, linear_trend, alpha=0.6, label=’実績’)
axes[0].plot(months, y_pred_linear, ‘r-‘, linewidth=2, label=’線形トレンド’)
axes[0].set_title(f’線形トレンド\ny = {model_linear.intercept_:.0f} + {model_linear.coef_[0]:.1f}x\nR² = {r2_linear:.3f}’)
axes[0].set_xlabel(‘月’)
axes[0].set_ylabel(‘売上(万円)’)
axes[0].legend()
axes[0].grid(True, alpha=0.3)
# 指数トレンド
axes[1].scatter(months, exponential_trend, alpha=0.6, label=’実績’)
axes[1].plot(months, y_pred_exp, ‘r-‘, linewidth=2, label=’指数トレンド’)
axes[1].set_title(f’指数トレンド\n月次成長率: {growth_rate:.1f}%\nR² = {r2_exp:.3f}’)
axes[1].set_xlabel(‘月’)
axes[1].set_ylabel(‘売上(万円)’)
axes[1].legend()
axes[1].grid(True, alpha=0.3)
# S字カーブ
axes[2].scatter(months, logistic_trend, alpha=0.6, label=’実績’)
axes[2].axhline(y=500, color=’gray’, linestyle=’–‘, label=’上限(500)’)
axes[2].set_title(‘S字カーブ(ロジスティック)\n初期→急成長→飽和’)
axes[2].set_xlabel(‘月’)
axes[2].set_ylabel(‘ユーザー数’)
axes[2].legend()
axes[2].grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig(‘trend_comparison.png’, dpi=150, bbox_inches=’tight’)
plt.show()
print(“\n→ グラフを ‘trend_comparison.png’ に保存しました”)
トレンド判断の早見表
📌 データの特徴からトレンドを見分ける
| 確認項目 |
線形 |
指数 |
S字 |
| 増加幅 |
一定 (毎月+10万円) |
拡大 (+10→+15→+22) |
山型 (小→大→小) |
| 増加率 |
低下 (10%→8%→6%) |
一定 (毎月+5%) |
山型 (低→高→低) |
| 上限の有無 |
なし |
なし |
あり |
| グラフの形状 |
直線 |
上向き曲線 |
S字 |
| 典型例 |
安定企業の売上 |
スタートアップ |
新製品の普及 |
🎯 2. どのトレンドを選ぶべきか?
トレンド選択の判断基準
⚠️ 正しいトレンドを選ぶための3つのステップ
ステップ1: データの特徴を確認
・増加幅: 一定(線形)、拡大(指数)、変動(S字)
・増加率: 低下(線形)、一定(指数)、山型(S字)
・上限: なし(線形・指数)、あり(S字)
ステップ2: R²(決定係数)で比較
・R² > 0.9: 非常に良いフィット
・R² > 0.7: 良いフィット
→ 複数のトレンドを試して、R²が最も高いものを選択
ステップ3: ビジネス知識で検証
・市場に上限はあるか?(あればS字)
・成長は加速しているか?(していれば指数)
・安定成長か?(していれば線形)
トレンド選択の実装
# ============================================
# トレンド選択: どのモデルが最適か判断する
# ============================================
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.preprocessing import PolynomialFeatures
# 実際の売上データ(例)
months = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
sales = np.array([100, 108, 118, 127, 139, 152, 166, 180, 197, 214, 233, 254])
X = months.reshape(-1, 1)
# 増加幅と増加率を確認
increases = np.diff(sales)
print(f”増加額の傾向: {increases[0]:.0f} → {increases[-1]:.0f}万円”)
if increases[-1] > increases[0] * 1.2:
print(” → 増加額が拡大 → 指数トレンドの可能性”)
# 3種類のトレンドをフィット
# 線形トレンド
model_linear = LinearRegression()
model_linear.fit(X, sales)
r2_linear = r2_score(sales, model_linear.predict(X))
# 指数トレンド(対数変換)
model_exp = LinearRegression()
model_exp.fit(X, np.log(sales))
r2_exp = r2_score(sales, np.exp(model_exp.predict(X)))
# 2次多項式
poly = PolynomialFeatures(degree=2)
model_poly = LinearRegression()
model_poly.fit(poly.fit_transform(X), sales)
r2_poly = r2_score(sales, model_poly.predict(poly.transform(X)))
print(f”\n【R²の比較】”)
print(f”線形: R² = {r2_linear:.4f}”)
print(f”指数: R² = {r2_exp:.4f}”)
print(f”多項式: R² = {r2_poly:.4f}”)
# 最適モデルの判定
results = {‘線形’: r2_linear, ‘指数’: r2_exp, ‘多項式’: r2_poly}
best = max(results, key=results.get)
print(f”\n【結論】最適: {best}トレンド (R²={results[best]:.4f})”)
# ============================================
# 将来予測の実行
# ============================================
future_months = np.array([13, 14, 15]) # 来期3ヶ月
future_X = future_months.reshape(-1, 1)
# 指数トレンドで予測(この例では指数が最適)
future_pred = np.exp(model_exp.predict(future_X))
print(f”\n【来期の売上予測(指数トレンド)】”)
for m, pred in zip(future_months, future_pred):
print(f”{m}ヶ月目: {pred:.0f}万円”)
# ============================================
# トレンド比較の可視化
# ============================================
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
# 実績データ
ax.scatter(months, sales, s=100, color=’blue’, label=’実績’, zorder=5)
# 各トレンドライン
x_line = np.linspace(1, 15, 100).reshape(-1, 1)
ax.plot(x_line, model_linear.predict(x_line), ‘–‘,
label=f’線形 (R²={r2_linear:.3f})’, alpha=0.7)
ax.plot(x_line, np.exp(model_exp.predict(x_line)), ‘-‘,
label=f’指数 (R²={r2_exp:.3f})’, linewidth=2)
ax.plot(x_line, model_poly.predict(poly.transform(x_line)), ‘:’,
label=f’多項式 (R²={r2_poly:.3f})’, alpha=0.7)
# 将来予測点
ax.scatter(future_months, future_pred, s=100, color=’red’,
marker=’*’, label=’予測’, zorder=5)
ax.axvline(x=12.5, color=’gray’, linestyle=’–‘, alpha=0.5)
ax.text(12.7, ax.get_ylim()[0] + 20, ‘← 実績 | 予測 →’, fontsize=10)
ax.set_xlabel(‘月’, fontsize=12)
ax.set_ylabel(‘売上(万円)’, fontsize=12)
ax.set_title(‘トレンド比較と将来予測’, fontsize=14)
ax.legend(loc=’upper left’)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig(‘trend_selection.png’, dpi=150, bbox_inches=’tight’)
plt.show()
print(“\n→ グラフを ‘trend_selection.png’ に保存しました”)
Excelでのトレンド分析
💡 Excelでトレンドラインを追加する方法
手順:
1. データを選択 → 挿入 → 散布図
2. グラフのデータ点を右クリック → 「近似曲線の追加」
3. トレンドの種類を選択(線形/指数/多項式)
4. 「グラフに数式を表示する」「R-2乗値を表示する」にチェック
Excel数式:
・R²: =RSQ(実績範囲, 予測範囲)
・傾き: =SLOPE(Y範囲, X範囲)
・切片: =INTERCEPT(Y範囲, X範囲)
・指数成長率: =LOGEST(Y範囲, X範囲)
📊 3. 予測精度の評価指標
3つの主要な評価指標
💡 MAE(平均絶対誤差)
計算式: MAE = Σ|実績 – 予測| ÷ n
意味: 予測が平均してどれくらいズレているか(金額)
特徴: 単位が元データと同じ、解釈しやすい
計算例:
実績: 100, 110, 120 / 予測: 105, 108, 118
MAE = (5 + 2 + 2) ÷ 3 = 3.0万円
💡 RMSE(二乗平均平方根誤差)
計算式: RMSE = √(Σ(実績 – 予測)² ÷ n)
意味: 大きな誤差を重視した評価(金額)
特徴: 外れ値に敏感、MAEより常に大きい
計算例:
二乗誤差: 25, 4, 4
RMSE = √(33 ÷ 3) = 3.3万円
💡 MAPE(平均絶対パーセント誤差)
計算式: MAPE = Σ(|実績 – 予測| ÷ 実績) ÷ n × 100%
意味: 予測が平均して何%ズレているか
特徴: スケールに依存しない、経営報告に最適
計算例:
%誤差: 5%, 1.8%, 1.7%
MAPE = (5 + 1.8 + 1.7) ÷ 3 = 2.8%
評価指標の使い分け
📌 目的と相手に応じて選択
| 指標 |
報告先 |
メリット |
| MAE |
現場担当者 |
金額で分かりやすい |
| RMSE |
データ分析者 |
外れ値を重視 |
| MAPE |
経営層 |
%で直感的 |
精度評価の完全実装
# ============================================
# 予測精度の完全評価
# ============================================
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# データの準備
actual = np.array([100, 110, 105, 115, 120, 125, 118, 130, 135, 140])
forecast = np.array([102, 108, 107, 113, 122, 123, 120, 128, 137, 138])
# 評価指標の計算
def calculate_metrics(actual, forecast):
errors = forecast – actual
abs_errors = np.abs(errors)
pct_errors = abs_errors / actual * 100
mae = np.mean(abs_errors)
rmse = np.sqrt(np.mean(errors ** 2))
mape = np.mean(pct_errors)
bias = np.mean(errors)
return {‘MAE’: mae, ‘RMSE’: rmse, ‘MAPE’: mape, ‘Bias’: bias}
metrics = calculate_metrics(actual, forecast)
print(“【評価指標】”)
print(f”MAE: {metrics[‘MAE’]:.2f}万円”)
print(f”RMSE: {metrics[‘RMSE’]:.2f}万円”)
print(f”MAPE: {metrics[‘MAPE’]:.2f}%”)
# 精度の評価基準
if metrics[‘MAPE’] < 5:
print("\n【評価】非常に良い")
elif metrics['MAPE'] < 10:
print("\n【評価】良好")
elif metrics['MAPE'] < 20:
print("\n【評価】普通")
else:
print("\n【評価】要改善")
# バイアス分析
print(f"\n【バイアス】{metrics['Bias']:+.2f}万円")
if abs(metrics['Bias']) < 1:
print("→ バイアスなし(良好)")
elif metrics['Bias'] > 0:
print(“→ 過大予測の傾向あり”)
else:
print(“→ 過小予測の傾向あり”)
# ============================================
# 精度評価の可視化(4つのグラフ)
# ============================================
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
months = np.arange(1, len(actual) + 1)
errors = forecast – actual
# 1. 実績 vs 予測の推移
ax1 = axes[0, 0]
ax1.plot(months, actual, ‘o-‘, label=’実績’, linewidth=2, markersize=8)
ax1.plot(months, forecast, ‘s–‘, label=’予測’, linewidth=2, markersize=8)
ax1.fill_between(months, actual, forecast, alpha=0.3, color=’orange’)
ax1.set_xlabel(‘月’)
ax1.set_ylabel(‘売上(万円)’)
ax1.set_title(‘① 実績 vs 予測の推移’)
ax1.legend()
ax1.grid(True, alpha=0.3)
# 2. 誤差の棒グラフ
ax2 = axes[0, 1]
colors = [‘#e74c3c’ if e > 0 else ‘#3498db’ for e in errors]
ax2.bar(months, errors, color=colors, alpha=0.7, edgecolor=’black’)
ax2.axhline(y=0, color=’black’, linewidth=1)
ax2.axhline(y=metrics[‘Bias’], color=’red’, linestyle=’–‘,
label=f’バイアス: {metrics[“Bias”]:+.1f}’)
ax2.set_xlabel(‘月’)
ax2.set_ylabel(‘誤差(万円)’)
ax2.set_title(‘② 月別誤差(赤=過大、青=過小)’)
ax2.legend()
ax2.grid(True, alpha=0.3, axis=’y’)
# 3. 散布図(45度線付き)
ax3 = axes[1, 0]
ax3.scatter(actual, forecast, s=100, alpha=0.7, edgecolors=’black’)
min_val = min(min(actual), min(forecast)) – 5
max_val = max(max(actual), max(forecast)) + 5
ax3.plot([min_val, max_val], [min_val, max_val], ‘r–‘,
linewidth=2, label=’完全一致線’)
ax3.set_xlabel(‘実績(万円)’)
ax3.set_ylabel(‘予測(万円)’)
ax3.set_title(‘③ 実績 vs 予測 散布図’)
ax3.legend()
ax3.grid(True, alpha=0.3)
ax3.set_xlim(min_val, max_val)
ax3.set_ylim(min_val, max_val)
# 4. 誤差分布のヒストグラム
ax4 = axes[1, 1]
ax4.hist(errors, bins=7, color=’steelblue’, alpha=0.7, edgecolor=’black’)
ax4.axvline(x=0, color=’red’, linestyle=’–‘, linewidth=2, label=’誤差0’)
ax4.axvline(x=metrics[‘Bias’], color=’orange’, linestyle=’-‘,
linewidth=2, label=f’バイアス: {metrics[“Bias”]:+.1f}’)
ax4.set_xlabel(‘誤差(万円)’)
ax4.set_ylabel(‘頻度’)
ax4.set_title(‘④ 誤差の分布’)
ax4.legend()
ax4.grid(True, alpha=0.3, axis=’y’)
plt.tight_layout()
plt.savefig(‘accuracy_evaluation.png’, dpi=150, bbox_inches=’tight’)
plt.show()
print(“\n→ グラフを ‘accuracy_evaluation.png’ に保存しました”)
ホールドアウト検証(テストデータでの評価)
⚠️ 学習データとテストデータを分ける重要性
問題: 学習に使ったデータで精度を測ると、過度に良い結果が出る
解決策: データを分割して「未知のデータ」でテスト
推奨分割:
・学習データ: 70-80%(例: 1-30ヶ月目)
・テストデータ: 20-30%(例: 31-36ヶ月目)
# ============================================
# ホールドアウト検証の実装
# ============================================
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error
# 36ヶ月分のデータ
np.random.seed(42)
months_all = np.arange(1, 37)
sales_all = 100 + 8 * months_all + np.random.normal(0, 10, 36)
# データ分割(80%学習、20%テスト)
split_point = 30 # 30ヶ月目で分割
# 学習データ
X_train = months_all[:split_point].reshape(-1, 1)
y_train = sales_all[:split_point]
# テストデータ
X_test = months_all[split_point:].reshape(-1, 1)
y_test = sales_all[split_point:]
print(f”学習データ: {len(y_train)}件(1-{split_point}ヶ月目)”)
print(f”テストデータ: {len(y_test)}件({split_point+1}-36ヶ月目)”)
# モデル学習(学習データのみ使用)
model = LinearRegression()
model.fit(X_train, y_train)
# 学習データでの精度
y_pred_train = model.predict(X_train)
mae_train = mean_absolute_error(y_train, y_pred_train)
# テストデータでの精度(重要!)
y_pred_test = model.predict(X_test)
mae_test = mean_absolute_error(y_test, y_pred_test)
print(f”\n【精度比較】”)
print(f”学習データ MAE: {mae_train:.2f}万円”)
print(f”テストデータ MAE: {mae_test:.2f}万円”)
# 過学習チェック
if mae_test > mae_train * 1.5:
print(“\n⚠️ 警告: 過学習の可能性あり”)
print(” → モデルを単純化するか、データを増やす”)
else:
print(“\n✓ 過学習なし(テスト精度が妥当)”)
# 可視化
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 6))
# 学習データ
ax.scatter(X_train, y_train, color=’blue’, s=60, label=’学習データ’, alpha=0.7)
# テストデータ
ax.scatter(X_test, y_test, color=’green’, s=80, marker=’s’, label=’テストデータ(実績)’, alpha=0.7)
# テスト予測
ax.scatter(X_test, y_pred_test, color=’red’, s=80, marker=’^’, label=’テストデータ(予測)’, alpha=0.7)
# トレンドライン
x_line = np.linspace(1, 36, 100).reshape(-1, 1)
ax.plot(x_line, model.predict(x_line), ‘r-‘, linewidth=2, label=’トレンドライン’)
# 分割線
ax.axvline(x=split_point + 0.5, color=’gray’, linestyle=’–‘, linewidth=2)
ax.text(split_point – 5, ax.get_ylim()[1] – 20, ‘学習期間’, fontsize=11)
ax.text(split_point + 1, ax.get_ylim()[1] – 20, ‘テスト期間’, fontsize=11)
ax.set_xlabel(‘月’, fontsize=12)
ax.set_ylabel(‘売上(万円)’, fontsize=12)
ax.set_title(f’ホールドアウト検証\n学習MAE: {mae_train:.1f}万円 / テストMAE: {mae_test:.1f}万円’, fontsize=14)
ax.legend(loc=’upper left’)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig(‘holdout_validation.png’, dpi=150, bbox_inches=’tight’)
plt.show()
print(“\n→ グラフを ‘holdout_validation.png’ に保存しました”)
Excelでの精度計算
💡 Excelで評価指標を計算する数式
データ配置: B列=実績、C列=予測
| 指標 |
Excel数式 |
| MAE |
=AVERAGE(ABS(B2:B11-C2:C11)) |
| RMSE |
=SQRT(AVERAGE((B2:B11-C2:C11)^2)) |
| MAPE |
=AVERAGE(ABS(B2:B11-C2:C11)/B2:B11)*100 |
| バイアス |
=AVERAGE(C2:C11-B2:B11) |
※Excel 365以前は配列数式(Ctrl+Shift+Enter)が必要
実務での精度目標
⚠️ 業界・用途別のMAPE目標
| 精度 |
MAPE |
用途例 |
| 非常に高精度 |
< 5% |
電力需要、金融 |
| 高精度 |
5-10% |
売上予測、在庫管理 |
| 中精度 |
10-20% |
新商品、中期計画 |
| 低精度 |
> 20% |
長期予測、新規事業 |
🔄 4. トレンド転換の検出
トレンド転換の兆候
💡 5つの早期警戒サイン
| サイン |
具体例 |
| 1. 成長率の変化 |
前年比+20%→+5% |
| 2. 移動平均の傾き |
上昇→横ばい |
| 3. 予測誤差の拡大 |
MAPE 5%→15% |
| 4. バイアスの発生 |
常に過大予測に |
| 5. 外部環境の変化 |
競合参入、規制変更 |
トレンド転換の検出実装
# ============================================
# トレンド転換の検出
# ============================================
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# トレンド転換があるデータ生成
np.random.seed(42)
months = np.arange(1, 37)
trend_change_point = 18 # 18ヶ月目で転換
# 前半:上昇、後半:下降
trend1 = 100 + 5 * months[:trend_change_point] + np.random.normal(0, 3, trend_change_point)
trend2 = trend1[-1] – 3 * np.arange(1, len(months) – trend_change_point + 1) + np.random.normal(0, 3, len(months) – trend_change_point)
sales = np.concatenate([trend1, trend2])
df = pd.DataFrame({‘month’: months, ‘sales’: sales})
df[‘MA_6’] = df[‘sales’].rolling(window=6).mean()
df[‘MA_change’] = df[‘MA_6’].diff()
# トレンド転換点の検出
def detect_trend_change(data, window=6):
ma = data.rolling(window=window).mean()
ma_change = ma.diff()
signs = np.sign(ma_change.dropna())
changes = []
for i in range(1, len(signs)):
if signs.iloc[i] != signs.iloc[i-1] and signs.iloc[i] != 0:
changes.append(signs.index[i])
return changes
change_points = detect_trend_change(df[‘sales’])
print(“【検出された転換点】”)
for cp in change_points:
print(f” {cp}ヶ月目”)
print(“\n【対応策】”)
print(“1. 転換点以降のデータで再学習”)
print(“2. 複数シナリオを準備”)
print(“3. モニタリング強化”)
⚠️ 5. 実務でよくある間違い
間違い①: 精度指標を1つしか見ない
❌ 問題: 「MAPEが8%なので良好です」
何が問題か?
・バイアスが隠れている可能性
・外れ値の影響が見えない
✅ 正しいアプローチ:
・MAE、RMSE、MAPEの3つを確認
・バイアスを確認
・誤差の分布を可視化
間違い②: 過去データだけで評価する
❌ 問題: 「全データで学習し、同じデータで評価したらMAPE=3%!」
何が問題か?
・過学習の可能性
・未知データに対する精度が不明
✅ 正しいアプローチ:
・データを学習用とテスト用に分割
・例: 1-30ヶ月目で学習、31-36ヶ月目でテスト
間違い③: 精度目標を決めずに進める
❌ 問題: 「とりあえずモデルを作って、精度を見てから考えよう」
✅ 正しいアプローチ:
・事前に目標を設定: 「MAPEを10%以下に」
・業界標準を参考にする
・費用対効果を考慮
間違い④: 外れ値を無視する
❌ 問題: 「12月は特需で2倍だけど、そのままモデルに入れよう」
✅ 正しいアプローチ:
1. 外れ値を検出(平均±3σの範囲外)
2. 原因を特定(特需?入力ミス?)
3. 適切に処理(除外or補正)
間違い⑤: モデルを更新しない
❌ 問題: 「去年作ったモデルをそのまま今年も使おう」
✅ 正しいアプローチ:
・月次: 精度モニタリング
・四半期: パラメータ調整
・年次: モデル全体の見直し
✅ 6. 精度評価チェックリスト
💡 予測精度を評価する前に確認!
【データの確認】
□ 十分なデータ量があるか(最低24ヶ月推奨)
□ 外れ値は処理したか
□ 欠損値は適切に補完したか
□ 季節調整は必要か(→STEP 35参照)
【トレンドの選択】
□ 複数のトレンドを試したか
□ R²で比較したか
□ ビジネス知識と整合性があるか
【精度評価】
□ 学習データとテストデータを分けたか
□ MAE、RMSE、MAPEの3つを確認したか
□ バイアスを確認したか
【運用準備】
□ 精度目標を設定したか
□ 更新スケジュールを決めたか
□ 複数シナリオを準備したか
📝 STEP 36 のまとめ
✅ このステップで学んだこと
- 3種類のトレンド: 線形(一定額)、指数(一定率)、S字(飽和あり)
- トレンドの選択: R²で比較、ビジネス知識で検証
- 評価指標: MAE(金額)、RMSE(外れ値重視)、MAPE(%)
- バイアス分析: 過大/過小予測の傾向を確認
- トレンド転換: 移動平均の変化率で早期検出
- よくある間違い: 単一指標、過学習、更新忘れなど
💡 実務での重要ポイント
予測精度評価の鉄則!
1. 複数の指標で総合判断
・MAPE: 経営報告向け
・MAE: 実務判断向け
・バイアス: 傾向の確認
2. テストデータで評価
・学習データと分離する
・時系列は時間順に分割
3. 継続的にモニタリング
・精度の低下を早期検出
・トレンド転換に注意
完璧な予測は不可能!
でも、精度を正しく評価し、
継続的に改善することで
意思決定の質は確実に向上します!
📌 次のステップへのつながり
このSTEPで学んだ精度評価の手法は、
STEP 37(ABC分析・パレート分析)でも活用します。
また、STEP 34(高度な予測手法)で学んだ
ARIMA、Prophet、指数平滑法などのモデルを
比較する際にも、このSTEPの知識が必要です。
📝 練習問題
問題 1
基礎
以下の予測結果について、MAE、RMSE、MAPEを計算してください。
実績: 100, 110, 120, 130, 140 (万円)
予測: 105, 108, 125, 128, 145 (万円)
【解答】MAE = 3.8万円、RMSE = 4.1万円、MAPE = 3.2%
計算手順:
誤差: +5, -2, +5, -2, +5
絶対誤差: 5, 2, 5, 2, 5
二乗誤差: 25, 4, 25, 4, 25
%誤差: 5.0%, 1.8%, 4.2%, 1.5%, 3.6%
MAE = (5+2+5+2+5) ÷ 5 = 3.8万円
RMSE = √(83÷5) = 4.1万円
MAPE = (5.0+1.8+4.2+1.5+3.6) ÷ 5 = 3.2%
評価: MAPE 3.2% → 非常に良い精度!
問題 2
応用
ある商品の売上が以下のように推移しています。
線形トレンドと指数トレンドのどちらが適切か判断してください。
1ヶ月目: 100万円
6ヶ月目: 130万円
12ヶ月目: 170万円
18ヶ月目: 220万円
24ヶ月目: 285万円
【解答】指数トレンド
判断の根拠:
増加幅の確認:
1-6ヶ月: +30万円
6-12ヶ月: +40万円
12-18ヶ月: +50万円
18-24ヶ月: +65万円
→ 増加幅が拡大している
増加率の確認:
各期間: 約30%, 31%, 29%, 30%
→ 増加率がほぼ一定
→ 指数トレンドの特徴に合致!
予測への影響:
30ヶ月目予測:
・線形: 約331万円
・指数: 約374万円
→ 43万円の差!
問題 3
応用
2つの予測モデルの結果があります。
どちらを採用すべきか判断し、理由を説明してください。
モデルA: MAE = 8万円、MAPE = 6%、バイアス = +7万円
モデルB: MAE = 10万円、MAPE = 8%、バイアス = -1万円
【解答】モデルBを採用すべき
判断の根拠:
一見するとモデルAが良さそう:
・MAE: A(8) < B(10)
・MAPE: A(6%) < B(8%)
しかしバイアスを見ると:
・モデルA: +7万円(常に過大予測)
・モデルB: -1万円(ほぼバイアスなし)
モデルAの問題点:
・バイアス+7万円 = MAE 8万円の87.5%
・誤差のほとんどが系統的な過大予測
・モデルに構造的な問題がある
結論:
バイアスがないモデルBの方が信頼性が高い!
問題 4
発展
月次売上予測の精度改善プロジェクトを任されました。
現状: MAPE = 18%
目標: MAPE = 10%
データ: 過去24ヶ月の売上実績
精度改善のためのアクションプランを3つ提案してください。
【解答例】精度改善アクションプラン
アクション1: データ品質の向上
・外れ値の検出と処理
・季節調整の実施(STEP 35参照)
・データ期間の延長(可能なら36ヶ月以上)
期待効果: MAPE 2-3%改善
アクション2: 特徴量の追加
・休日フラグ(祝日、大型連休)
・プロモーション情報
・天候データ
期待効果: MAPE 3-5%改善
アクション3: モデルの高度化
・ARIMA、Prophet等を試行(STEP 34参照)
・複数モデルのアンサンブル
期待効果: MAPE 2-4%改善
プロジェクト計画:
1. データ品質向上(2週間)→ MAPE 15%
2. 特徴量追加(3週間)→ MAPE 12%
3. モデル高度化(3週間)→ MAPE 10%
❓ よくある質問
Q1: MAE、RMSE、MAPE、どれを使えばいいですか?
目的と相手に応じて使い分けます。
・経営層への報告 → MAPE(%で分かりやすい)
・現場での実務 → MAE(金額で具体的)
・モデル比較 → RMSE(外れ値を重視)
推奨: 基本はMAPEをメインに、MAEも併記
Q2: R²(決定係数)とMAPEの違いは何ですか?
目的が異なります。
・R²: トレンドの当てはまりの良さ(0〜1)
→ トレンド選択時に使用
・MAPE: 予測の精度(%)
→ 予測評価時に使用
両方確認するのがベスト!
Q3: 予測精度が目標に達しない場合、どうすればいいですか?
段階的にアプローチします。
1. 現状分析(どの月の誤差が大きいか)
2. データ改善(外れ値処理、データ量増加)
3. モデル改善(トレンド変更、特徴量追加)
4. 目標の見直し(費用対効果を考慮)
MAPE 20%→10%は努力で可能、10%→5%は極めて困難
Q4: トレンド転換をどう見極めますか?
複数の兆候から総合的に判断します。
数値的な兆候:
・移動平均の傾きが変化
・成長率の急変
・予測誤差の拡大
定性的な兆候:
・競合の動き
・市場環境の変化
対応策: 予測期間を短縮、モデル更新、複数シナリオ準備
artnasekai
#artnasekai #学習メモ