1

我正在为一个班级做一些关于性别分类的工作。我一直在使用 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
4

1 回答 1

6

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

不过不要指望奇迹,因为 300 个样本对于训练集来说非常小(尽管对于二元分类,它可能足以击败“最频繁”的基线)。YMMV。

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

于 2013-04-26T16:22:09.810 回答