НЛП в Python: получить имена слов из SelectKBest после векторизации - PullRequest
0 голосов
/ 28 сентября 2018

Я не могу найти ответ на мою точную проблему.Кто-нибудь может помочь?

Упрощенное описание моего фрейма данных ("df"): он имеет 2 столбца: один представляет собой набор текста ("Примечания"), а другой - двоичную переменную, указывающую, является ли разрешениевремя было выше среднего или нет («у»).

Я сделал много слов в тексте:

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

Моя матрица 6290 x 4650. Нет проблем с получением названий слов (т.е. имен объектов):

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()]

Это дает мне ошибку: имя_функции не найдено.Чего мне не хватает?

A

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

После того, как я действительно понял, что я хотел сделать (спасибо Дэниелу) и провел больше исследований, я нашел еще несколько способов достичь своей цели.

Способ 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 для выбора функций

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
0 голосов
/ 04 октября 2018

У меня недавно была похожая проблема, но я не был вынужден использовать 20 самых важных слов.Скорее, я мог бы выбрать слова, у которых показатель ци был выше установленного порога.Я дам вам метод, который я использовал для решения этой второй задачи.Причина, по которой это предпочтительнее, чем просто использование первых n слов в соответствии с их хи-баллом, заключается в том, что эти 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])

В результате получается матрица, содержащая единицы, в которых термины имеют показатель хи выше порогового значения, и нули, где они имеют показатель хи ниже, чемпорог.Тогда эта матрица может быть np.dot либо с матрицей cv, либо с матрицей tfidf и впоследствии передана методу fit классификатора.

Если вы сделаете это, столбцы матрицы which_ones_to_keepсоответствуют столбцам объекта CountVectorizer, и таким образом вы можете определить, какие термины были релевантными для данных меток, сравнив ненулевые столбцы матрицы which_ones_to_keep с индексами .get_feature_names(), или вы можете простозабудьте об этом и передайте прямо в классификатор.

...