import numpy as np
#bayes 基础核心算法是以一个假设为前提,通过乘法概率以及全概率等观念,将非数值类型原始标本转化为数值类型的矩阵模型,实现非确定型分类标本的分类。
# 这是一种不确定性的推理,与产生式推理法则相关连,通过已知分类,逆向推理得到相关参数,通过相关参数实现不缺性分类的分类器的实现。P(A|B)*P(B)=P(B|A)*P(A)
# 渐进性思维与极限思维带有局限性,因此在实际的应用中,为了降低为0 概率特征项的影响,对于概率的参数初始化做了两点改进
# 1,我们可以将所有词组出现的次数初始化为1, 并将分母初始化为2, 这样就可以降低这样的情况出现 2,由于概率的乘积可能是很小的数,python在处理小数的时候可能会产生下溢出等,解决这个问题的方案是对小数取对数,因为对数函数 的曲线图与原函数的曲线图都是在同一个点取极值,因此取对数不会对结果造成任何影响
#优点:在数据较小的情况下任然有效, 可以处理多类别问题
#缺点: 对于输入数据的准备方式比较敏感
#适用数据类型 : 标称型数据类型
#description: 朴素贝叶斯模型是贝叶斯决策模型的一部分,对于类别的判断 如果p1(x,y)>p2(x,y), 那么为类别1,反之为类别2,。 也就是说我们会选择概率比较高的决策##,与KNN 算法相比,KNN 算法会在原有的基础之上实现n次的距离计算。因此KNN 算法的计算量比较大
def createDataSet():
postingList = [
['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
['mabye', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'i', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']
]
classVec = [0, 1, 0, 1, 0, 1]
return postingList, classVec
# 这个函数是讲所有的文档片段去掉重复值,并且组成一个没有重复值的集合{}向量
def createVocabList(dataset):
vovabSet = set([]) # 将矩阵向量转化为一个集合,并且讲集合中的重复特征值取出
for document in dataset:
vovabSet = vovabSet | set(document)
#print(vovabSet)
return list(vovabSet) # create the combination-set of two iteams
# ------得到初始数据
dataset,classVec=createDataSet()
#-------讲集合向量赋值setVo
setVo=createVocabList(dataset)
# 判断一个文档在这个集合向量中的是否出现,这个出现表现在与集合同等长度向量中,这个向量只有0,1 两个值
# 1 代表存在,0 代表不存在
def setOfWords2Vec(vocablist,imputSet):
returnVec =[0]*len(vocablist)
for word in imputSet:
if word in vocablist:
returnVec[vocablist.index(word)]=1
else :
print('the word:%s isnot in my vocabulary'%word)
return returnVec
trainMat = []
for postDoc in dataset:
trainMat.append(setOfWords2Vec(setVo,postDoc))
def trainNB0(trainMatrix,trainCategory):
numTrainDocs=len(trainMatrix)
print(numTrainDocs)
numWords=len(trainMatrix[0])
pAbusive=sum(trainCategory)/float(numTrainDocs)
p0Num=np.ones(numWords) # 这里不选择zearos 作为出书化向量,是因为,全概率公式中不允许出现概率为0 的情况
p1Num=np.ones(numWords)
p0Denom=2.0 # 这里不选择0.0 作为初始化的结果,是为了降低在实际应用中 理论仿真对实际想过的影响
p1Denom=2.0
for i in range(numTrainDocs): #numTrainDocs 行数
if trainCategory[i] == 1:
p1Num += trainMatrix[i] # 0 矩阵向量和 trainMatrix 中的每行0 矩阵向量相加
p1Denom +=sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect =np.log(p1Num/p1Denom)
p0Vect =np.log(p0Num/p0Denom)
return p0Vect,p1Vect,pAbusive
# 传入的参数为矩阵,类别向量
p0Vect,p1Vect,pAbusive=trainNB0(trainMat,classVec)
#print(p0Vect)
#print(p1Vect)
#print(trainMat)
# 测试算法
# name: kenny adelaide
# time:12-3
# email: kenny13141314@163.com
# description:
# 根据全概率公式我们可以指导,在对文档进行分类的时候,是已经在某个条件下实现文档的树形图分类,因此,这个文档的分类计算遵循全概率的公式。
# p(w1|ci)*p.......
# stiuation-development-one: 由于上述的实验可以知道, 某些词组出现的概率为0,在进行全概率公式计算的时候,只要有一个为-0 , 那么这个公式的结果就为-0, 在实际的应用中,这样的情况是不允许出现的。
# method: 为了降低这种情况所带来的影响,我们可以将所有词组出现的次数初始化为1, 并将分母初始化为2, 这样就可以降低这样的情况出现
#stiuation-development-two: 在python 程序设计语言中,由于很多概率的数是由小数组成的,这样的获得全概率公式的时候容易出现,下溢出的情况【程序得出一个很小的记过,就会四舍五入,结果还是为0】
# method : 为了降低这种情况带来的影响,方案1:对乘积 取自然对数。 ln(a*b)=ln(a)+ln(b) 这样可以避免出现下溢出的错误。采用自然对数不会有任何的损失。其中f(x) 与ln(fx) 这两个函数在同一个地方取极值,因此没有任何损失
# simply bayes classfire
# name: kenny adelaide
# time: 12-3
# email: kenny13141314@163.com
# description: 朴素贝叶斯分类函数
# classify function
def classfyNB(evc2Classify,p0Vec,p1Vec,pClass1):
#print('evc2Classify:%s'%evc2Classify)
p1=sum(evc2Classify *p1Vec)+ np.log(pClass1)
p0=sum(evc2Classify *p0Vec) +np.log(1.0-pClass1)
if p1 > p0 : return 1
else: return 0
def testingNB ():
listOposts,listClasses=createDataSet() # 创建一个文档集合
myVocabList=createVocabList(listOposts) # 创建一个不重复的词组向量
#print('evc2Classify:%s'%myVocabList)
trainMats=[] # 创建一个词组验证举证
for postDocs in listOposts:
trainMats.append(setOfWords2Vec(myVocabList,postDocs))# 获取相应的词组验证概率矩阵
#print(trainMats)
p0q,p1q,pA=trainNB0(np.array(trainMats),np.array(listClasses))
testEntry=['love','my','dalmation']
thisDoc=np.array(setOfWords2Vec(myVocabList,testEntry))
print('thisDoc:%s'%thisDoc)
print('entry:%s , classfiled:%s'%(testEntry,classfyNB(thisDoc,p0q,p1q,pA)))
testEntry=['stupid','garbage']
thisDoc=np.array(setOfWords2Vec(myVocabList,testEntry))
print('entry:%s , classfiled:%s' % (testEntry, classfyNB(thisDoc, p0q, p1q, pA)))
return 0
testingNB ()
#贝叶斯口袋模型
def bagOfWords2VecMn(vocabList,imputSet):
returnVec=[0]*len(vocabList)
for word in imputSet:
returnVec[vocabList.index(word)] +=1
return returnVec
*** 本文章可能出现描述性错误,如果有这样的错误,大家指正