one-class svm通过仅学习正常数据的边界来识别异常。步骤包括:1. 生成正常与异常模拟数据并标准化;2. 使用oneclasssvm模型训练,设置nu和kernel参数;3. 对数据进行预测并计算决策分数;4. 可视化结果并评估模型性能。适用场景如质量控制、网络入侵检测等,调参时nu控制异常比例,gamma影响边界复杂度,评估依赖专家判断或少量标签。

用Python实现基于One-Class SVM的异常检测,核心在于利用
scikit-learn
OneClassSVM

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import OneClassSVM
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_blobs
# 1. 生成模拟数据:正常数据和少量异常数据
# 模拟正常数据(一个紧密的集群)
X_normal, _ = make_blobs(n_samples=300, centers=[[0, 0]], cluster_std=0.5, random_state=42)
# 模拟异常数据(远离正常集群的点)
X_outliers, _ = make_blobs(n_samples=30, centers=[[3, 3], [-2, -2]], cluster_std=0.8, random_state=42)
# 将正常数据和异常数据合并,但训练时只用“正常”数据
X_combined = np.vstack([X_normal, X_outliers])
# 为了One-Class SVM更好地工作,通常需要对数据进行标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_combined)
# 2. 初始化并训练One-Class SVM模型
# nu: 控制异常值比例的参数,这里假设我们期望有0.05(5%)的异常值。
# kernel: 'rbf'是径向基函数核,适合处理非线性边界。
# gamma: rbf核的参数,控制单个训练样本的影响范围。'auto'会使用1 / n_features。
model = OneClassSVM(nu=0.05, kernel="rbf", gamma='auto')
# 注意:One-Class SVM通常只在“正常”数据上进行训练
# 这里我们用X_normal_scaled来训练,模拟只有正常数据可用的情况
X_normal_scaled = scaler.fit_transform(X_normal)
model.fit(X_normal_scaled)
# 3. 对所有数据进行预测
# decision_function返回每个样本到超平面的有符号距离
# 距离越小(负值越大),越可能是异常
y_pred = model.predict(X_scaled)
scores = model.decision_function(X_scaled)
# 4. 结果可视化
# 识别出被模型标记为异常的点(y_pred = -1)
# 正常点(y_pred = 1)
anomalies = X_combined[y_pred == -1]
normals = X_combined[y_pred == 1]
plt.figure(figsize=(10, 7))
plt.scatter(normals[:, 0], normals[:, 1], c='blue', marker='o', s=50, label='正常数据 (模型判断)')
plt.scatter(anomalies[:, 0], anomalies[:, 1], c='red', marker='x', s=100, label='异常数据 (模型判断)')
plt.title('One-Class SVM 异常检测结果')
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.legend()
plt.grid(True)
plt.show()
print(f"模型识别出的异常点数量: {np.sum(y_pred == -1)}")
print(f"模型识别出的正常点数量: {np.sum(y_pred == 1)}")One-Class SVM,顾名思义,它只关注一类数据——我们认为是“正常”的数据。它的核心思想是在一个高维特征空间中,找到一个最优的超平面,将所有正常数据点尽可能地包含在一个区域内,同时将这个区域与原点(或数据转换后的原点)分开。简单来说,它学习的是正常数据的“轮廓”或“边界”,任何落在边界之外的点,或者说,在边界内部但离边界很近的点,都有可能被标记为异常。
这和我们熟悉的二分类SVM有本质区别。二分类SVM需要正负两类样本来划定一个决策边界,将它们分开。而One-Class SVM通常在只有“正常”样本的情况下训练,它不需要知道异常样本长什么样。这使得它在很多实际场景中非常有用,比如:
立即学习“Python免费学习笔记(深入)”;

它的优势在于能够处理高维数据,并且通过核函数(如RBF)可以捕捉非线性的复杂边界。但它也有其局限性,比如对参数
nu
gamma
One-Class SVM的性能很大程度上取决于其核心参数的设置,尤其是
nu
gamma

nu
nu
nu
kernel
rbf
rbf
linear
poly
sigmoid
rbf
gamma
rbf
poly
sigmoid
gamma
gamma
gamma
gamma
nu
'auto'
'scale'
scikit-learn
调优技巧:
StandardScaler
nu
评估One-Class SVM模型性能是一个挑战,因为我们通常没有大量的真实异常标签。这不像传统的监督学习,可以直接计算准确率、精确率、召回率等指标。但我们仍然有几种方法来“摸索”模型的表现:
1. 当存在少量已知异常样本时(最理想的情况): 如果你的数据集中,即使训练时没有用到,但在测试或验证阶段能获取到一部分真实异常样本的标签,那么评估就变得相对容易。
TP / (TP + FP)
TP / (TP + FN)
decision_function
2. 当完全没有已知异常样本时(更常见的情况): 这才是One-Class SVM的真正用武之地,但评估也更棘手。
nu
gamma
总的来说,评估One-Class SVM更像是一门艺术,而不是纯粹的科学。它往往需要结合量化指标(如果可能)、领域知识、人工审查以及对数据分布的直观理解。最终目标是构建一个能够有效帮助我们发现潜在问题的工具,而不是一个在所有指标上都“完美”的模型。
以上就是如何用Python实现基于SVM的异常检测?单类分类器的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号