100本ノック / マーケティングサイエンス / マーケティングサイエンス100本ノック
製造業の意思決定をデータとAIで変える|マーケティングサイエンス実践10本ノック
営業・生産・経営をつなぐ意思決定基盤:製造業マーケティングサイエンス実践10本ノック
本記事では、産業機器メーカーの架空データを用い、観測から経営判断、実行、学習までを一つの仕組みにする方法を扱います。対象は No.091〜No.100(意思決定科学、OODA、シナリオ分析、KPI設計、経営ダッシュボード、AIと意思決定、製造業DI、Palantirから学ぶこと、数理工房のビジョン、AI時代のマーケティングサイエンス)です。
分析精度だけでなく、「誰が、いつ、何を決めるか」「どの条件なら判断を変えるか」まで具体化します。
[!NOTE] 本資料は、数理工房 (もしくは代表である和山個人) が過去に企業研修において使用した notebook を企業様の許可を得て再構成・編集のうえ公開しています。 掲載データはすべて架空のものであり、実在する企業・工場・数値とは一切関係ありません。
はじめに:この記事で扱う製造業の実務課題
架空の「光栄インダストリアル」は、標準機・高効率機・特注機を販売する産業機器メーカーです。引き合いは増えていますが、営業は受注、工場は稼働率、経営は利益を重視し、会議ごとに異なる数字が提示されます。本記事の問いは、限られた生産能力と営業資源を、どの案件・市場へ振り向けるべきかです。
現場でよくある状況
- 売上目標を追うほど、低採算の特急案件が増えて残業と納期遅延が悪化する
- CRM、見積、受注、生産、品質のデータが分断され、同じ顧客を一貫して見られない
- 予測値だけが提示され、前提・不確実性・撤退条件が共有されない
- AIの提案が、責任者や承認条件のないまま「参考情報」で終わる
なぜこの問題は判断が難しいのか
売上、粗利、納期、品質は相互に影響し、施策の効果が現れる時期も異なります。さらに、受注確率や材料費は確定値ではありません。したがって、単一KPIの最大化ではなく、目的・制約・不確実性を明示した意思決定が必要です。
今回扱うノックの全体像
| No. | テーマ | 経営会議で答える問い |
|---|---|---|
| 091 | 意思決定科学とは | 期待利益とリスクをどう比較するか |
| 092 | OODA | どの兆候を見て、いつ方針を変えるか |
| 093 | シナリオ分析 | 悲観・基準・楽観で計画は耐えられるか |
| 094 | KPI設計 | 結果指標を動かす先行指標は何か |
| 095 | 経営ダッシュボード | 例外をどの順で確認するか |
| 096 | AIと意思決定 | AI提案をどの条件で採用するか |
| 097 | 製造業DI | 現場の変化を合成指標で早期検知できるか |
| 098 | Palantirから学ぶこと | データを業務オブジェクトと判断へどう結ぶか |
| 099 | 数理工房のビジョン | PoCから運用定着までどう設計するか |
| 100 | AI時代のマーケティングサイエンス | 人とAIの学習ループをどう構築するか |
Python環境の準備
外部データには依存せず、numpy、pandas、matplotlib だけを使います。乱数シードを固定し、同じ結果を再現できるようにします。グラフ内のラベルは実行環境の日本語フォント差を避けるため英語表記とします。
import sys
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from IPython.display import display
SEED = 42
rng = np.random.default_rng(SEED)
pd.set_option("display.max_columns", 20)
pd.set_option("display.float_format", lambda x: f"{x:,.2f}")
plt.rcParams["figure.figsize"] = (8, 4.5)
plt.rcParams["axes.unicode_minus"] = False
print("Python :", sys.version.split()[0])
print("numpy :", np.__version__)
print("pandas :", pd.__version__)
print("matplotlib :", matplotlib.__version__)
print("random seed:", SEED)
Python : 3.13.1
numpy : 2.5.1
pandas : 3.0.3
matplotlib : 3.11.0
random seed: 42
架空データの作成
24か月、3製品、3地域の案件・受注・操業データを生成します。金額単位は百万円です。orders は案件数と受注率から生成し、売上・粗利・納期遵守率・不良率を連動させています。この因果構造は説明用の仮定であり、実務では業務知識と検証によって更新します。
months = pd.date_range("2024-01-01", periods=24, freq="MS")
products = ["Standard", "Eco", "Custom"]
regions = ["East", "Central", "West"]
rows = []
for t, month in enumerate(months):
season = 1 + 0.12 * np.sin(2 * np.pi * t / 12)
for p in products:
for r in regions:
p_mult = {"Standard": 1.0, "Eco": 0.8, "Custom": 0.55}[p]
r_mult = {"East": 1.15, "Central": 1.0, "West": 0.85}[r]
leads = max(8, int(rng.poisson(28 * season * p_mult * r_mult * (1 + 0.012*t))))
quote_days = max(3, rng.normal({"Standard": 7, "Eco": 9, "Custom": 15}[p], 1.8))
discount = np.clip(rng.normal(0.075 if p != "Custom" else 0.045, 0.018), 0.02, 0.14)
win_prob = np.clip(0.38 + 0.08*(p == "Eco") - 0.010*quote_days - 0.65*discount + 0.12, 0.12, 0.65)
orders = rng.binomial(leads, win_prob)
unit_price = {"Standard": 4.8, "Eco": 6.7, "Custom": 10.5}[p]
revenue = orders * unit_price * (1-discount)
utilization = np.clip(rng.normal(0.78 + 0.006*t + 0.05*(p == "Custom"), 0.045), 0.60, 0.98)
defect_rate = np.clip(0.012 + 0.055*max(utilization-0.82, 0) + rng.normal(0, .002), .004, .04)
on_time = np.clip(0.98 - 0.55*max(utilization-0.80, 0) - 1.8*defect_rate + rng.normal(0,.01), .78, .99)
margin_rate = 0.34 - discount - 0.10*(p == "Custom") - 0.35*defect_rate
rows.append([month,p,r,leads,quote_days,discount,win_prob,orders,revenue,margin_rate,
revenue*margin_rate,utilization,defect_rate,on_time])
df = pd.DataFrame(rows, columns=["month","product","region","leads","quote_days","discount",
"win_prob","orders","revenue","margin_rate","gross_profit","utilization","defect_rate","on_time"])
display(df.head())
print(f"rows={len(df):,}, period={df.month.min():%Y-%m} to {df.month.max():%Y-%m}")
| month | product | region | leads | quote_days | discount | win_prob | orders | revenue | margin_rate | gross_profit | utilization | defect_rate | on_time | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2024-01-01 | Standard | East | 37 | 8.35 | 0.09 | 0.36 | 9 | 39.23 | 0.24 | 9.56 | 0.72 | 0.01 | 0.95 |
| 1 | 2024-01-01 | Standard | Central | 21 | 8.58 | 0.09 | 0.36 | 8 | 34.98 | 0.25 | 8.61 | 0.83 | 0.01 | 0.93 |
| 2 | 2024-01-01 | Standard | West | 25 | 8.58 | 0.07 | 0.37 | 11 | 48.89 | 0.26 | 12.75 | 0.75 | 0.01 | 0.95 |
| 3 | 2024-01-01 | Eco | East | 30 | 9.96 | 0.08 | 0.43 | 10 | 61.53 | 0.25 | 15.55 | 0.80 | 0.02 | 0.95 |
| 4 | 2024-01-01 | Eco | Central | 20 | 10.11 | 0.10 | 0.42 | 6 | 36.37 | 0.24 | 8.77 | 0.74 | 0.01 | 0.97 |
rows=216, period=2024-01 to 2025-12
No.091:意思決定科学とは
実務での意味
意思決定科学は「予測を当てる技術」だけではありません。選択肢、起こり得る状態、結果の価値、制約を整理し、どの選択肢を採るかまで扱います。ここでは次四半期の営業・生産方針を比較します。
分析・モデル化の考え方
施策 、需要状態 、利益 、状態確率 とすると、期待利益は
です。ただし平均だけでは下振れを見落とすため、標準偏差と最悪値も併記します。確率は真実ではなく、現時点の仮定です。
Pythonで確認する
states = pd.DataFrame({"scenario":["Low","Base","High"], "probability":[0.25,0.50,0.25]})
payoff = pd.DataFrame({
"Balanced":[46, 61, 72],
"Growth_priority":[28, 66, 91],
"Margin_priority":[51, 59, 63]
}, index=states["scenario"])
decision = pd.DataFrame({
"expected_profit": payoff.mul(states.probability.to_numpy(), axis=0).sum(),
"risk_std": [np.sqrt(np.average((payoff[c]-np.average(payoff[c],weights=states.probability))**2,
weights=states.probability)) for c in payoff],
"worst_case": payoff.min()
}).sort_values("expected_profit", ascending=False)
display(payoff)
display(decision.round(1))
| Balanced | Growth_priority | Margin_priority | |
|---|---|---|---|
| scenario | |||
| Low | 46 | 28 | 51 |
| Base | 61 | 66 | 59 |
| High | 72 | 91 | 63 |
| expected_profit | risk_std | worst_case | |
|---|---|---|---|
| Growth_priority | 62.80 | 22.50 | 28 |
| Balanced | 60.00 | 9.20 | 46 |
| Margin_priority | 58.00 | 4.40 | 51 |
結果の読み取り
成長優先は期待利益が最大でも下振れ幅が大きく、利益優先は期待値を少し犠牲にして最悪値を改善します。経営会議では「最大期待利益」だけでなく、最低限確保したい利益と追加リスクを引き受ける条件を先に決めるべきです。
No.092:OODA
実務での意味
OODAは Observe(観測)、Orient(状況判断)、Decide(決定)、Act(実行)の循環です。月次会議の資料作成手順ではなく、変化を検知して判断を更新する運用設計として使います。
分析・モデル化の考え方
観測値を基準値と比較し、しきい値を超えた例外だけを判断対象にします。ここでは納期遵守率が92%未満、または設備稼働率が90%超なら増産より負荷調整を優先する単純な判断規則を置きます。
Pythonで確認する
monthly = df.groupby("month").agg(revenue=("revenue","sum"), gross_profit=("gross_profit","sum"),
utilization=("utilization","mean"), on_time=("on_time","mean"), defect_rate=("defect_rate","mean")).reset_index()
monthly["signal"] = np.select(
[(monthly.on_time < .92) | (monthly.utilization > .90), monthly.gross_profit.pct_change() < -.08],
["Capacity review", "Demand review"], default="Continue")
display(monthly.tail(8).assign(
utilization=lambda x: x.utilization.map("{:.1%}".format),
on_time=lambda x: x.on_time.map("{:.1%}".format),
defect_rate=lambda x: x.defect_rate.map("{:.1%}".format)))
| month | revenue | gross_profit | utilization | on_time | defect_rate | signal | |
|---|---|---|---|---|---|---|---|
| 16 | 2025-05-01 | 577.78 | 138.85 | 86.7% | 91.4% | 1.5% | Capacity review |
| 17 | 2025-06-01 | 545.86 | 132.93 | 91.1% | 88.9% | 1.6% | Capacity review |
| 18 | 2025-07-01 | 624.31 | 140.50 | 92.9% | 87.7% | 1.8% | Capacity review |
| 19 | 2025-08-01 | 591.95 | 146.69 | 89.1% | 90.0% | 1.6% | Capacity review |
| 20 | 2025-09-01 | 628.77 | 155.17 | 90.5% | 89.1% | 1.6% | Capacity review |
| 21 | 2025-10-01 | 522.30 | 122.20 | 91.4% | 88.9% | 1.6% | Capacity review |
| 22 | 2025-11-01 | 600.21 | 141.85 | 92.7% | 87.9% | 1.8% | Capacity review |
| 23 | 2025-12-01 | 522.11 | 129.40 | 95.3% | 86.5% | 1.8% | Capacity review |
結果の読み取り
OODAの速度は、会議回数ではなく「兆候から対策実行までの日数」で測ります。しきい値を自動検知し、担当者・期限・選べる対策を事前に定義すると、観測から実行までの滞留を減らせます。
No.093:シナリオ分析
実務での意味
単一予算は外れた瞬間に役に立たなくなります。需要、材料費、供給能力の組み合わせを複数用意し、各状況で利益と納期が許容範囲に入るかを確認します。
分析・モデル化の考え方
簡易的な四半期粗利を
とします。 は需要増減、 は材料費上昇による粗利率低下、 は稼働率です。式の係数は説明用の仮定であり、実務では原価構造から推定します。
Pythonで確認する
base_revenue = monthly.revenue.tail(3).sum()
base_margin = monthly.gross_profit.tail(3).sum() / base_revenue
scenarios = pd.DataFrame({
"scenario":["Downside","Base","Upside"],
"demand_change":[-.15,0,.18], "material_margin_impact":[.045,.015,.005],
"utilization":[.80,.88,.96], "probability":[.25,.50,.25]})
scenarios["quarter_revenue"] = base_revenue*(1+scenarios.demand_change)
scenarios["quarter_profit"] = scenarios.quarter_revenue*(base_margin-scenarios.material_margin_impact-
.08*np.maximum(scenarios.utilization-.85,0))
display(scenarios.round(2))
plt.bar(scenarios.scenario, scenarios.quarter_profit, color=["#d95f5f","#4c78a8","#59a14f"])
plt.axhline(120, color="black", linestyle="--", label="Minimum target")
plt.title("Quarterly Gross Profit by Scenario")
plt.xlabel("Scenario"); plt.ylabel("Gross profit (JPY million)"); plt.grid(axis="y", alpha=.3); plt.legend()
plt.tight_layout(); plt.show()
| scenario | demand_change | material_margin_impact | utilization | probability | quarter_revenue | quarter_profit | |
|---|---|---|---|---|---|---|---|
| 0 | Downside | -0.15 | 0.04 | 0.80 | 0.25 | 1,397.93 | 271.53 |
| 1 | Base | 0.00 | 0.02 | 0.88 | 0.50 | 1,644.63 | 364.84 |
| 2 | Upside | 0.18 | 0.00 | 0.96 | 0.25 | 1,940.66 | 437.49 |

