sklearn GaussianNB - 结果不佳,[nan]概率

fla*_*ine 1 python machine-learning bayesian scikit-learn

我正在为一堂课做一些关于性别分类的工作.我一直在使用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
Run Code Online (Sandbox Code Playgroud)

Fre*_*Foo 5

GaussianNB因为tf-idf值是非负频率,所以根本不适合文档分类; 使用MultinomialNB,也许尝试BernoulliNB.scikit-learn带有一个文档分类示例,顺便提一下,使用内置的tf-idf加权TfidfTransformer.

不过,不要指望奇迹,因为300个样本对于训练集而言非常小(尽管对于二进制分类,它可能足以击败"最常见的"基线).因人而异.

完全披露:我是scikit-learn核心开发者之一,也是当前MultinomialNBBernoulliNB代码的主要作者.