Python案例:如何分配不同场景的权重
权重分配是数据分析、机器学习和业务决策中的核心问题,下面我用多个实际案例来演示不同场景下的权重分配方法。

多指标综合评价(熵权法 + AHP)
适用场景:绩效考核、供应商评估、城市排名等需要综合多个指标的场景。
import numpy as np
import pandas as pd
# 模拟数据:5个候选方案,4个指标
data = pd.DataFrame({
'质量': [90, 85, 78, 92, 88],
'成本': [70, 80, 75, 65, 85], # 越高越好(已转换)
'交付速度': [60, 90, 70, 85, 75],
'服务': [85, 70, 88, 75, 80]
})
# ========== 方法1:熵权法(客观权重)==========
def entropy_weight(df):
# 归一化
norm = df / df.sum(axis=0)
# 计算熵值
k = 1.0 / np.log(len(df))
entropy = -k * (norm * np.log(norm + 1e-12)).sum(axis=0)
# 计算权重
d = 1 - entropy
weights = d / d.sum()
return weights
w_entropy = entropy_weight(data)
print("熵权法权重:\n", w_entropy)
# ========== 方法2:AHP层次分析法(主观权重)==========
# 判断矩阵(1-9标度,对角线为1,a[i][j] = 1/a[j][i])
A = np.array([
[1, 1/3, 2, 1/2],
[3, 1, 4, 2 ],
[1/2, 1/4, 1, 1/3],
[2, 1/2, 3, 1 ]
])
def ahp_weight(A):
eigvals, eigvecs = np.linalg.eig(A)
idx = np.argmax(eigvals.real)
w = eigvecs[:, idx].real
w = w / w.sum()
# 一致性检验
CI = (eigvals[idx].real - len(A)) / (len(A) - 1)
RI = {1:0, 2:0, 3:0.58, 4:0.90, 5:1.12, 6:1.24}[len(A)]
CR = CI / RI if RI else 0
print(f"CR = {CR:.3f} ({'通过' if CR < 0.1 else '未通过'})")
return w
w_ahp = ahp_weight(A)
print("AHP权重:\n", w_ahp)
# ========== 方法3:组合权重(乘法合成)==========
w_combined = np.sqrt(w_entropy * w_ahp)
w_combined = w_combined / w_combined.sum()
print("组合权重:\n", w_combined)
# 综合评分
scores = (data * w_combined).sum(axis=1)
print("\n综合得分:\n", scores.sort_values(ascending=False))
多场景推荐系统(场景加权融合)
适用场景:电商推荐、内容推荐中,用户在不同场景(首页、搜索、详情页)行为权重不同。
import numpy as np
# 用户在不同场景下的商品偏好分数
scenario_scores = {
'首页推荐': np.array([0.8, 0.3, 0.6, 0.9, 0.2]),
'搜索结果': np.array([0.5, 0.9, 0.4, 0.3, 0.8]),
'详情页': np.array([0.2, 0.4, 0.9, 0.5, 0.6]),
'购物车': np.array([0.9, 0.2, 0.3, 0.8, 0.4]),
}
# ========== 动态权重:根据场景置信度分配 ==========
# 搜索意图最明确,权重最高;首页最泛,权重最低
base_weights = {
'首页推荐': 0.15,
'搜索结果': 0.40, # 意图明确
'详情页': 0.25,
'购物车': 0.20,
}
# ========== 场景权重归一化函数 ==========
def normalize_weights(w_dict):
total = sum(w_dict.values())
return {k: v / total for k, v in w_dict.items()}
weights = normalize_weights(base_weights)
# 加权融合
final_scores = sum(weights[s] * scenario_scores[s] for s in scenario_scores)
print("场景权重:", weights)
print("最终推荐分数:", final_scores.round(3))
# 排序推荐
items = [f'商品{i}' for i in range(5)]
ranking = sorted(zip(items, final_scores), key=lambda x: -x[1])
print("\n推荐排名:")
for rank, (item, score) in enumerate(ranking, 1):
print(f" {rank}. {item}: {score:.3f}")
时间衰减权重(用户行为分析)
适用场景:用户兴趣建模、RFM模型、近期行为权重更高。
import pandas as pd
from datetime import datetime, timedelta
# 模拟用户购买记录
data = pd.DataFrame({
'user': ['A', 'A', 'A', 'B', 'B', 'A'],
'amount': [100, 200, 50, 300, 150, 80],
'date': pd.to_datetime([
'2024-01-01', '2024-03-15', '2024-05-20',
'2024-02-10', '2024-06-01', '2024-06-10'
])
})
# ========== 时间衰减权重(指数衰减)==========
def time_decay_weight(dates, half_life_days=30, ref_date=None):
"""半衰期越短,近期行为权重越大"""
if ref_date is None:
ref_date = dates.max()
days_diff = (ref_date - dates).dt.days
return 0.5 ** (days_diff / half_life_days)
data['weight'] = time_decay_weight(data['date'])
data['weighted_amount'] = data['amount'] * data['weight']
print(data.to_string(index=False))
# 用户加权总价值
user_value = data.groupby('user')['weighted_amount'].sum()
print("\n用户加权价值:\n", user_value.round(2))
业务规则权重(多目标权衡)
适用场景:风控评分、广告竞价、搜索排序中多因子加权。
import numpy as np
def risk_score(features):
"""风控场景:多因子加权评分"""
# 权重根据业务经验设定
weights = {
'历史逾期次数': 0.30,
'当前负债率': 0.25,
'收入稳定性': 0.20,
'征信查询次数': 0.15,
'年龄': 0.10,
}
# 各因子归一化到 [0,1]
normalized = {
'历史逾期次数': min(features['历史逾期次数'] / 5, 1),
'当前负债率': features['当前负债率'],
'收入稳定性': 1 - features['收入稳定性'], # 反向
'征信查询次数': min(features['征信查询次数'] / 10, 1),
'年龄': abs(features['年龄'] - 35) / 35, # 偏离35岁风险高
}
score = sum(weights[k] * normalized[k] for k in weights)
return round(score, 3)
# 测试
user1 = {'历史逾期次数': 1, '当前负债率': 0.3, '收入稳定性': 0.8,
'征信查询次数': 3, '年龄': 35}
user2 = {'历史逾期次数': 4, '当前负债率': 0.7, '收入稳定性': 0.3,
'征信查询次数': 8, '年龄': 22}
print(f"用户1风险分: {risk_score(user1)}")
print(f"用户2风险分: {risk_score(user2)}")
机器学习中的样本权重
适用场景:类别不平衡、样本重要性不同的监督学习。
from sklearn.utils.class_weight import compute_class_weight
import numpy as np
# ========== 方法1:类别平衡权重 ==========
y = np.array([0]*950 + [1]*50) # 9.5:0.5 不平衡
class_weights = compute_class_weight('balanced', classes=np.unique(y), y=y)
print("类别权重:", dict(zip(np.unique(y), class_weights)))
# ========== 方法2:样本级权重(重要性采样)==========
def compute_sample_weights(y, alpha=0.5):
"""稀有类别获得更高权重"""
unique, counts = np.unique(y, return_counts=True)
class_w = {u: (1/c)**alpha for u, c in zip(unique, counts)}
return np.array([class_w[label] for label in y])
sample_weights = compute_sample_weights(y)
print(f"正样本平均权重: {sample_weights[y==1].mean():.2f}")
print(f"负样本平均权重: {sample_weights[y==0].mean():.2f}")
# 使用示例
# model.fit(X, y, sample_weight=sample_weights)
多场景 A/B 测试流量分配
适用场景:多实验并行时的流量权重分配。
import random
# 实验权重配置
experiments = {
'baseline': 0.50, # 对照组
'exp_v1': 0.20, # 新版本
'exp_new_ui':0.20, # 新UI
'exp_model': 0.10, # 新模型(小流量试探)
}
# 验证权重合计
assert abs(sum(experiments.values()) - 1.0) < 1e-9
def assign_experiment(user_id, exp_config):
"""基于用户ID哈希的稳定分配(同一用户始终分到同一组)"""
# 用hash保证可复现
h = hash(str(user_id)) % 10000 / 10000.0
cumsum = 0
for name, weight in exp_config.items():
cumsum += weight
if h < cumsum:
return name
return list(exp_config.keys())[-1]
# 测试
results = {}
for uid in range(10000):
exp = assign_experiment(uid, experiments)
results[exp] = results.get(exp, 0) + 1
print("实际分配比例:")
for k, v in results.items():
print(f" {k}: {v/10000:.3f} (目标 {experiments[k]})")
权重分配方法总结
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 等权重 | 无先验信息 | 简单、无偏 | 忽略重要性差异 |
| 熵权法 | 客观评价 | 数据驱动、无主观性 | 忽略业务意义 |
| AHP | 专家经验可得 | 融合主观判断 | 需一致性检验 |
| 组合权重 | 稳定性要求高 | 兼顾主客观 | 计算略复杂 |
| 时间衰减 | 用户行为分析 | 反映时效性 | 需调半衰期 |
| 类别平衡 | 类别不平衡 | 改善模型偏向 | 可能过拟合少数类 |
| 业务规则 | 有明确业务逻辑 | 可解释性强 | 依赖经验 |
选择建议:
- 无数据无经验 → 等权重
- 只有数据 → 熵权法
- 只有专家 → AHP / Delphi
- 两者都有 → 组合权重(推荐)
- 时间敏感 → 指数衰减
- 监督学习 → sample_weight
要不要我针对某个具体场景(比如推荐系统、风控、绩效考核)展开更详细的代码示例?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播