为什么 SVM 难以在垃圾中找到好的特征?

机器算法验证 支持向量机
2022-04-12 21:20:17

我正在研究一个具有许多功能的小型数据集,其中大多数只是垃圾。目标是在这个二元分类任务上具有良好的分类精度。

因此,我编写了一个小示例代码来说明问题。该代码简单地创建了一个二进制数据集,其中包含许多随机特征和一个用于类标签 1 的有用特征。然后我通过线性 SVM 执行简单的模型选择。问题是分类精度很差,甚至是随机的。(我也尝试了一个 StratifiedKFold 结果相同)

那么,为什么 SVM 很难找到好的模式呢?这也可能是样本数量减少的问题,但我无法增加数据集。

PS我想在没有特征选择的情况下解决问题(如果存在解决方案)

import numpy as np
from sklearn.utils import shuffle
from sklearn import preprocessing
from sklearn.svm import SVC
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import StratifiedShuffleSplit

# dataset
N = 10
X1 = np.random.rand(N,500)
X2 = np.random.rand(N,500)
X2[:,100] = 1
data = np.concatenate((X1,X2), axis=0)
labels = np.concatenate((np.zeros(N),np.ones(N)))

# shuffle and normalization
data, labels = shuffle(data, labels)
scaler = preprocessing.StandardScaler().fit(data)                                      
data_n = scaler.transform(data)

# CV
sss = StratifiedShuffleSplit(labels, n_iter=100, test_size=0.4, random_state=0)
clf = GridSearchCV(SVC(kernel='linear'), {'C': np.logspace(-4,2,100)}, cv=sss)
clf.fit(data_n, labels)
for params, mean_score, scores in clf.grid_scores_:
    print("%0.3f (+/-%0.03f) for %r" % (mean_score, scores.std() * 2, params))

谢谢。

1个回答

TL;DR:垃圾进,垃圾出。选择更好的特征将促进更好的模型。(有时答案真的很简单!)接下来是对在拟合 SVM 的上下文中选择更高质量特征的一条路径的描述。

当呈现许多垃圾特征时,SVM 性能可能会受到影响,因为该模型仅通过核函数处理数据,而不是像更传统的回归分析那样直接处理特征。我将通过与标准线性核和所谓的“自动相关性确定”方法的比较来说明。

标准的线性核函数是K1(x,x)=xTx.所有特征都有助于输出K1:首先我们计算元素乘积,然后对乘积求和。没有步骤可以评估哪些组件x比其他人更有用。

如果我们愿意,我们可以包括一个标量因子γ屈服K2(x,x)=xTγx,但一个标量γ只是具有重新缩放的效果C, 所以在(γ,C)空间。

但是如果我们更换γ对角线对称半正定 (SPSD)Γ, 我们有K3(x,x)=xTΓx.我们可以认为这是为每个条目估计一个系数x,即每个特征。我们可以解释对角元素Γ更接近于零对分类输出的贡献相对较小,而绝对值较大的对角元素对输出的贡献更大。一方面,对于d功能,你现在有d+1调整参数(每个元素ΓC),但另一方面,您可以将所有功能直接提交给 SVM。

这个过程可以进一步推广到非对角线,但仍然是 SPSD,Γ承认特征之间的非零相关性。这将产生d(d+1)2+1调整参数,这很快变得没有吸引力,因为d成长。

最后,这种 ARD 方法可以扩展到其他内核。RBF 核通过平方欧几里得距离变化,所以我们可以写K4=exp((xx)TΓ(xx)σ),并且通常将任何平方欧几里得距离替换为(X-X')Γ(X-X').

PS我想在没有特征选择的情况下解决问题(如果存在解决方案)

所以......你想找到一个具有高预测价值的特征子集,但你不想做“特征选择”?也许我很密集,但听起来你所追求的是一个矛盾的术语。我想一个可接受的解决方案对你来说是什么样的取决于你对“特征选择”的定义有多广泛。