用于文本分类的朴素贝叶斯 - Python 2.7 数据结构问题
Posted
技术标签:
【中文标题】用于文本分类的朴素贝叶斯 - Python 2.7 数据结构问题【英文标题】:Naive Bayes for Text Classification - Python 2.7 Data Structure Issue 【发布时间】:2017-08-28 21:58:30 【问题描述】:我在训练朴素贝叶斯分类器时遇到问题。我有一个我想使用的功能集和目标,但我不断收到错误。我看过其他有类似问题的人,但我似乎无法弄清楚问题所在。我确定有一个简单的解决方案,但我还没有找到。
这是我试图用来训练分类器的数据结构示例。
In [1] >> train[0]
Out[1] (
u'profici': [False],
u'saver': [False],
u'four': [True],
u'protest': [False],
u'asian': [True],
u'upsid': [False],
.
.
.
u'captain': [False],
u'payoff': [False],
u'whose': [False]
,
0)
其中 train[0] 是列表中的第一个元组,包含:
用于指示文档中是否存在单词的特征和布尔值字典[0]
document[0]二分类的目标标签
显然,火车列表的其余部分包含我想要分类的其他文档的特征和标签。
运行以下代码时
from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.naive_bayes import MultinomialNB
MNB_clf = SklearnClassifier(MultinomialNB())
MNB_clf.train(train)
我收到错误消息:
TypeError: float() argument must be a string or a number
编辑:
功能在此处创建。来自包含第 1 列中的帖子和第 2 列中的情绪分类的数据框 post_sent。
stopwords = set(stopwords.words('english'))
tokenized = []
filtered_posts = []
punc_tokenizer = RegexpTokenizer(r'\w+')
# tokenizing and removing stopwords
for post in post_sent.post:
tokenized = [word.lower() for word in.
punc_tokenizer.tokenize(post)]
filtered = ([w for w in tokenized if not w in stopwords])
filtered_posts.append(filtered)
# stemming
tokened_stemmed = []
for post in filtered_posts:
stemmed = []
for w in post:
stemmed.append(PorterStemmer().stem_word(w))
tokened_stemmed.append(stemmed)
#frequency dist
all_words =.
list(itertools.chain.from_iterable(tokened_stemmed))
frequency = FreqDist(all_words)
# Feature selection
word_features = list(frequency.keys())[:3000]
# IMPORTANT PART
#######################
#------ featuresets creation ---------
def find_features(list_of_posts):
features =
wrds = set(post)
for w in word_features:
features[w] = [w in wrds]
return features
# zipping inputs with targets
words_and_sent = zip(tokened_stemmed,
post_sent.sentiment)
# IMPORTANT PART
##########################
# feature sets created here
featuresets = [(find_features(words), sentiment) for
words, sentiment in
words_and_sent]
【问题讨论】:
您的特征字典的值都是具有单个值的列表:[False]
。相反,它们可能应该直接是布尔值True
/False
,而不是包含在列表中。
好的,现在我有一个不同的问题.. ` In [1] >> train[0] out[1] >> ([False, False, True, ... False, ], 0)`这给了我错误AttributeError: 'list' object has no attribute 'iteritems'
【参考方案1】:
你设置错了火车。正如@lenz 在评论中所说,删除特征字典值中的括号并仅使用单个值。
如official documentation:
labeled_featuresets – (特征集、标签)列表,其中每个 featureset 是一个将字符串映射到数字、布尔值或 字符串。
但是您将映射(dict 中键的值)设置为列表。
你正确的火车应该是这样的:
[(u'profici':False,
u'saver':False,
u'four':True,
u'protest':False,
u'asian':True,
u'upsid':False,
.
.
, 0),
..
..
(u'profici':True,
u'saver':False,
u'four':False,
u'protest':False,
u'asian':True,
u'upsid':False,
.
.
, 1)]
您可以在此处查看更多示例: - http://www.nltk.org/howto/classify.html
【讨论】:
谢谢 Vivek,这更清楚了。我对字典数据类型不是特别擅长。关于如何将它从我现在拥有的东西转换为我需要的东西,你有什么建议吗?干杯 @DiarmaidFinnerty 您最初是如何创建功能集的?更新您的答案(或发布新答案)以包含生成您标记的功能集的代码,然后它将直接向您展示如何修复它。 嗨,lenz,我已经添加了创建功能集的代码 嗨维韦克,感谢您的帮助。如果您愿意,可以编辑您的帖子以包含使其正确运行的代码(作为答案发布在下面)。感谢所有帮助!【参考方案2】:感谢 Vivek 和 Lenz 的帮助,他们向我解释了这个问题,我能够重新组织我的训练集,谢天谢地,它现在可以工作了。谢谢大家!
Vivek 的帖子中很好地解释了这个问题。这是将火车数据重新组织成正确格式的代码。
features_targ = []
for feature in range(0,len(featuresets)):
dict_test = featuresets[feature]
values = list(itertools.chain.from_iterable(dict_test[0].values()))
keys = dict_test[0].keys()
target = dict_test[1]
dict_ion =
for key in range(x,len(keys)):
dict_ion[keys[key]] = values[key]
features_targ.append((dict_ion,target))
【讨论】:
以上是关于用于文本分类的朴素贝叶斯 - Python 2.7 数据结构问题的主要内容,如果未能解决你的问题,请参考以下文章