100本ノック / マーケティングサイエンス / マーケティングサイエンス100本ノック

製造業の意思決定をデータとAIで変える|マーケティングサイエンス実践10本ノック

営業・生産・経営をつなぐ意思決定基盤:製造業マーケティングサイエンス実践10本ノック

本記事では、産業機器メーカーの架空データを用い、観測から経営判断、実行、学習までを一つの仕組みにする方法を扱います。対象は No.091〜No.100(意思決定科学、OODA、シナリオ分析、KPI設計、経営ダッシュボード、AIと意思決定、製造業DI、Palantirから学ぶこと、数理工房のビジョン、AI時代のマーケティングサイエンス)です。

分析精度だけでなく、「誰が、いつ、何を決めるか」「どの条件なら判断を変えるか」まで具体化します。

[!NOTE] 本資料は、数理工房 (もしくは代表である和山個人) が過去に企業研修において使用した notebook を企業様の許可を得て再構成・編集のうえ公開しています。 掲載データはすべて架空のものであり、実在する企業・工場・数値とは一切関係ありません。

はじめに:この記事で扱う製造業の実務課題

架空の「光栄インダストリアル」は、標準機・高効率機・特注機を販売する産業機器メーカーです。引き合いは増えていますが、営業は受注、工場は稼働率、経営は利益を重視し、会議ごとに異なる数字が提示されます。本記事の問いは、限られた生産能力と営業資源を、どの案件・市場へ振り向けるべきかです。

現場でよくある状況

  • 売上目標を追うほど、低採算の特急案件が増えて残業と納期遅延が悪化する
  • CRM、見積、受注、生産、品質のデータが分断され、同じ顧客を一貫して見られない
  • 予測値だけが提示され、前提・不確実性・撤退条件が共有されない
  • AIの提案が、責任者や承認条件のないまま「参考情報」で終わる

なぜこの問題は判断が難しいのか

売上、粗利、納期、品質は相互に影響し、施策の効果が現れる時期も異なります。さらに、受注確率や材料費は確定値ではありません。したがって、単一KPIの最大化ではなく、目的・制約・不確実性を明示した意思決定が必要です。

今回扱うノックの全体像

No.テーマ経営会議で答える問い
091意思決定科学とは期待利益とリスクをどう比較するか
092OODAどの兆候を見て、いつ方針を変えるか
093シナリオ分析悲観・基準・楽観で計画は耐えられるか
094KPI設計結果指標を動かす先行指標は何か
095経営ダッシュボード例外をどの順で確認するか
096AIと意思決定AI提案をどの条件で採用するか
097製造業DI現場の変化を合成指標で早期検知できるか
098Palantirから学ぶことデータを業務オブジェクトと判断へどう結ぶか
099数理工房のビジョンPoCから運用定着までどう設計するか
100AI時代のマーケティングサイエンス人とAIの学習ループをどう構築するか

Python環境の準備

外部データには依存せず、numpypandasmatplotlib だけを使います。乱数シードを固定し、同じ結果を再現できるようにします。グラフ内のラベルは実行環境の日本語フォント差を避けるため英語表記とします。

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:意思決定科学とは

実務での意味

意思決定科学は「予測を当てる技術」だけではありません。選択肢、起こり得る状態、結果の価値、制約を整理し、どの選択肢を採るかまで扱います。ここでは次四半期の営業・生産方針を比較します。

分析・モデル化の考え方

施策 aa、需要状態 ss、利益 π(a,s)\pi(a,s)、状態確率 p(s)p(s) とすると、期待利益は

E[π(a)]=sp(s)π(a,s)E[\pi(a)] = \sum_s p(s)\pi(a,s)

です。ただし平均だけでは下振れを見落とすため、標準偏差と最悪値も併記します。確率は真実ではなく、現時点の仮定です。

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:シナリオ分析

実務での意味

単一予算は外れた瞬間に役に立たなくなります。需要、材料費、供給能力の組み合わせを複数用意し、各状況で利益と納期が許容範囲に入るかを確認します。

分析・モデル化の考え方

簡易的な四半期粗利を

G=R0(1+g){m0c0.08max(u0.85,0)}G = R_0(1+g)\{m_0-c-0.08\max(u-0.85,0)\}