結果の読み取り
悲観ケースで最低利益を下回るなら、予算を下げるだけでは不十分です。材料価格の再交渉、案件選別、外注枠の確保など、先に実行できる緩和策と発動条件を紐づけます。
No.094:KPI設計
実務での意味
売上は重要ですが、結果が判明した時点では手遅れになりがちです。受注前の案件量・見積速度、受注後の稼働率・品質をつなぎ、現場が動かせるKPIに分解します。
分析・モデル化の考え方
売上を「案件数 × 受注率 × 平均単価」に分解し、粗利を「売上 × 粗利率」に接続します。KPIには定義、粒度、更新頻度、責任者、目標、ガードレールが必要です。
Pythonで確認する
latest = df[df.month >= df.month.max()-pd.offsets.MonthBegin(2)]
kpi = pd.Series({
"Leads": latest.leads.sum(),
"Win rate": latest.orders.sum()/latest.leads.sum(),
"Avg revenue/order": latest.revenue.sum()/latest.orders.sum(),
"Gross margin": latest.gross_profit.sum()/latest.revenue.sum(),
"On-time rate": np.average(latest.on_time, weights=latest.orders),
"Defect rate": np.average(latest.defect_rate, weights=latest.orders)
}, name="latest_quarter")
targets = pd.Series({"Leads":650,"Win rate":.30,"Avg revenue/order":6.0,"Gross margin":.25,
"On-time rate":.94,"Defect rate":.015}, name="target")
kpi_table = pd.concat([kpi, targets], axis=1)
kpi_table["status"] = np.where(
[kpi[x] <= targets[x] if x=="Defect rate" else kpi[x] >= targets[x] for x in kpi.index], "OK", "Review")
display(kpi_table)
| latest_quarter | target | status | |
|---|---|---|---|
| Leads | 671.00 | 650.00 | OK |
| Win rate | 0.39 | 0.30 | OK |
| Avg revenue/order | 6.23 | 6.00 | OK |
| Gross margin | 0.24 | 0.25 | Review |
| On-time rate | 0.88 | 0.94 | Review |
| Defect rate | 0.02 | 0.01 | Review |
結果の読み取り
売上未達だけを見るのではなく、案件不足、受注率低下、単価低下のどこが原因かを切り分けられます。一方、受注率だけを上げる値引きを防ぐため、粗利率と納期遵守率をガードレールにします。
No.095:経営ダッシュボード
実務での意味
ダッシュボードの目的は情報を多く載せることではなく、例外を発見し、担当者が次の行動へ移れることです。全社→製品→案件へ掘り下げられる粒度を設計します。
分析・モデル化の考え方
最新月の実績を目標と比較し、差分を色で示します。KPIカード、時系列、内訳の三層を最小構成とし、同じ定義を全会議で使います。
Pythonで確認する
fig, axes = plt.subplots(2, 2, figsize=(11, 7))
axes[0,0].plot(monthly.month, monthly.revenue, marker="o", ms=3)
axes[0,0].set_title("Monthly Revenue"); axes[0,0].set_xlabel("Month"); axes[0,0].set_ylabel("JPY million"); axes[0,0].grid(alpha=.3)
axes[0,1].plot(monthly.month, monthly.gross_profit, color="#59a14f")
axes[0,1].set_title("Monthly Gross Profit"); axes[0,1].set_xlabel("Month"); axes[0,1].set_ylabel("JPY million"); axes[0,1].grid(alpha=.3)
axes[1,0].plot(monthly.month, monthly.on_time*100, color="#f28e2b")
axes[1,0].axhline(94, color="black", ls="--")
axes[1,0].set_title("On-time Delivery"); axes[1,0].set_xlabel("Month"); axes[1,0].set_ylabel("Percent"); axes[1,0].grid(alpha=.3)
prod = latest.groupby("product").gross_profit.sum().sort_values()
axes[1,1].barh(prod.index, prod.values, color="#4c78a8")
axes[1,1].set_title("Quarterly Profit by Product"); axes[1,1].set_xlabel("JPY million"); axes[1,1].set_ylabel("Product"); axes[1,1].grid(axis="x", alpha=.3)
fig.suptitle("Executive Decision Dashboard", fontsize=14)
plt.tight_layout(); plt.show()

