用Python识别"战术被摸透"的风险
"战术被摸透"本质是你的行为模式被对手建模预测,在量化交易、游戏AI、电商定价等场景都常见,下面给出一套可落地的Python检测框架。

核心思路
风险信号来自三个维度:
- 可预测性:历史行为能否被模型高精度预测
- 对手适应速度:对手策略是否在针对你调整
- 收益衰减:近期策略效果是否系统性下降
可预测性检测(最关键)
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import accuracy_score
def predictability_score(actions, features, n_splits=5):
"""
actions: 你的历史动作序列 (如 0=进攻,1=防守,2=撤退)
features: 当时的可观测状态特征
返回: 交叉验证准确率, 越接近1越危险(越容易被预测)
"""
tscv = TimeSeriesSplit(n_splits=n_splits)
accs = []
for train_idx, test_idx in tscv.split(features):
clf = RandomForestClassifier(n_estimators=100, max_depth=5)
clf.fit(features[train_idx], actions[train_idx])
pred = clf.predict(features[test_idx])
accs.append(accuracy_score(actions[test_idx], pred))
return np.mean(accs), np.std(accs)
# 判读基准
# <0.4 安全 0.4-0.6 观察 >0.6 高风险
原理:如果对手能用同样的状态特征高精度预测你的下一步动作,说明你的策略存在强模式。
动作分布偏移检测(对手在适应你)
from scipy.stats import entropy
def action_entropy_shift(actions, window=50):
"""检测动作分布是否被压缩(对手逼你进入固定应对)"""
entropies = []
for i in range(window, len(actions)):
seg = actions[i-window:i]
p = np.bincount(seg).astype(float) / len(seg)
p = p[p > 0]
entropies.append(entropy(p))
return np.array(entropies)
# 熵持续下降 = 你的选择被压缩 = 被针对的信号
收益衰减 + 对手反应速度
def detect_adaptation(rounds, my_rewards, opponent_rewards, window=20):
"""
检测对手是否在系统性利用你:
- 你的收益漂移为负
- 对手收益与你的历史动作显著相关
"""
my_drift = np.mean(my_rewards[-window:]) - np.mean(my_rewards[-2*window:-window])
opp_gain = np.mean(opponent_rewards[-window:]) - np.mean(opponent_rewards[-2*window:-window])
# 对手收益与你上一轮动作的相关系数
if len(my_rewards) > 2:
corr = np.corrcoef(my_rewards[:-1], opponent_rewards[1:])[0, 1]
else:
corr = 0.0
risk = 0
if my_drift < 0 and opp_gain > 0: risk += 1
if abs(corr) > 0.3: risk += 1 # 对手在"读"你的顺序
return {"my_drift": my_drift, "opp_gain": opp_gain,
"lag_corr": corr, "risk_level": risk}
综合风险打分
def tactic_exposure_report(actions, features, my_rewards, opp_rewards):
acc, std = predictability_score(actions, features)
ent = action_entropy_shift(actions)
ent_trend = np.polyfit(range(len(ent)), ent, 1)[0] # 斜率
adapt = detect_adaptation(range(len(my_rewards)), my_rewards, opp_rewards)
score = 0
score += 40 if acc > 0.6 else 20 if acc > 0.45 else 0
score += 30 if ent_trend < -0.01 else 0
score += adapt["risk_level"] * 15
score = min(score, 100)
return {
"predictability": round(acc, 3),
"entropy_trend": round(ent_trend, 4),
"adaptation": adapt,
"exposure_score": score,
"verdict": "高风险-战术已被摸透" if score >= 60
else "警戒" if score >= 35
else "相对安全"
}
缓解策略(检测之外)
| 方法 | 做法 |
|---|---|
| 随机化 | 在动作选择中加入 ε-greedy 或采样温度 |
| 混合策略 | 用博弈论求混合纳什均衡,而非纯策略 |
| 定期换招 | 监控熵值,跌破阈值自动触发策略轮换 |
| 欺骗信号 | 主动制造假模式诱使对手误判 |
| 对手建模 | 同时训练对手模型,反向利用其预测 |
实战注意事项
- 数据要按时间切分,别用随机CV,否则准确率虚高
- 准确率基准要对比"无信息基线":比如动作3类,随机基线33%,0.5其实已偏高
- 样本量:小于几百轮时结论不稳,用滚动窗口
- 滞后相关只测1步不够,可扫 lag=1..5 找峰值
这套组合能帮你从"感觉被针对"变成"量化判断被针对",如果你告诉我具体场景(交易/游戏/对抗定价),我可以把特征工程和动作空间写得更贴合。