Python NLP - Sklearn - классификатор текста, униграммы и биграммы одинаковые как для негативных, так и для позитивных меток - PullRequest
0 голосов
/ 05 ноября 2019

Я пытаюсь создать классификатор текста, чтобы определить, указывает ли реферат на доступ к исследовательскому проекту по уходу. Я импортирую из набора данных, который имеет два поля: Абстрактный и Accessclass. Аннотация представляет собой описание из 500 слов о проекте, а Accessclass равен 0 для не связанных с доступом и 1 для связанных с доступом. Я все еще на стадии разработки, однако, когда я посмотрел на униграммы и биграммы для меток 0 и 1, они были одинаковыми, несмотря на совершенно разные тона текста. Есть ли что-то, что мне не хватает в моем коде? Например, я случайно дважды добавляю отрицательный или положительный результат? Любая помощь приветствуется.

import pandas as pd
import numpy as np
import nltk
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn import naive_bayes

df = pd.read_excel("accessclasses.xlsx")
df.head()

from io import StringIO
col = ['accessclass', 'abstract']
df = df[col]
df = df[pd.notnull(df['abstract'])]
df.columns = ['accessclass', 'abstract']
df['category_id'] = df['accessclass'].factorize()[0]
category_id_df = df[['accessclass', 'category_id']].drop_duplicates().sort_values('category_id')
category_to_id = dict(category_id_df.values)
id_to_category = dict(category_id_df[['category_id', 'accessclass']].values)
df.head()

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer(sublinear_tf=True, min_df=4, norm='l2', encoding='latin-1', ngram_range=(1, 
2), stop_words='english')
features = tfidf.fit_transform(df.abstract).toarray()
labels = df.category_id
print(features.shape)

from sklearn.feature_selection import chi2
import numpy as np
N = 2
for accessclass, category_id in sorted(category_to_id.items()):
   features_chi2 = chi2(features, labels == category_id)
   indices = np.argsort(features_chi2[0])
   feature_names = np.array(tfidf.get_feature_names())[indices]
   unigrams = [v for v in feature_names if len(v.split(' ')) == 1]
   bigrams = [v for v in feature_names if len(v.split(' ')) == 2]
   print("# '{}':".format(accessclass))
   print("  . Most correlated unigrams:\n. {}".format('\n. '.join(unigrams[-N:])))
   print("  . Most correlated bigrams:\n. {}".format('\n. '.join(bigrams[-N:])))

1 Ответ

1 голос
/ 07 ноября 2019

Я думаю, что проблема в вашем коде заключается в установке min_df с большим числом, таким как 4 в этом небольшом наборе данных. Согласно вашим данным, которые вы разместили, наиболее распространенными словами являются стоп-слова, которые будут удалены после использования TfidfVectorizer. Вот они:

to :  19
and :  11
a :  6
the :  6
are :  6
of :  6
for :  5
is :  4
in :  4
will :  4
access :  4
I :  4
times :  4
healthcare :  3
more :  3
have :  3
with :  3
...

А это униграмма ... Количество биграмм будет намного ниже.

Вы можете решить это одним из следующих двух вариантов:

  • Установка аргумента stopwords на None примерно так stopwords=None
  • Установка значения min_df ниже 4, например, 1 или 2.

Я рекомендую использовать второй вариант, так как первый вернет стоп-слова как коррелированные, что совсем не полезно. Я пытался использовать min_df=1 и вот результат:

  . Most correlated unigrams:
. times
. access

  . Most correlated bigrams:
. enjoyed watching
. wait times
...