結果の読み取り
利益の変化と同時に納期・製品別内訳を見ることで、「売れているが供給できない」「売上は小さいが高採算」といった構造を確認できます。赤信号には必ず、責任者、原因仮説、次回確認日を付けます。
No.096:AIと意思決定
実務での意味
AIは受注確率を提示できますが、価格、供給制約、顧客戦略を含む採否は人が担います。モデル出力を「決定」に変換する規則と、人へ戻す例外条件が必要です。
分析・モデル化の考え方
案件 の期待価値を
とし、受注確率 が高く、期待価値が正で、能力負荷が許容内なら優先します。高額・低信頼の案件は自動判断せず、人のレビューへ回します。
Pythonで確認する
opportunities = pd.DataFrame({
"deal":[f"D-{i:03d}" for i in range(1,9)],
"ai_win_prob":[.82,.71,.64,.58,.47,.39,.76,.55],
"gross_profit":[18,11,25,8,20,7,35,13],
"proposal_cost":[1.5,1.2,3.5,.8,2.7,.7,5.0,1.4],
"capacity_hours":[120,80,260,70,190,60,340,110],
"confidence":[.90,.86,.62,.91,.72,.88,.55,.84]})
opportunities["expected_value"] = opportunities.ai_win_prob*opportunities.gross_profit-(1-opportunities.ai_win_prob)*opportunities.proposal_cost
opportunities["decision"] = np.select(
[(opportunities.confidence < .65) | (opportunities.capacity_hours > 300),
(opportunities.ai_win_prob >= .55) & (opportunities.expected_value > 5)],
["Human review","Prioritize"], default="Nurture")
display(opportunities.sort_values("expected_value", ascending=False))
| deal | ai_win_prob | gross_profit | proposal_cost | capacity_hours | confidence | expected_value | decision | |
|---|---|---|---|---|---|---|---|---|
| 6 | D-007 | 0.76 | 35 | 5.00 | 340 | 0.55 | 25.40 | Human review |
| 2 | D-003 | 0.64 | 25 | 3.50 | 260 | 0.62 | 14.74 | Human review |
| 0 | D-001 | 0.82 | 18 | 1.50 | 120 | 0.90 | 14.49 | Prioritize |
| 4 | D-005 | 0.47 | 20 | 2.70 | 190 | 0.72 | 7.97 | Nurture |
| 1 | D-002 | 0.71 | 11 | 1.20 | 80 | 0.86 | 7.46 | Prioritize |
| 7 | D-008 | 0.55 | 13 | 1.40 | 110 | 0.84 | 6.52 | Prioritize |
| 3 | D-004 | 0.58 | 8 | 0.80 | 70 | 0.91 | 4.30 | Nurture |
| 5 | D-006 | 0.39 | 7 | 0.70 | 60 | 0.88 | 2.30 | Nurture |
結果の読み取り
高い期待価値でも、学習データの少ない大型案件や能力負荷の大きい案件は人が確認します。判断ログにはAI提案、採否、上書き理由、結果を残し、モデルと業務規則の双方を改善します。
No.097:製造業DI
実務での意味
ここでのDI(Decision Intelligence)は、データ・モデル・業務知識をつなぎ、意思決定の質と速度を継続改善する考え方です。単なるBIや予測モデルではなく、判断と結果を閉ループにします。
分析・モデル化の考え方
先行指標を標準化し、需要・収益・供給の方向が良いほど高くなる合成指数を作ります。重みは経営上の優先度を表すため、統計だけで自動決定せず、感度分析と合意形成を行います。
Pythonで確認する
di = monthly.copy()
di["lead_growth"] = df.groupby("month").leads.sum().pct_change().values
di["margin_rate"] = di.gross_profit/di.revenue
features = pd.DataFrame({
"demand": di.lead_growth.fillna(0), "margin": di.margin_rate,
"delivery": di.on_time, "quality": -di.defect_rate, "capacity_buffer": -di.utilization})
z = (features-features.mean())/features.std(ddof=0)
weights = pd.Series({"demand":.20,"margin":.25,"delivery":.25,"quality":.15,"capacity_buffer":.15})
di["DI_score"] = 50 + 10*z.mul(weights).sum(axis=1)
display(di[["month","DI_score","signal"]].tail(8))
plt.plot(di.month, di.DI_score, marker="o")
plt.axhline(50, color="black", ls="--", label="Long-run baseline")
plt.title("Manufacturing Decision Intelligence Index")
plt.xlabel("Month"); plt.ylabel("DI score"); plt.grid(alpha=.3); plt.legend(); plt.tight_layout(); plt.show()
| month | DI_score | signal | |
|---|---|---|---|
| 16 | 2025-05-01 | 49.58 | Capacity review |
| 17 | 2025-06-01 | 46.74 | Capacity review |
| 18 | 2025-07-01 | 36.91 | Capacity review |
| 19 | 2025-08-01 | 49.28 | Capacity review |
| 20 | 2025-09-01 | 46.10 | Capacity review |
| 21 | 2025-10-01 | 41.02 | Capacity review |
| 22 | 2025-11-01 | 43.98 | Capacity review |
| 23 | 2025-12-01 | 42.61 | Capacity review |

