赞
踩
朴素贝叶斯算法是一个典型的统计学习方法,主要理论基础就是一个贝叶斯公式,贝叶斯公式的基本定义如下:
朴素贝叶斯分类器的表示形式:
当特征为为x时,计算所有类别的条件概率,选取条件概率最大的类别作为待分类的类别。由于上公式的分母对每个类别都是一样的,因此计算时可以不考虑分母,即
朴素贝叶斯的朴素体现在其对各个条件的独立性假设上,加上独立假设后,大大减少了参数假设空间。
1.创建词典,词典长度为不重复的总单词数
def creteVocabList(dataSet):
vocabList = set([]) #建立一个空集合
for data in dataSet:
vocabList = vocabList | set(data) #词典对每一行求并集
return list(vocabList)
2.将文本转化为向量,测试集和训练集都需要这一步
##词集模型将输入的文本转化为词向量,建立一个和词典长度相同的向量,在该文本出现的词设为1,没出现的设为0
def setofWords2Vec(vocabList,inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if(word in vocabList):
returnVec[vocabList.index(word)] = 1 #查找一个列表中某一元素的索引
return returnVec
#词袋模型,与词集模型类似,但是出现不是置为1,而是该词出现的次数。
def bagofWords2Vec(vocabList,inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if(word in vocabList):
returnVec[vocabList.index(word)] += 1 #查找一个列表中某一元素的索引
return returnVec
3.对训练集进行训练
#训练算法,此算法是针对二分类,输入是两个array数组,返回的p0vect,p1vect也是数组
def trainNB0(trainMatrix,trainCategory):
cal = len(trainCategory)
row = len(trainMatrix[0])
P1 = sum(trainCategory)/float(len(trainMatrix))
Cal0 = ones(row);Cal1 = ones(row) #原为Cal0 = zeros(row);Cal1 = zeros(row)
Total0Word = 2.0 #原为Total0Word = 0.0
Total1Word = 2.0 #原为Total0Word = 0.0
for i in range(cal):
if(trainCategory[i]==1):
Cal1 += trainMatrix[i]
Total1Word += sum(trainMatrix[i])
else:
Cal0 += trainMatrix[i]
Total0Word += sum(trainMatrix[i])
#下面是对一个数组/一个实数,对每个元素做除法
P1vect = log(Cal1/Total1Word) #原为P1vect = Cal1/Total1Word
P0vect = log(Cal0/Total0Word) #原为P1vect = Cal0/Total0Word
return P1,P0vect,P1vect
4.分类器
#根据现实情况修改分类器,上述分类器存在问题有p(w0|1)*P(w1|1)...若有一个值为0则概率为0,因此将各个单词出现次数初始化为1,分母初始化为2.
#经过上面的修改,由于相乘的数都太小容易发生下溢出,对乘数取对数处理
#下面是分类器的使用
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
p1 = sum(vec2Classify*p1Vec)+log(pClass1)
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1>p0:
return 1
else:
return 0
5.上述分类器在邮件分类中的使用
先读取文件,将文件分成一个一个单词
采用正则表达式,将一个字符串读成包涵长度大于3单词的列表
def textParse(bigString):
listofTokens = re.split(r"\W+",bigString)
return(tok.lower() for tok in listofTokens if len(tok)>2)
接下来进行分类
def spamTest():
docList = [];classList = [];
#读取数据和标签,开始都读入到训练集中,后来再分割为训练集和测试集
for i in range(1,26):
wordList = textParse(open('email/spam/%d.txt'%i).read())
wordList = list(wordList) #这里返回的是可迭代对象?将他转为列表,开始按照书中写的错误率特别高
docList.append(wordList)
#fullText.extend(listwordList)
classList.append(1)
wordList = textParse(open('email/ham/%d.txt' % i).read())
wordList = list(wordList)
docList.append(wordList)
#fullText.extend(wordList)
classList.append(0)
#创建词典
vocabList = Bayes1.creteVocabList(docList)
#print(vocabList)
#列表记录索引,便于分割
trainingSet = list(range(50));testSet = []
#划分测试集
for i in range(10
#随机选取0-len..中的整数,这个的作用和书中的int(random.uniform(0,len..))作用一样,uniform返回的不是整数
randIndex = random.randint(0,len(trainingSet))
#print(randIndex)
testSet.append(trainingSet[randIndex])
del(trainingSet[randIndex])
#将训练集转化为向量
trainMat = [];trainClass = []
for docIndex in trainingSet:
trainMat.append(Bayes1.bagofWords2Vec(vocabList,docList[docIndex]))
trainClass.append(classList[docIndex])
#对训练进行训练
p1,p0V,p1V = Bayes1.trainNB0(array(trainMat),array(trainClass))
#下面是测试,并计算错误率
errorCount = 0
for docIndex in testSet:
print(docList[docIndex])
wordVector = Bayes1.bagofWords2Vec(vocabList,docList[docIndex])
if Bayes1.classifyNB(array(wordVector),p0V,p1V,p1)!=classList[docIndex]:
errorCount += 1
#print("classification error", docList[docIndex])
print("error rate is:",float(errorCount)/len(testSet))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。