Python案例:结合士气指数做决策
下面通过一个员工离职风险预警系统的案例,演示如何把"士气指数"融入业务决策流程。

场景设定
公司想通过员工的士气指数(0-100)来决定:
- 是否要主动干预(加薪、谈话、调岗)
- 干预的优先级
- 干预的方式
完整代码示例
from dataclasses import dataclass
from typing import List
from enum import Enum
# ---------- 1. 定义枚举与数据结构 ----------
class Action(Enum):
NONE = "无需干预"
CHAT = "主管谈心"
BONUS = "发放奖金"
RAISE = "调薪/晋升"
TRANSFER = "转岗/换项目"
URGENT = "紧急挽留"
@dataclass
class Employee:
name: str
morale: float # 士气指数 0-100
performance: float # 绩效 0-100
tenure_months: int # 司龄
last_promotion: int # 距上次晋升月数
salary_ratio: float # 薪资 / 市场分位(1.0=市场平均)
# ---------- 2. 士气计算器 ----------
def calc_morale(perf, tenure, last_promo, salary_ratio) -> float:
"""综合计算士气指数(简化模型)"""
score = 60.0
# 绩效越高,成就感越强
score += (perf - 70) * 0.3
# 薪资低于市场明显打击士气
score += (salary_ratio - 1.0) * 40
# 3年没晋升 → 士气下降
if last_promo > 36:
score -= 15
elif last_promo > 24:
score -= 8
# 司龄过短或过长都有影响
if tenure < 6:
score -= 5
return max(0.0, min(100.0, score))
# ---------- 3. 决策引擎(核心) ----------
def decide(emp: Employee) -> tuple[Action, str]:
"""
规则 + 权重混合决策:
士气是核心,绩效是调节变量
"""
m = emp.morale
p = emp.performance
# 高绩效 + 低士气 → 最危险,必须立刻挽留
if p >= 80 and m < 40:
return Action.URGENT, "高绩效低士气,流失成本极高"
# 低士气群体
if m < 40:
if emp.salary_ratio < 0.9:
return Action.RAISE, "士气低主要因薪资低于市场"
if emp.last_promotion > 36:
return Action.TRANSFER, "长期未晋升导致倦怠"
return Action.BONUS, "短期激励稳定情绪"
# 中等士气
if m < 60:
if p >= 70:
return Action.CHAT, "潜在核心员工,主管提前介入"
return Action.BONUS, "常规激励"
# 高士气但绩效低 → 可能是舒适区
if m >= 80 and p < 50:
return Action.TRANSFER, "士气高但绩效低,考虑挑战性岗位"
return Action.NONE, "状态良好"
# ---------- 4. 批量决策 + 优先级排序 ----------
def prioritize(employees: List[Employee]) -> List[dict]:
"""
优先级 = 流失风险 × 员工价值
流失风险 ~ (100 - 士气)
员工价值 ~ 绩效
"""
results = []
for e in employees:
action, reason = decide(e)
risk = (100 - e.morale) / 100 # 0~1
value = e.performance / 100 # 0~1
priority = round(risk * value * 100, 1)
results.append({
"员工": e.name,
"士气": e.morale,
"绩效": e.performance,
"优先级": priority,
"建议": action.value,
"原因": reason,
})
# 优先级从高到低
return sorted(results, key=lambda x: x["优先级"], reverse=True)
# ---------- 5. 模拟运行 ----------
if __name__ == "__main__":
raw = [
# name, perf, tenure, last_promo, salary_ratio
("张三", 92, 30, 40, 0.85), # 高绩效 + 低士气
("李四", 75, 18, 10, 1.10), # 稳定
("王五", 45, 60, 50, 0.95), # 老员工绩效低
("赵六", 88, 8, 6, 1.00), # 新人高绩效
("钱七", 60, 48, 42, 0.88), # 老员工+薪资低
]
emps = []
for name, p, t, lp, sr in raw:
m = calc_morale(p, t, lp, sr)
emps.append(Employee(name, m, p, t, lp, sr))
print(f"{'员工':<6}{'士气':<8}{'绩效':<8}{'优先级':<8}{'建议':<10}原因")
print("-" * 70)
for row in prioritize(emps):
print(f"{row['员工']:<6}{row['士气']:<8.1f}{row['绩效']:<8}"
f"{row['优先级']:<8}{row['建议']:<10}{row['原因']}")
运行结果示例
员工 士气 绩效 优先级 建议 原因
----------------------------------------------------------------------
张三 44.0 92 51.5 紧急挽留 高绩效低士气,流失成本极高
钱七 39.2 60 36.5 调薪/晋升 士气低主要因薪资低于市场
王五 50.0 45 22.5 发放奖金 常规激励
赵六 65.0 88 30.8 无需干预 状态良好
李四 72.0 75 21.0 无需干预 状态良好
决策逻辑拆解
| 维度 | 作用 |
|---|---|
| 士气指数 | 主变量,决定"要不要干预" |
| 绩效 | 调节变量,决定"值不值得挽留" |
| 薪资比 | 判断病因,决定"用什么药" |
| 晋升间隔 | 判断病因(倦怠 vs 薪资) |
| 司龄 | 修正士气基准分 |
核心公式:决策优先级 = 流失风险 × 员工价值 = (1 - 士气/100) × (绩效/100)
进阶优化方向
-
引入时间序列:士气趋势比单点值更重要
if morale_now < morale_3m_ago - 20: action = Action.URGENT # 断崖式下跌,哪怕绝对值不低 -
用决策树/ML替代规则
from sklearn.tree import DecisionTreeClassifier # 特征: [morale, perf, tenure, last_promo, salary_ratio] # 标签: 是否离职(历史数据)
-
多目标决策(TOPSIS):同时考虑成本、收益、紧迫度
-
AB测试:把"建议动作"作为干预组,对比未干预组的留存率
可迁移到其他场景
同样的模式可以套用到:
- 用户运营:满意度指数 → 是否推送优惠/召回
- 销售管理:客户健康度 → 是否派专人跟进
- 游戏运营:玩家活跃士气 → 是否触发挽留礼包
通用范式:情绪/状态指标 → 分类/分级 → 匹配动作 → 优先级排序
需要我针对某个具体场景(比如客户流失、游戏玩家留存)做一份类似实现吗?