結果の読み取り
合成指数は経営環境の方向を一目で示しますが、原因を隠す危険があります。DIが低下した月は必ず構成指標へ掘り下げ、需要減なのか、供給逼迫なのかを特定して対策を変えます。
No.098:Palantirから学ぶこと
実務での意味
特定製品の機能紹介ではなく、データを「顧客・案件・製品・設備・注文」という業務オブジェクトとして結び、分析結果を現場のアクションへ接続する設計思想を学びます。
分析・モデル化の考え方
共通ID、関係、状態、権限、実行可能なアクションを定義します。分析用の巨大な一枚表だけではなく、どの案件がどの製品能力を消費し、誰が承認するかという意味構造を持たせます。
Pythonで確認する
object_model = pd.DataFrame([
["Customer","customer_id","owns","Opportunity","Sales"],
["Opportunity","deal_id","requests","Product","Sales"],
["Order","order_id","consumes","WorkCenter","Production"],
["Product","product_id","uses","Material","Engineering"],
["Decision","decision_id","acts_on","Opportunity/Order","Manager"]
], columns=["object","primary_key","relationship","linked_object","owner"])
decision_log = opportunities[["deal","ai_win_prob","expected_value","decision"]].copy()
decision_log["action"] = decision_log.decision.map({"Prioritize":"Assign senior sales", "Nurture":"Schedule follow-up", "Human review":"Convene S&OP review"})
display(object_model)
display(decision_log.head())
| object | primary_key | relationship | linked_object | owner | |
|---|---|---|---|---|---|
| 0 | Customer | customer_id | owns | Opportunity | Sales |
| 1 | Opportunity | deal_id | requests | Product | Sales |
| 2 | Order | order_id | consumes | WorkCenter | Production |
| 3 | Product | product_id | uses | Material | Engineering |
| 4 | Decision | decision_id | acts_on | Opportunity/Order | Manager |
| deal | ai_win_prob | expected_value | decision | action | |
|---|---|---|---|---|---|
| 0 | D-001 | 0.82 | 14.49 | Prioritize | Assign senior sales |
| 1 | D-002 | 0.71 | 7.46 | Prioritize | Assign senior sales |
| 2 | D-003 | 0.64 | 14.74 | Human review | Convene S&OP review |
| 3 | D-004 | 0.58 | 4.30 | Nurture | Schedule follow-up |
| 4 | D-005 | 0.47 | 7.97 | Nurture | Schedule follow-up |
結果の読み取り
価値はデータ統合そのものではなく、案件の優先順位変更や能力予約というアクションまで追跡できる点にあります。最初から全社統合を狙わず、重要な意思決定一つと必要オブジェクトから始めます。
No.099:数理工房のビジョン
実務での意味
数理モデルを納品して終えるのではなく、経営課題の定義、データ整備、モデル、業務実装、人材育成を一体で進めることが重要です。現場が自ら改善できる状態をゴールにします。
分析・モデル化の考え方
価値を「年間判断回数 × 1回当たり改善額 × 採用率 − 年間運用費」と捉えます。精度が高くても採用されなければ価値は生まれません。段階導入で利用率と効果を検証します。
Pythonで確認する
roadmap = pd.DataFrame({
"phase":["1. Decision design","2. Pilot","3. Workflow integration","4. Scale"],
"months":[1,2,3,6], "decisions_per_year":[12,24,60,180],
"benefit_per_decision":[.8,1.0,1.2,1.3], "adoption_rate":[.25,.50,.72,.85],
"annual_run_cost":[3,6,12,25]})
roadmap["annual_value"] = roadmap.decisions_per_year*roadmap.benefit_per_decision*roadmap.adoption_rate-roadmap.annual_run_cost
display(roadmap)
plt.bar(roadmap.phase, roadmap.annual_value, color="#4c78a8")
plt.title("Expected Annual Value by Implementation Phase")
plt.xlabel("Phase"); plt.ylabel("Net value (JPY million/year)"); plt.grid(axis="y", alpha=.3)
plt.xticks(rotation=18, ha="right"); plt.tight_layout(); plt.show()
| phase | months | decisions_per_year | benefit_per_decision | adoption_rate | annual_run_cost | annual_value | |
|---|---|---|---|---|---|---|---|
| 0 | 1. Decision design | 1 | 12 | 0.80 | 0.25 | 3 | -0.60 |
| 1 | 2. Pilot | 2 | 24 | 1.00 | 0.50 | 6 | 6.00 |
| 2 | 3. Workflow integration | 3 | 60 | 1.20 | 0.72 | 12 | 39.84 |
| 3 | 4. Scale | 6 | 180 | 1.30 | 0.85 | 25 | 173.90 |

