SVM分类器最重要特征系数与目标类别无相关性问题问询
问题分析与解决办法
核心问题1:训练任务与代码实现不匹配
你明确要做0和大于0的二分类,但代码直接用原始目标列y = df[target]作为标签,导致SVM默认执行多分类(如果目标列包含多个大于0的类别值)。这会引发两个问题:
- SVM的特征系数是针对多分类场景计算的,此时“最重要特征”的含义和二分类完全不同;
- 散点图用原始目标值
targetRaw,自然会显示所有类别,而非你预期的0/非0二分类结果。
核心问题2:特征缩放的错误操作
代码中对测试集执行scaler.fit_transform(X_test),会重新计算测试集的均值和标准差,属于数据泄露,严重影响模型泛化能力。正确做法是用训练集拟合的scaler来转换测试集。
修正后的代码示例
import pandas as pd import matplotlib.pyplot as plt from sklearn import metrics, svm, preprocessing from sklearn.model_selection import train_test_split # 1. 将原始目标转换为二分类标签:0 vs 非0 df['binary_target'] = df[target].apply(lambda x: 0 if x == 0 else 1) y = df['binary_target'] X = df.drop(columns=[target, 'binary_target']) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42) scaler = preprocessing.StandardScaler() # 2. 正确的特征缩放:仅在训练集拟合,测试集复用同一scaler转换 X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) # 3. 训练线性SVM二分类模型 svc = svm.SVC(kernel='linear') svc.fit(X_train, y_train) y_pred = svc.predict(X_test) print("Testing Accuracy:", metrics.accuracy_score(y_test, y_pred)) coefficients = 15 # 4. 基于二分类模型的特征系数排序 imp, names = zip(*sorted(zip(svc.coef_[0], X.columns.values))) plt.figure(0) plt.xlabel("特征权重") plt.ylabel("输入特征") plt.barh(range(len(names[-coefficients:])), imp[-coefficients:], align='center') plt.yticks(range(len(names[-coefficients:])), names[-coefficients:]) plt.savefig('SVMCoefficientsAttribution.png', bbox_inches='tight', dpi=100) # 5. 使用二分类标签绘制散点图 mostImportantFeature = names[-1] # 取权重最大的特征 correlationRaw = df[mostImportantFeature] targetBinary = df['binary_target'] plt.figure(1) plt.xlabel("二分类目标(0/1)") plt.ylabel(mostImportantFeature) plt.scatter(targetBinary.tolist(), correlationRaw.tolist(), s=4.0) plt.savefig('SVMTargetFeatureCorrelation.png', bbox_inches='tight', dpi=100)
额外建议
- 若要量化二分类标签与连续特征的相关性,可计算点二列相关系数,比散点图更直观;
- 线性SVM的系数大小受特征缩放影响,必须保证训练、测试集的缩放逻辑完全一致。
内容的提问来源于stack exchange,提问作者binaryBigInt
相关产品推荐
相关产品推荐

