用于文本分类的朴素贝叶斯 - Python 2.7 数据结构问题
Naive Bayes for Text Classification - Python 2.7 Data Structure Issue
我在训练朴素贝叶斯分类器时遇到问题。我有一个我想使用的功能集和目标,但我不断收到错误。我看过其他有类似问题的人,但我似乎无法弄清楚这个问题。我确定有一个简单的解决方案,但我还没有找到它。
这是我试图用来训练分类器的数据结构示例。
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]
文档[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]
你把火车设置错了。正如@lenz 在评论中所说,删除特征字典值中的括号并仅使用单个值。
如 official documentation 中所示:
labeled_featuresets – A list of (featureset, label) where each
featureset is a dict mapping strings to either numbers, booleans or
strings.
但是您将映射(字典中键的值)设置为列表。
你正确的火车应该是这样的:
[({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 和 Lenz 的帮助,他们向我解释了这个问题,我能够重新组织我的训练集,幸运的是它现在可以工作了。谢谢大家!
这个问题在 Vivek 的 post 中得到了很好的解释。这是将火车数据重组为正确格式的代码。
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))
我在训练朴素贝叶斯分类器时遇到问题。我有一个我想使用的功能集和目标,但我不断收到错误。我看过其他有类似问题的人,但我似乎无法弄清楚这个问题。我确定有一个简单的解决方案,但我还没有找到它。
这是我试图用来训练分类器的数据结构示例。
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]
文档[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]
你把火车设置错了。正如@lenz 在评论中所说,删除特征字典值中的括号并仅使用单个值。
如 official documentation 中所示:
labeled_featuresets – A list of (featureset, label) where each featureset is a dict mapping strings to either numbers, booleans or strings.
但是您将映射(字典中键的值)设置为列表。
你正确的火车应该是这样的:
[({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 和 Lenz 的帮助,他们向我解释了这个问题,我能够重新组织我的训练集,幸运的是它现在可以工作了。谢谢大家!
这个问题在 Vivek 的 post 中得到了很好的解释。这是将火车数据重组为正确格式的代码。
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))