結果の読み取り
初期段階では価値が小さくても、判断回数と採用率が上がると効果が拡大します。PoCの合格条件にはモデル精度だけでなく、利用率、判断時間、上書き理由の記録率を含めます。
No.100:AI時代のマーケティングサイエンス
実務での意味
AI時代の競争力は、モデル単体の性能ではなく、顧客理解・需要予測・供給制約・現場判断をつなぎ、結果から学ぶ速度で決まります。AIは提案を大量に生成し、人は目的・制約・例外・説明責任を担います。
分析・モデル化の考え方
施策の価値を、期待粗利から能力負荷の影のコストとリスクペナルティを引いて評価します。
評価指標は予測精度、利益、ガードレール、採用率、学習速度の組み合わせです。
Pythonで確認する
portfolio = opportunities.copy()
portfolio["risk"] = (1-portfolio.confidence)*portfolio.gross_profit
portfolio["decision_score"] = portfolio.expected_value - .012*portfolio.capacity_hours - .35*portfolio.risk
portfolio = portfolio.sort_values("decision_score", ascending=False)
portfolio["cumulative_hours"] = portfolio.capacity_hours.cumsum()
portfolio["selected_under_700h"] = portfolio.cumulative_hours <= 700
display(portfolio[["deal","ai_win_prob","expected_value","capacity_hours","risk","decision_score","selected_under_700h"]])
colors = np.where(portfolio.selected_under_700h, "#59a14f", "#bab0ac")
plt.scatter(portfolio.capacity_hours, portfolio.decision_score, s=portfolio.gross_profit*12, c=colors, alpha=.8)
for _, row in portfolio.iterrows():
plt.annotate(row.deal, (row.capacity_hours, row.decision_score), xytext=(4,4), textcoords="offset points", fontsize=8)
plt.title("Human-AI Opportunity Portfolio")
plt.xlabel("Required capacity (hours)"); plt.ylabel("Decision score"); plt.grid(alpha=.3); plt.tight_layout(); plt.show()
| deal | ai_win_prob | expected_value | capacity_hours | risk | decision_score | selected_under_700h | |
|---|---|---|---|---|---|---|---|
| 6 | D-007 | 0.76 | 25.40 | 340 | 15.75 | 15.81 | True |
| 0 | D-001 | 0.82 | 14.49 | 120 | 1.80 | 12.42 | True |
| 2 | D-003 | 0.64 | 14.74 | 260 | 9.50 | 8.30 | False |
| 1 | D-002 | 0.71 | 7.46 | 80 | 1.54 | 5.96 | False |
| 7 | D-008 | 0.55 | 6.52 | 110 | 2.08 | 4.47 | False |
| 4 | D-005 | 0.47 | 7.97 | 190 | 5.60 | 3.73 | False |
| 3 | D-004 | 0.58 | 4.30 | 70 | 0.72 | 3.21 | False |
| 5 | D-006 | 0.39 | 2.30 | 60 | 0.84 | 1.29 | False |

