sklearn GaussianNB - плохие результаты, [нан] вероятности

Я делаю некоторую работу по классификации пола для класса. Я использовал 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

person flatline    schedule 26.04.2013    source источник
comment
Это действительно сложно сказать, не увидев данных или хотя бы их выборки. Однако первый вопрос: вы уверены, что GaussianNB подходит? Являются ли ваши характеристики (примерно) гауссианами, то есть нормально распределенными?   -  person Fred Foo    schedule 26.04.2013
comment
Хороший вопрос. На самом деле я не уверен, какое влияние tf-idf и нормализация оказывают на распределение, но вполне возможно, что это не гауссово. Честно говоря, я просто взял это из набора инструментов, потому что он обрабатывает непрерывные функции, так что это вполне может быть плохим выбором для данных. Я до сих пор не уверен, объясняет ли это результаты, которые я получаю, или нет.   -  person flatline    schedule 26.04.2013
comment
Я упустил тот факт, что это векторы tf-idf. Я приготовлю ответ.   -  person Fred Foo    schedule 26.04.2013


Ответы (1)


GaussianNB вообще не подходит для классификации документов, поскольку значения tf-idf являются неотрицательными частотами; используйте вместо этого MultinomialNB и, возможно, попробуйте BernoulliNB. scikit-learn поставляется с примером классификации документов, который, кстати, использует tf-idf взвешивание с использованием встроенного TfidfTransformer.

Однако не ждите чудес, поскольку 300 образцов - это довольно мало для обучающего набора (хотя для двоичной классификации этого может быть достаточно, чтобы превзойти «наиболее частый» базовый уровень). YMMV.

Полное раскрытие информации: я являюсь одним из основных разработчиков scikit-learn и основным автором текущего кода MultinomialNB и BernoulliNB.

person Fred Foo    schedule 26.04.2013
comment
Спасибо - работали и полиномиальный, и классификатор Бернулли. В ре. чудеса, вы можете быть удивлены, но на самом деле я получаю неплохие результаты (точность ~ 84%), наравне с результатами SVM. - person flatline; 26.04.2013
comment
@flatline: это хороший результат! Учитывая, что вы проводите гендерную классификацию, я ожидаю, что базовый уровень будет чуть более 50%? - person Fred Foo; 26.04.2013
comment
К сожалению, исходные данные несколько более предвзяты - 58% мужчин - но это все же лучший результат, чем я ожидал вначале. Я не думаю, что я собираюсь получить от этого что-нибудь еще, но ты никогда не знаешь. Scikit-learn выглядит как действительно хороший пакет, кстати, мне он нравится намного больше, чем weka. MultinomialNB / BernoulliNB, по крайней мере, может обрабатывать гораздо большее пространство функций, чем я думал, что смогу сделать с помощью байесовских методов. - person flatline; 26.04.2013