Python中的NLP:矢量化后从SelectKBest获取单词名称

时间:2018-09-28 18:59:00

标签: python nlp vectorization

我似乎找不到确切问题的答案。有人可以帮忙吗?

我的数据框(“ df”)的简化描述:它有2列:一列是一堆文本(“ Notes”),另一列是一个二进制变量,指示解析时间是否高于平均水平( “ y”)。

我在文字上用了字眼:

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(lowercase=True, stop_words="english")
matrix = vectorizer.fit_transform(df["Notes"])

我的矩阵是6290 x4650。获取单词名称(即功能名称)没问题:

feature_names = vectorizer.get_feature_names()
feature_names

接下来,我想知道这4650中的哪一个与高于平均分辨率时间最相关;并减少我可能要在预测模型中使用的矩阵。我进行了卡方检验,以找出前20个最重要的单词。

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
selector = SelectKBest(chi2, k=20)
selector.fit(matrix, y)
top_words = selector.get_support().nonzero()

# Pick only the most informative columns in the data.
chi_matrix = matrix[:,top_words[0]]

现在,我被卡住了。我如何从这个简化的矩阵(“ chi_matrix”)中得到单词?我的功能名称是什么?我正在尝试:

chi_matrix.feature_names[selector.get_support(indices=True)].tolist()

chi_matrix.feature_names[features.get_support()]

这些给我一个错误:找不到feature_names。我想念什么?

A

2 个答案:

答案 0 :(得分:1)

在弄清了我真正想做的事之后(感谢Daniel)并进行了更多的研究,我找到了实现我的目标的其他几种方法。

方法1-https://glowingpython.blogspot.com/2014/02/terms-selection-with-chi-square.html

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(lowercase=True,stop_words='english')
X = vectorizer.fit_transform(df["Notes"])

from sklearn.feature_selection import chi2
chi2score = chi2(X,df['AboveAverage'])[0]

wscores = zip(vectorizer.get_feature_names(),chi2score)
wchi2 = sorted(wscores,key=lambda x:x[1]) 
topchi2 = zip(*wchi2[-20:])
show=list(topchi2)
show

方法2-这是我使用的方法,因为它是我最容易理解的方法,并产生了一个不错的输出,其中列出了单词,chi2得分和p值。此处的另一个主题:Sklearn Chi2 For Feature Selection

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_selection import SelectKBest, chi2

vectorizer = CountVectorizer(lowercase=True,stop_words='english')
X = vectorizer.fit_transform(df["Notes"])

y = df['AboveAverage']

# Select 10 features with highest chi-squared statistics
chi2_selector = SelectKBest(chi2, k=10)
chi2_selector.fit(X, y)

# Look at scores returned from the selector for each feature
chi2_scores = pd.DataFrame(list(zip(vectorizer.get_feature_names(), chi2_selector.scores_, chi2_selector.pvalues_)), 
                                       columns=['ftr', 'score', 'pval'])
chi2_scores

答案 1 :(得分:0)

我最近有一个类似的问题,但是我并没有被限制使用20个最相关的词。相反,我可以选择单词chi得分高于设定阈值的单词。我将为您提供用于完成第二个任务的方法。之所以能做到这一点,而不是仅仅将前n个单词用于其chi分数,是更可取的,原因是这20个单词的得分可能非常低,因此几乎对分类任务毫无贡献。

这是我完成二进制分类任务的方式:

    import pandas as pd
    import numpy as np
    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.feature_selection import chi2

    THRESHOLD_CHI = 5 # or whatever you like. You may try with
     # for threshold_chi in [1,2,3,4,5,6,7,8,9,10] if you prefer
     # and measure the f1 scores

    X = df['text']
    y = df['labels']

    cv = CountVectorizer()
    cv_sparse_matrix = cv.fit_transform(X)
    cv_dense_matrix = cv_sparse_matrix.todense()

    chi2_stat, pval = chi2(cv_dense_matrix, y)

    chi2_reshaped = chi2_stat.reshape(1,-1)
    which_ones_to_keep = chi2_reshaped > THRESHOLD_CHI
    which_ones_to_keep = np.repeat(which_ones_to_keep ,axis=0,repeats=which_ones_to_keep.shape[1])

结果是一个矩阵,其中包含一项,其中项的chi得分高于阈值,而零则在其中chi得分低于阈值。然后,该矩阵可以是np.dot或cv矩阵或tfidf矩阵,然后传递给分类器的fit方法。

如果执行此操作,则矩阵which_ones_to_keep的列与CountVectorizer对象的列相对应,因此可以通过比较非零来确定哪些术语与给定标签相关which_ones_to_keep矩阵的各列到.get_feature_names()的索引,或者您可以忘记它,然后将其直接传递给分类器。