結果の読み取り
受注確率だけで並べず、利益、能力、モデル信頼度を含めると優先順位が変わります。人が上書きした理由と最終結果を蓄積すれば、次回のスコアと判断規則を更新できます。これが人とAIの学習ループです。
対象ノックを通して見える実務上の示唆
- 予測値ではなく、選択肢・制約・判断期限を分析の入口にする
- 売上、利益、納期、品質を同じ意思決定モデルで扱う
- シナリオごとに対策と発動条件を先に決める
- AIの提案、採否、上書き理由、結果を判断ログとして残す
- ダッシュボードから担当者のアクションまでを一つの業務フローにする
実務導入する場合に必要なこと
- 意思決定の棚卸し:頻度、責任者、選択肢、期限、現状の所要時間を特定する
- データ契約:KPI定義、共通ID、更新頻度、欠損時の扱い、アクセス権を定める
- 検証設計:予測精度に加え、利益、納期、採用率、判断時間を導入前後で比較する
- ガバナンス:自動化可能範囲、人の承認条件、停止条件、監査ログを明文化する
- 運用体制:モデル監視、KPIレビュー、現場教育、改善バックログの責任者を置く
まとめ
No.091〜No.100では、意思決定科学からOODA、シナリオ、KPI、ダッシュボード、AI、DI、業務オブジェクト、導入ロードマップまでを一つの流れとして確認しました。製造業のマーケティングサイエンスは、需要を分析するだけでなく、供給制約のもとで顧客・案件・生産能力をどう結び付けるかを扱う経営技術です。
法人向けのご相談
数理工房では、経営ダッシュボード、需要・受注予測、営業案件の優先順位付け、S&OP、意思決定AIの構想設計からPoC、運用定着までご支援します。自社のどの意思決定から始めるべきか整理したい段階でもご相談いただけます。
📩 お問い合わせ: surikobo.co.jp/contact まずはお気軽にご相談ください。