我开始使用Scikit-learn,并尝试训练和预测高斯朴素贝叶斯分类器。我不太清楚自己在做什么,希望有人能帮帮我。
问题:我输入X数量的类型1的项目,结果却得到它们是类型0的响应
我这样做的:为了生成用于训练的数据,我这样做:
#这属于类型1 ganado={ "Hora": "16:43:35", "Fecha": "19/06/2015", "Tiempo": 10, "Brazos": "der", "Sentado": "no", "Puntuacion Final Pasteles": 50, "Nombre": "usuario1", "Puntuacion Final Botellas": 33 } #这属于类型0 perdido={ "Hora": "16:43:35", "Fecha": "19/06/2015", "Tiempo": 10, "Brazos": "der", "Sentado": "no", "Puntuacion Final Pasteles": 4, "Nombre": "usuario1", "Puntuacion Final Botellas": 3 } train=[] for repeticion in range(0,400): train.append(ganado) for repeticion in range(0,1): train.append(perdido)
我通过这个弱条件标记数据:
listLabel=[]for data in train: condition=data["Puntuacion Final Pasteles"]+data["Puntuacion Final Botellas"] if condition<20: listLabel.append(0) else: listLabel.append(1)
我这样生成用于测试的数据:
#这应该是类型1 pruebaGanado={ "Hora": "16:43:35", "Fecha": "19/06/2015", "Tiempo": 10, "Brazos": "der", "Sentado": "no", "Puntuacion Final Pasteles": 10, "Nombre": "usuario1", "Puntuacion Final Botellas": 33 } #这应该是类型0 pruebaPerdido={ "Hora": "16:43:35", "Fecha": "19/06/2015", "Tiempo": 10, "Brazos": "der", "Sentado": "no", "Puntuacion Final Pasteles": 2, "Nombre": "usuario1", "Puntuacion Final Botellas": 3 } test=[] for repeticion in range(0,420): test.append(pruebaGanado) test.append(pruebaPerdido)
之后,我使用train
和listLabel
来训练分类器:
vec = DictVectorizer()X=vec.fit_transform(train)gnb = GaussianNB()trained=gnb.fit(X.toarray(),listLabel)
一旦我训练了分类器,我就使用测试数据
testX=vec.fit_transform(test)predicted=trained.predict(testX.toarray())
最后结果总是0
。你能告诉我我哪里做错了以及如何修复吗?
回答:
首先,由于你的数据中有一些特征对分类没有信息量(所有数据的值都相同),我对其进行了一些清理:
ganado={ "a": 50, "b": 33}perdido={ "a": 4, "b": 3 }pruebaGanado={ "a": 10, "b": 33 }pruebaPerdido={ "a": 2, "b": 3 }
其余部分并不重要,清理你的代码将有助于你专注于重要的事情。
现在,高斯朴素贝叶斯全部是关于概率的:正如你可能注意到的那样,分类器试图告诉你:
P((a,b)=(10,33)|class=0)*P(class=0) > P((a,b)=(10,33)|class=1)*P(class=1)
因为它假设a
和b
都具有正态分布,并且在这种情况下概率非常低,你给它的先验概率-(1,400)是可以忽略的。你可以在这里查看公式本身 这里。顺便说一句,你可以得到确切的概率:
t = [pruebaGanado,pruebaPerdido]t = vec.fit_transform(t)print model.predict_proba(t.toarray())#prints:[[ 1. 0.][ 1. 0.]]
所以分类器确定0是正确的类。现在,让我们稍微改变一下测试数据:
pruebaGanado={ "Puntuacion Final Pasteles": 20, "Puntuacion Final Botellas": 33}
现在我们有:
[[ 0. 1.][ 1. 0.]]
所以你没有做错什么,这完全是计算的问题。顺便说一句,我挑战你用MultinomialNB
替换GaussianNB
,看看先验概率如何改变一切。
另外,除非你有很好的理由使用GaussianNB
,我建议考虑使用某种树分类,因为在我看来,它可能更适合你的问题。