Наивный байес pyspark 1.3 нет ответа

Я пытаюсь запустить наивный байесовский классификатор для моих данных в PySpark 1.3

Вот мой пример данных:

Используя текстовый файл, я конвертирую его в объект LabeledPoint

67,[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,3.....60,66],[0.45,0.441666666667,0.475,0.0,0.717763157895,0.0,0.497300944669,0.476608187135,0.0,0.0,0.45183714002,0.616666666667,0.966666666667,0.0790064102564,-0.364093614847,0.0679487179487,0.256043956044,0.7,0.449583333333,0.231904697754,0.341666666667,0.06....,0,0]

data = MLUtils.loadLibSVMFile(sc, 'path to file')

training, test = data.randomSplit([0.7, 0.3], seed=0)

model = NaiveBayes.train(training, 1.0)

predictionAndLabel = test.map(lambda p: (model.predict(p.features), p.label))

accuracy = (
    1.0 * predictionAndLabel.filter(lambda (x, v): x == v).count() / test.count()
)

PySpark, кажется, навсегда зависает от расчета переменной модели. Кто-нибудь еще сталкивался с этой проблемой раньше? Благодарю.

1 ответ

Решение

Алгоритм Наивного Байеса в Spark требует, чтобы никакие особенности (например, значения x) не были отрицательными. В LabeledPoints вы можете видеть, что -0.364093614847 является отрицательным. Это должно быть ошибка. Итак, попробуйте вернуться к исходным данным и найти способ преобразовать все отрицательное в положительное значение. В приведенном ниже примере все мои данные находятся в диапазоне от -1,0 до 1,0. Я просто добавляю 1.0 ко всем значениям, чтобы распределения / средние / стандартные отклонения остались прежними.

Ваш data выглядит так:

[LabeledPoint(1.0,(1,[0,1,2,3],[-0.5,0.5,0.0,0.8]))], 
[LabeledPoint(0.0,(1,[0,1,2,3],[0.1,0.5,0.5,-0.6]))],
[LabeledPoint(1.0,(1,[0,1,2,3],[0.9,0.1,-0.2,0.7]))]

Проблема в том, что структуры данных в Spark в основном неизменны. Следовательно, вам нужно вернуться к тому моменту, когда ваши данные еще не были преобразованы в объект LabeledPoint (например, когда они все еще были текстовыми). Вот пример кода о том, как читать в текстовом файле (с некоторыми пропущенными значениями), добавить по одному для каждой функции, а затем преобразовать в LabeledPoint. Обратите внимание, что это для CSV, но если вы измените, что в split Вы можете изменить его для TSV или другого разделителя.

sc.textFile("/your/directory/your-file/*") \
     .map(lambda x: [unicode("") if x1=="nan" else x1 for x1 in x.split(',')[1:]])\
     .map(lambda x: x[0] + " " + " ".join([str(i+1)+":"+str(float(x1)+1) for i,x1 in enumerate(x[1:4]) if x1 != ''])) \ 
     .saveAsTextFile("/your/directory/new-directory/no-neg")

Предполагается, что исходный файл имеет вид:

Label, X1, X2, X3, X4

Другие вопросы по тегам