我正在为一个班级做一些性别分类的工作。我一直在使用SVMLight,结果不错,但我也想在我的数据上尝试一些贝叶斯方法。我的数据集由文本数据组成,并且我已经进行了特征缩减,将特征空间缩减到一些贝叶斯方法更合理的大小。所有实例都通过tf-idf运行,然后进行规范化(通过我自己的代码)。
我抓住了sklearn工具包,因为它很容易与我当前的代码库集成,但是我从GaussianNB得到的结果都是一个类(在这种情况下是-1),预测的概率都是[nan]。
我已经粘贴了一些相关代码;我不知道这是否足够继续,但我希望我只是在使用sklearn api时忽略了一些明显的东西。我有几个不同的功能集,我试着通过它,也有相同的结果。使用训练集和交叉验证也是一样。任何想法吗?会不会是我的特征空间太过稀疏而无法实现?我有300多个实例,其中大多数都有几百个非零特征。
class GNBLearner(BaseLearner):
def __init__(self, featureCount):
self.gnb = GaussianNB()
self.featureCount = featureCount
def train(self, instances, params):
X = np.zeros( (len(instances), self.featureCount) )
Y = [0]*len(instances)
for i, inst in enumerate(instances):
for idx,val in inst.data:
X[i,idx-1] = val
Y[i] = inst.c
self.gnb.fit(X, Y)
def test(self, instances, params):
X = np.zeros( (len(instances), self.featureCount) )
for i, inst in enumerate(instances):
for idx,val in inst.data:
X[i,idx-1] = val
return self.gnb.predict(X)
def conf_mtx(self, res, test_set):
conf = [[0,0],[0,0]]
for r, x in xzip(res, test_set):
print "pred: %d, act: %d" % (r, x.c)
conf[(x.c+1)/2][(r+1)/2] += 1
return conf
GaussianNB
根本不适合文档分类,因为tf-idf值是非负频率;用MultinomialNB
代替,或者用BernoulliNB
。scikit-learn附带了一个文档分类示例,顺便说一下,该示例使用内置的TfidfTransformer
来使用tf-idf加权。
全面披露:我是scikit-learn核心开发人员之一,也是当前MultinomialNB
和BernoulliNB
代码的主要作者。