【问题标题】:SVC scikit learn coef_ (n_class * (n_class - 1)/2, n_features) what are the n_features?SVC scikit learn coef_ (n_class * (n_class - 1)/2, n_features) n_features 是什么?
【发布时间】:2021-07-21 13:38:47
【问题描述】:

我目前正在为一个数据帧训练一个 svc,该数据帧有很多列,其中一个列作为目标


df.rename(columns={'Sequence': 'target'}, inplace=True)

cat_pipeline = Pipeline([
    ('imputer', SimpleImputer(fill_value='none', strategy='constant')),
    ('one_hot', OneHotEncoder())])

full_pipeline = ColumnTransformer([
    ('num', StandardScaler(), num),
    ('cat', cat_pipeline, string_col)
])


clf = make_pipeline(StandardScaler(), SVC())


X = df.iloc[:, :-1]
y = df.target
X = full_pipeline.fit_transform(X)
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, train_size=0.80, test_size=0.20, random_state=101)
linear = svm.SVC(kernel='linear', degree=3, C=1).fit(X_train, y_train)

当我输入 linear.coef_ 时, 我得到一个稀疏矩阵,然后将其更改为数据框

c = linear.coef_.tocoo()
matrix = pd.DataFrame({"node1": c.row, "node2": c.col, "poids": c.data})

id node1 node2 poids
0 0 56 -0.010062
1 0 62 -0.000089
2 0 83 0.0090587
7576 14 1030 -0.000089

但我不明白node1和node 2是什么,我搜索了一下,发现根据这个线程:The dimension of dual_coef_ in sklearn. SVC

它应该是 0 类与 1 类等,但我的节点 1 介于 0 和 14 之间,节点 2 介于 0 和 1063 之间。所以我想我有 15 个类(节点 1)和节点 2 是特征,但我只有在这个例子中有 210 列(我没有在所有数据上运行我的程序,我会得到更多列)。那么 1063 node2 是什么,有没有办法找到我每个列的权重? 我已经尝试了很多我在互联网上找到的代码,但他们中的大多数人都认为我的列是我的功能(我发现不起作用的一个例子):

def f_importances(coef, names):
    imp = coef
    imp,names = zip(*sorted(zip(imp,names)))
    plt.barh(range(len(names)), imp, align='center')
    plt.yticks(range(len(names)), names)
    plt.show()

features_names = df.iloc[:, :-1].columns
f_importances(linear.coef_, features_names)

此代码导致ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all() 但无论如何,它看起来不起作用(我试图用 linear.coef_[0]、矩阵和其他一些东西改变 linear.coef_,我成功地消除了错误,但它仍然不起作用)。

非常感谢任何事情,对不起我的英语不好,我不是本地用户。

编辑: 感谢 Ben Reiniger 的回答,我现在知道 OneHotEncoder 将我的列分成不同的列(不知道为什么),以便解释节点 2 中的 1063 列,以便找到我发现的数据框的最重要特征:

clf['full_pipeline'].transformers_[1][1]['one_hot'].get_feature_names(string_col)

哪些列被转换成哪个列,但仅限于对象类型列。 您需要在其中添加字符串列才能拥有 1063 列。

为了得到正确的顺序,我做了一些 panda 操作,最后在我的原始列和我的 svm 中的系数之间建立了链接。

谢谢!

【问题讨论】:

  • 您是否考虑了特征计数中的预处理 (full_pipeline.fit_transform)? X_train是什么形状的?
  • X_train : ' 的稀疏矩阵,具有 4800 个压缩稀疏行格式的存储元素> 但真正困扰我的不是错误,我可以找到一个修复,我找到了另一种方法,但为了知道我所做的是否正确,我想知道什么是“n_features”以及为什么我的形状是这样的。还是谢谢!

标签: python scikit-learn svm


【解决方案1】:

n_features 是指特征的数量,即训练数据集中的列数。在您的情况下,这是在预处理full_pipeline 之后 的列数;大概您的 210 个原始特征中的一些被一次性编码或以其他方式扩展为许多列。

n_classes 确实是目标类的数量,但请注意coef_ 的第一个维度是n_class * (n_class - 1)/2(如您的标题中所示)。您有 6 个类,所以 coef_ 中的 6*(6-1)/2=15 行。这是类对的数量:SVM 会自动执行一对一分类,因此您可以为每对类获得一个线性函数。

为了确定特征的重要性,由于这种一对一的行为,您需要决定如何聚合所有类对中每个特征的系数。 coef 矩阵的按列求和似乎是合理的,但总是有一些关于特征重要性的警告。

您指向有关dual_coef_ 的问题的链接有点引人注意,因为您在这里分析的是原始公式,而不是对偶公式。

最后,在您的 X_train 中只有 25 个示例,当您有更多功能时,可能不适合得出结论。

【讨论】:

  • 哦,好的,谢谢!我没有考虑扩展到很多列,我需要检查它是如何工作的,以便找到我的 210 个原始特征中的每一个的权重!我将尝试 coef 矩阵的总和,并检查人们是否在互联网上这样做。是的,您对 25 个样本是正确的,这只是为了让我的 svm 运行,然后我将放置更多样本。非常感谢您的帮助!
猜你喜欢
  • 2020-08-26
  • 2019-01-07
  • 2015-03-10
  • 2016-08-20
  • 2017-04-26
  • 2021-07-28
  • 2021-08-04
  • 2020-10-01
  • 2018-11-08
相关资源
最近更新 更多