定位为教学级市场容量测算工具(Educational Demo),去营销、中立化,避免任何引流与商业承诺,仅用于课程讨论、工程思维训练与战略沙盘教学。
术语说明:“M 型社会”源自大前研一等学者的消费结构理论,指财富分配向高/低端两极集中、中产层相对收缩的现象;“麦时尚”此处作为平价快时尚(Mass-market Fast Fashion)的简称使用,非特指单一商业品牌。
一、实际应用场景描述
在时尚产业与品牌创新课程的“市场洞察”模块中,“如何估算一个赛道容量”是高频但常被简化的议题。
典型教学/实践场景包括:
- 课程作业:学生需要为“平价快时尚 / 大众通勤穿搭”赛道估算可触达市场规模
- 品牌企划:判断某一价格带、某一人群是否值得进入
- 战略工作坊:用 TAM / SAM / SOM 框架做 What-if 推演
- 行业研究入门:理解“人口 × ARPU”“自上而下 / 自下而上”两类测算逻辑
本工具尝试将 M 型社会人口分层 与 平价穿搭赛道 结构化,通过透明、可审计的参数模型,输出 TAM / SAM / SOM 三级市场容量估算,用于课堂讨论与方法论训练。
二、引入痛点(中立表述)
- 市场规模常被拍脑袋:引用第三方报告数字,但不清楚口径与假设
- 人口分层缺失:直接套用“全国人口 × 人均服装消费”,忽略 M 型结构下不同层级消费行为差异
- TAM/SAM/SOM 混淆:三者边界不清,教学场景缺乏最小可运行原型
- What-if 能力弱:人口占比、ARPU、渗透率任一变量变化时,需重新手工推算
- 工程化误区:把行业报告截图当作“模型”,不可复现、不可审计
本工具不预测真实市场规模,而是回答:
“在给定假设下,M 型社会中平价快时尚赛道的三级容量如何结构化拆解?”
三、核心逻辑讲解
1. M 型人口分层(教学模型)
层级 定义 对平价穿搭的意义
顶层(Top) 高净值,奢侈/设计师导向 非目标赛道,可作对照
中层(Middle,塌陷中) 原中产,消费趋于“精明化” 部分流向平价优质
底层(Bottom,扩张中) 价格敏感,追求性价比 平价快时尚主战场
2. 三级市场容量框架(TAM / SAM / SOM)
- TAM(Total Addressable Market):理论最大市场
"总人口 × 平价穿搭适用人口比例 × 人均年服装支出"
- SAM(Serviceable Addressable Market):商业模式可触达部分
"TAM × 渠道/价格带覆盖比例"
- SOM(Serviceable Obtainable Market):短期内可获取的份额
"SAM × 竞争格局/品牌份额假设"
自上而下公式可表达为:
市场规模 ≈ 目标人口 × 渗透率 × ARPU
3. 关键变量
变量 含义
total_population 区域总人口
bottom_pct / mid_pct / top_pct 人口分层占比(合计=1)
fashion_share_of_spend 服装占个人消费比例(分层差异)
arpu_fast_fashion 平价快时尚人均年支出
channel_coverage 渠道可触达比例(SAM)
brand_share 品牌可获取份额(SOM)
4. 关键假设(必须显式声明)
- 人口占比、ARPU、渗透率均为教学假设,非官方统计
- 未考虑地域差异、通胀、跨境、二手分流
- 输出为量级估算(order-of-magnitude),不可直接用于融资材料
四、代码模块化(注释清晰)
目录结构:
m_shaped_ff_market/
├── models.py # 数据结构与默认参数
├── population.py # 人口分层计算
├── tam_sam_som.py # 三级容量计算
├── scenario.py # What-if 情景扰动
├── reporter.py # 结果格式化
├── main.py # CLI 入口 + demo
└── README.md
"models.py"
"""
models.py
定义 M 型社会市场测算的数据结构与默认参数。
所有数值均为教学示例,可按课程/区域替换。
"""
from dataclasses import dataclass
@dataclass
class MarketInput:
total_population: int # 区域总人口(人)
bottom_pct: float # 底层人口占比
mid_pct: float # 中层人口占比
top_pct: float # 顶层人口占比
# 各层人均年服装支出(元,教学假设)
arpu_bottom: float
arpu_mid: float
arpu_top: float
# 平价快时尚在每层的可触达比例
fast_fashion_penetration_bottom: float
fast_fashion_penetration_mid: float
fast_fashion_penetration_top: float
# SAM / SOM 参数
channel_coverage: float # SAM 占可触达市场比例
brand_share: float # SOM 占 SAM 比例
@dataclass
class MarketResult:
tam: float
sam: float
som: float
bottom_pop: int
mid_pop: int
top_pop: int
detail_by_tier: dict
# 教学用默认参数(示意,非真实统计数据)
DEFAULT_INPUT = MarketInput(
total_population=140_000_000, # 1.4 亿(示例区域)
bottom_pct=0.55,
mid_pct=0.30,
top_pct=0.15,
arpu_bottom=800,
arpu_mid=2000,
arpu_top=6000,
fast_fashion_penetration_bottom=0.70,
fast_fashion_penetration_mid=0.25,
fast_fashion_penetration_top=0.05,
channel_coverage=0.60,
brand_share=0.03,
)
"population.py"
"""
population.py
人口分层计算。
"""
def split_population(inp: "MarketInput") -> tuple[int, int, int]:
"""
返回 (bottom_pop, mid_pop, top_pop)
"""
total = inp.total_population
return (
int(total * inp.bottom_pct),
int(total * inp.mid_pct),
int(total * inp.top_pct),
)
"tam_sam_som.py"
"""
tam_sam_som.py
TAM / SAM / SOM 三级市场容量计算。
"""
from .population import split_population
def calc_market(inp: "MarketInput") -> "MarketResult":
bottom_pop, mid_pop, top_pop = split_population(inp)
# ---- TAM:分人群加总 ----
# 平价快时尚可触达人群 × 对应 ARPU
tam_bottom = (
bottom_pop * inp.fast_fashion_penetration_bottom * inp.arpu_bottom
)
tam_mid = (
mid_pop * inp.fast_fashion_penetration_mid * inp.arpu_mid
)
tam_top = (
top_pop * inp.fast_fashion_penetration_top * inp.arpu_top
)
tam = tam_bottom + tam_mid + tam_top
# ---- SAM:商业模式可触达 ----
sam = tam * inp.channel_coverage
# ---- SOM:品牌可获取 ----
som = sam * inp.brand_share
from .models import MarketResult
return MarketResult(
tam=tam,
sam=sam,
som=som,
bottom_pop=bottom_pop,
mid_pop=mid_pop,
top_pop=top_pop,
detail_by_tier={
"bottom": {"pop": bottom_pop, "tam_contrib": tam_bottom},
"mid": {"pop": mid_pop, "tam_contrib": tam_mid},
"top": {"pop": top_pop, "tam_contrib": tam_top},
},
)
"scenario.py"
"""
scenario.py
What-if 情景扰动:单变量或组合变量变化。
"""
def perturb(inputs: list[tuple["MarketInput", str]], base_result) -> list[dict]:
"""
对每组 (inp, label) 重新计算,并与 baseline 对比。
"""
from .tam_sam_som import calc_market
results = []
for inp, label in inputs:
res = calc_market(inp)
results.append({
"label": label,
"tam": res.tam,
"sam": res.sam,
"som": res.som,
"tam_delta_pct": (res.tam - base_result.tam) / base_result.tam
if base_result.tam else None,
})
return results
"reporter.py"
"""
reporter.py
终端格式化输出。
"""
def print_report(result: "MarketResult", inp: "MarketInput"):
print("\n" + "=" * 56)
print(" M 型社会 · 平价快时尚市场容量(教学演示)")
print("=" * 56)
print(f"\n 人口分层")
print(f" 底层: {result.bottom_pop:,} 人 ({inp.bottom_pct:.0%})")
print(f" 中层: {result.mid_pop:,} 人 ({inp.mid_pct:.0%})")
print(f" 顶层: {result.top_pop:,} 人 ({inp.top_pct:.0%})")
print(f"\n TAM(理论可触达)")
print(f" 底层贡献: ¥{result.detail_by_tier['bottom']['tam_contrib']:,.0f}")
print(f" 中层贡献: ¥{result.detail_by_tier['mid']['tam_contrib']:,.0f}")
print(f" 顶层贡献: ¥{result.detail_by_tier['top']['tam_contrib']:,.0f}")
print(f" TAM 合计: ¥{result.tam:,.0f}")
print(f"\n SAM(渠道可触达,覆盖率 {inp.channel_coverage:.0%})")
print(f" SAM: ¥{result.sam:,.0f}")
print(f"\n SOM(品牌可获取,份额 {inp.brand_share:.0%})")
print(f" SOM: ¥{result.som:,.0f}")
print(f"\n{'=' * 56}")
print(" 说明:")
print(" - TAM/SAM/SOM 为教学级量级估算,非真实统计")
print(" - 参数可替换为国家/城市/平台级数据")
print(" - 建议做多情景扰动,观察结论稳健性")
print(f"{'=' * 56}\n")
"main.py"
"""
main.py
CLI 入口,内置 baseline + 两个 What-if 情景。
运行:python main.py
"""
from models import DEFAULT_INPUT, MarketInput
from tam_sam_som import calc_market
from reporter import print_report
from scenario import perturb
def run_demo():
base = DEFAULT_INPUT
base_result = calc_market(base)
print_report(base_result, base)
# What-if 情景
scenarios = [
(
MarketInput(
**{**base.__dict__, "bottom_pct": 0.60, "mid_pct": 0.25, "top_pct": 0.15},
),
"情景 A:底层扩张至 60%(M 型加剧)"
),
(
MarketInput(
**{**base.__dict__, "arpu_bottom": 1000, "channel_coverage": 0.70},
),
"情景 B:底层 ARPU↑ + 渠道覆盖↑"
),
]
perturbed = perturb(scenarios, base_result)
print(" What-if 情景对比")
print("=" * 56)
for p in perturbed:
label = p["label"]
tam = p["tam"]
delta = p["tam_delta_pct"]
line = f" {label}"
line += f"\n TAM: ¥{tam:,.0f}"
if delta is not None:
line += f" ({delta:+.1%} vs baseline)"
print(line)
print("=" * 56)
if __name__ == "__main__":
run_demo()
五、README.md
# M-Shaped Fast-Fashion Market Sizing(教学演示)
一个轻量级 Python 工具,基于 **M 型社会人口分层** 与 **TAM/SAM/SOM 框架**,估算平价快时尚赛道的市场容量量级。
## 定位与边界
- 目的:把“市场规模”从引用报告数字,转为可审计的参数模型
- 非行业数据库,不替代 Statista / Euromonitor / 券商研报
- 忽略:地域差异、通胀、跨境、二手、库存周转
- 输出为 **order-of-magnitude 量级估算**,不可直接用于融资材料
- 适用于:时尚产业课程、战略沙盘、作业原型
## 环境
- Python ≥ 3.8(仅标准库)
## 安装与运行
bash
git clone <repo-url>
cd m_shaped_ff_market
python main.py
## 模块说明
| 文件 | 职责 |
|---|---|
| `models.py` | 数据结构、默认参数 |
| `population.py` | 人口分层 |
| `tam_sam_som.py` | TAM / SAM / SOM 计算 |
| `scenario.py` | What-if 单变量扰动 |
| `reporter.py` | 终端格式化 |
| `main.py` | CLI 入口与演示情景 |
## 如何调整
### 替换区域/人口
修改 `models.py` 中 `DEFAULT_INPUT.total_population` 与分层占比。
### 接入外部数据
将 `arpu_*` / `fast_fashion_penetration_*` 替换为地方统计或报告值。
### 扩展 SAM 逻辑
在 `tam_sam_som.py` 中引入渠道、价格带、线上/线下细分。
### 批量情景
循环调用 `scenario.perturb()`,或从 JSON/YAML 读取参数矩阵。
## TAM / SAM / SOM 简要
- TAM:理论最大市场(所有人 × 可触达比例 × ARPU)
- SAM:商业模式/渠道可覆盖部分
- SOM:特定品牌在中短期内可获取的份额
## 许可证
MIT(教学用途,自行承担使用风险)
六、核心知识点卡片(中立、去营销)
卡片 1 · M 型社会与消费分层
- 大前研一等提出:财富向两端集中,中产相对收缩
- 对时尚产业含义:奢华端(DSPD)+ 平价端(BLCR)同步扩张,中层受挤压
- 教学要点:人口分层是市场测算的前置假设,需显式声明
卡片 2 · TAM / SAM / SOM 框架
- 战略分析经典工具,用于区分“理论市场 / 可触达 / 可获取”
- 常见误区:把 TAM 当成年收入预期
- Python 映射:三级计算链式调用,参数集中管理
卡片 3 · 自上而下 vs 自下而上测算
- 自上而下:宏观人口/行业报告 → 细分过滤
- 自下而上:单客 ARPU × 客户数 → 放大
- 教学建议:两种并行,交叉校验量级
卡片 4 · What-if 敏感性分析
- 核心思想:单一变量扰动,观察结论是否反转
- 工程实现:参数副本 + 重新计算 + 相对变化输出
- 教学价值:培养“假设意识”,避免把数字当真理
七、总结
这个程序的核心价值不在于“算出某市场多少亿”,而在于三点:
1. 把“市场规模”从报告引用变成可拆解、可审计的参数结构
2. 展示如何用 TAM/SAM/SOM + M 型分层构建一个透明的教学级测算模型
3. 为课程提供一个“从消费理论到数量化”的最小可运行原型
对全栈工程师而言,这是典型的领域建模 + 参数驱动 + CLI 工具;对技术博主而言,重点应放在方法论透明度、假设声明与教学延伸,而非给出“权威市场数字”。
利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!