とします。gg は需要増減、cc は材料費上昇による粗利率低下、uu は稼働率です。式の係数は説明用の仮定であり、実務では原価構造から推定します。

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

png

結果の読み取り

悲観ケースで最低利益を下回るなら、予算を下げるだけでは不十分です。材料価格の再交渉、案件選別、外注枠の確保など、先に実行できる緩和策と発動条件を紐づけます。

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()

png

結果の読み取り

利益の変化と同時に納期・製品別内訳を見ることで、「売れているが供給できない」「売上は小さいが高採算」といった構造を確認できます。赤信号には必ず、責任者、原因仮説、次回確認日を付けます。

No.096:AIと意思決定

実務での意味

AIは受注確率を提示できますが、価格、供給制約、顧客戦略を含む採否は人が担います。モデル出力を「決定」に変換する規則と、人へ戻す例外条件が必要です。

分析・モデル化の考え方

案件 ii の期待価値を

EVi=pi×GPi(1pi)CiEV_i = p_i\times GP_i-(1-p_i)C_i

とし、受注確率 pip_i が高く、期待価値が正で、能力負荷が許容内なら優先します。高額・低信頼の案件は自動判断せず、人のレビューへ回します。

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

png

結果の読み取り

合成指数は経営環境の方向を一目で示しますが、原因を隠す危険があります。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

png

結果の読み取り

初期段階では価値が小さくても、判断回数と採用率が上がると効果が拡大します。PoCの合格条件にはモデル精度だけでなく、利用率、判断時間、上書き理由の記録率を含めます。

No.100:AI時代のマーケティングサイエンス

実務での意味

AI時代の競争力は、モデル単体の性能ではなく、顧客理解・需要予測・供給制約・現場判断をつなぎ、結果から学ぶ速度で決まります。AIは提案を大量に生成し、人は目的・制約・例外・説明責任を担います。

分析・モデル化の考え方

施策の価値を、期待粗利から能力負荷の影のコストとリスクペナルティを引いて評価します。

Scorei=piGPi(1pi)CiλhHiλrRiScore_i=p_iGP_i-(1-p_i)C_i-\lambda_h H_i-\lambda_r R_i

評価指標は予測精度、利益、ガードレール、採用率、学習速度の組み合わせです。

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

png

結果の読み取り

受注確率だけで並べず、利益、能力、モデル信頼度を含めると優先順位が変わります。人が上書きした理由と最終結果を蓄積すれば、次回のスコアと判断規則を更新できます。これが人とAIの学習ループです。

対象ノックを通して見える実務上の示唆

  1. 予測値ではなく、選択肢・制約・判断期限を分析の入口にする
  2. 売上、利益、納期、品質を同じ意思決定モデルで扱う
  3. シナリオごとに対策と発動条件を先に決める
  4. AIの提案、採否、上書き理由、結果を判断ログとして残す
  5. ダッシュボードから担当者のアクションまでを一つの業務フローにする

実務導入する場合に必要なこと

  • 意思決定の棚卸し:頻度、責任者、選択肢、期限、現状の所要時間を特定する
  • データ契約:KPI定義、共通ID、更新頻度、欠損時の扱い、アクセス権を定める
  • 検証設計:予測精度に加え、利益、納期、採用率、判断時間を導入前後で比較する
  • ガバナンス:自動化可能範囲、人の承認条件、停止条件、監査ログを明文化する
  • 運用体制:モデル監視、KPIレビュー、現場教育、改善バックログの責任者を置く

まとめ

No.091〜No.100では、意思決定科学からOODA、シナリオ、KPI、ダッシュボード、AI、DI、業務オブジェクト、導入ロードマップまでを一つの流れとして確認しました。製造業のマーケティングサイエンスは、需要を分析するだけでなく、供給制約のもとで顧客・案件・生産能力をどう結び付けるかを扱う経営技術です。

法人向けのご相談

数理工房では、経営ダッシュボード、需要・受注予測、営業案件の優先順位付け、S&OP、意思決定AIの構想設計からPoC、運用定着までご支援します。自社のどの意思決定から始めるべきか整理したい段階でもご相談いただけます。

📩 お問い合わせ: surikobo.co.jp/contact まずはお気軽にご相談ください。