如何从sklearn TruncatedSVD对象中获取特征名称?

5
我有以下代码:
import pandas as pd
import numpy as np
from sklearn.decomposition import TruncatedSVD
df = df = pd.DataFrame(np.random.randn(1000, 25), index=dates, columns=list('ABCDEFGHIJKLMOPQRSTUVWXYZ'))

def reduce(dim):
    svd = sklearn.decomposition.TruncatedSVD(n_components=dim, n_iter=7, random_state=42)
    return svd.fit(df)

fitted = reduce(5)

如何从fitted中获取列名?


1
SVD和PCA不会从现有的列中选择列。它们使用所有可用的列将数据转换为新的维度。因此,从已拟合的列中获取列是没有意义的。 - Vivek Kumar
经过一些研究,我意识到自己的想法是多么的错误。我在stats.exchange上提出了另一个问题链接,如果您有时间,请考虑回答。@VivekKumar - m.awad
2个回答

7

继续Mikhail的帖子。

假设您已经从vectorizer.get_feature_names()获得了feature_names,并在此之后调用了svd.fit(X)

现在,您可以使用以下代码提取排序后的最佳特征名称:

best_fearures = [feature_names[i] for i in svd.components_[0].argsort()[::-1]]

上述代码尝试返回降序排列的 svd.components_[0] 参数,并从 feature_names(所有特征)中查找相对索引并构建 best_features 数组。然后,您可以看到例如前10个最佳功能:
In[21]: best_features[:10]

Out[21]: 
['manag',
 'develop',
 'busi',
 'solut',
 'initi',
 'enterprise',
 'project',
 'program',
 'process',
 'plan']

5
列名将是SVD维度。
每个维度都是输入特征的线性组合。为了理解特定维度的含义,请查看svd.components_数组 - 它包含一个系数矩阵,输入特征被乘以其上。
您的原始示例略有更改:
import pandas as pd
import numpy as np
from sklearn.decomposition import TruncatedSVD

feature_names = list('ABCDEF')
df = pd.DataFrame(
    np.random.randn(1000, len(feature_names)), 
    columns=feature_names
)

def reduce(dim):
    svd = TruncatedSVD(n_components=dim, n_iter=7, random_state=42)
    return svd.fit(df)

svd = reduce(3)

然后你可以像这样做,以获得更易读的SVD维度名称 - 让我们计算第0个维度的名称:

" ".join([
    "%+0.3f*%s" % (coef, feat) 
    for coef, feat in zip(svd.components_[0], feature_names)
])

它显示了一个名为“特征名称”的内容,您可以在这种情况下使用该内容作为第0个SVD维度:+0.170*A -0.564*B -0.118*C +0.367*D +0.528*E +0.475*F(当然,系数取决于数据,因此特征名称也取决于数据)。

如果您有许多输入维度,您可以通过权衡一些“精度”来增加可解释性,例如按系数排序并仅使用其中的几个顶部。更详细的示例可以在https://github.com/TeamHG-Memex/eli5/pull/208中找到(免责声明:我是eli5维护者之一;拉取请求不是由我提交的)。


我理解的是,新名称告诉我如何从旧维度构建新维度,我理解正确吗? - m.awad
谢谢你的帮助,我还在stats.exchange上提出了更详细的问题链接,如果你有时间,请考虑回答,再次感谢。 - m.awad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接