解题思路
先从训练集里分离出所有正常样本和异常样本,再把正常样本按固定随机种子划分为训练集和验证集,异常样本全部放进验证集,仅用于评估,不参与训练。
然后只用正常训练集计算每一维的均值和标准差,完成标准化。若某一维标准差为 0,就把它改成 1,避免除以 0。接着用同一组均值和标准差去变换正常训练集、正常验证集、异常验证集和测试集。
接下来枚举所有 gamma 和 nu,对每组参数训练一个 OneClassSVM。它本质上是单类分类算法,只学习正常样本的分布范围,再通过 decision_function 判断样本更像正常还是异常。
评估时,把正常验证集和异常验证集合并,真实标签设为正常是 0、异常是 1。因为 decision_function 的值越大越偏向正常,所以算 AUC 时使用 −s,算 F1 时直接按阈值 0 判断,s<0 视为异常。
P4670.第2题-SVM异常检测
题目内容
小美是一位算法工程师,她的任务是识别平台上的异常交易订单,以保障用户和商家的资金安全。她计划使用 One−Class SVM 模型来解决这个问题,并设计了一套标准的模型训练、验证和调优流程。请你遵循小美的设计,仅用numpy/pandas/scikit−learn,完成整个流程。
1.数据拆分
- 输入 “train” 中标签 y=0 为正常,y=1 为异常
- 先提取所有正常样本,再固定随机划分
train_test_split(test_size = 0.25,
random_state = 42,
shuffle = True)
得到正常训练集 Xtr、正常验证集 Xval_norm
- 所有异常样本组成 Xval_anom(仅作评估)
2.标准化
- 只用 Xtr 估计 mean / std;若std值为0,将其重置为1。
- 对 Xtr、Xval_norm、Xval_anom、以及最终“test”全部用同一 (x−mean)/std
3.超参网格 — 由输入给定
- gamma_list:正浮点
- nu_list: 0<ν<1
对每对 (γ,ν) 训练 OneClassSVM
OneClassSVM(kernel="rbf", gamma=gamma, nu=nu,
shrinking=False, tol=1e-4, cache_size=200, max_iter=-1)
4.验证评估
- 在 Xval=Xval_norm∪Xval_anom 上,模型 decision_function 输出分值 s
- 以真标签(0=正常,1=异常)计算
- AUC = roc_auc_score
- F1 = f1_score(阈值 = 0,即 One-Class SVM 内部阈值)
5.选最优超参
按下列优先级排序,选择 (γ∗,ν∗):
i. AUC 降序
ii. F1 降序
iii. ν 升序
iv. γ 升序
6. 在整套正常样本(Xtr ∪ Xval_norm)上重训最优模型,然后对“test”样本输出标签(0=normal,1=anomaly)。
输入描述
单行 JSON(示例):
{
"train": [[x11, x12, ..., 0],
[x21, x22, ..., 0],
[x31, x32, ..., 1],
...],
"test": [[t11, t12, ...],
[t21, t22, ...]],
"gamma_list": [0.1, 0.5],
"nu_list": [0.05, 0.1]
}
- |train| ≤ 40, |test| ≤ 10,维度 d ≤ 6,全为实数
- gamma_list、nu_list 长度各 ≥ 2
输出描述
仅一行:
[pred1,pred2,...]
长度 = ∣test∣ 的 JSON整型数组 (0/1),顺序与输入一致,以空格间隔。
补充说明
- 整个流程唯一随机源:train_test_split,固定 random_state=42
- 为确保通过测试用例,仅允许使用numpy/pandas/scikit−learn。
样例1
输入
{"train":[[0,0,0],[-0.1,0.1,0],[0.2,-0.2,0],[5,5,1]],"test":[[0.1,0.0],[5,5]],"gamma_list":[0.05,0.2],"nu_list":[0.05,0.1]}
输出
[0, 1]