Python NLP - Sklearn - 文本分类器,负标签和正标签的一元字母和二元字母相同
Python NLP - Sklearn - text classifier, unigrams and bigrams the same for both negative and positive labels
我正在尝试创建一个文本分类器来确定摘要是否表示访问护理研究项目。我正在从具有两个字段的数据集导入:Abstract 和 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:])))
我认为您的代码中的问题是在这个小数据集上使用 4
这样的大数字设置 min_df
。根据您发布的数据,最常见的词是停用词,使用 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
...
这些是 unigram...bigram 的数量会少很多。
您可以通过以下两个选项之一解决该问题:
- 像这样将
stopwords
参数设置为 None
stopwords=None
- 将
min_df
设置为低于 4
,例如 1
或 2
。
我建议使用第二个选项,因为第一个选项会 return 停用词相关,这根本没有帮助。我试过使用 min_df=1
结果如下:
. Most correlated unigrams:
. times
. access
. Most correlated bigrams:
. enjoyed watching
. wait times
我正在尝试创建一个文本分类器来确定摘要是否表示访问护理研究项目。我正在从具有两个字段的数据集导入:Abstract 和 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:])))
我认为您的代码中的问题是在这个小数据集上使用 4
这样的大数字设置 min_df
。根据您发布的数据,最常见的词是停用词,使用 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
...
这些是 unigram...bigram 的数量会少很多。
您可以通过以下两个选项之一解决该问题:
- 像这样将
stopwords
参数设置为None
stopwords=None
- 将
min_df
设置为低于4
,例如1
或2
。
我建议使用第二个选项,因为第一个选项会 return 停用词相关,这根本没有帮助。我试过使用 min_df=1
结果如下:
. Most correlated unigrams:
. times
. access
. Most correlated bigrams:
. enjoyed watching
. wait times