机器学习 Python实现 贝叶斯算法

[['my','dog','has','flea','problems','help','please'],    0

 ['maybe','not','take','him','to','dog','park','stupid'],  1

 ['my','dalmation','is','so','cute','I','love','him'],          0

 ['stop','posting','stupid','worthless','garbage'],          1

 ['mr','licks','ate','my','steak','how','to','stop','him'],  0

['quit','buying','worthless','dog','food','stupid']]           1


以上是六句话,标记是0句子的表示正常句,标记是1句子的表示为粗口。我们通过分析每个句子中的每个词,在粗口句或是正常句出现的概率,可以找出那些词是粗口。

注意:主要从以下两点对分类器进行修改

<1>贝叶斯概率需要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|1)p(w1|1)p(w2|1)。如果其中一个概率值为0,那么最后的乘积也为0

<2>第二个问题就是下溢出,这是由于太多过小的数相乘造成的。由于大部分因子都非常小,所以程序会下溢出或者得不到正确的答案。解决办法是对乘积取自然对数这样可以避免下溢出或者浮点数舍入导致的错误。

<3>每个单词的出现与否作为一个特征,被称为词集模型;在词袋模型中,每个单词可以出现多次。

贝叶斯理论就是通过可以求得的后验概率计算前验概率
这里用到的朴素贝叶斯理论有两个前提
特征之间相互独立
特征之间同等重要
# -*- coding: cp936 -*-
from numpy import *  
#过滤网站的恶意留言  
# 创建一个实验样本  
def loadDataSet():  
    postingList = [['my','dog','has','flea','problems','help','please'],  
                   ['maybe','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):  
    vocabSet = set([])      #创建一个空集  
    for document in dataSet:  
        vocabSet = vocabSet | set(document)   #创建两个集合的并集  
    return list(vocabSet)  
  
#将文档词条转换成词向量  
def setOfWords2Vec(vocabList, inputSet):  
    returnVec = [0]*len(vocabList)        #创建一个其中所含元素都为0的向量  
    for word in inputSet:  
        if word in vocabList:  
            #returnVec[vocabList.index(word)] = 1     #index函数在字符串里找到字符第一次出现的位置  词集模型  
            returnVec[vocabList.index(word)] += 1      #文档的词袋模型    每个单词可以出现多次  
        else: print "the word: %s is not in my Vocabulary!" % word  
    return returnVec

#朴素贝叶斯分类器训练函数   从词向量计算概率  
def trainNB0(trainMatrix, trainCategory):  
    numTrainDocs = len(trainMatrix)  #文本数量
    numWords = len(trainMatrix[0])   #文本中词汇数量也是词库的大小
    pAbusive = sum(trainCategory)/float(numTrainDocs)  #P(wi)
   # p0Num = zeros(numWords); p1Num = zeros(numWords)  
    #p0Denom = 0.0; p1Denom = 0.0  
    p0Num = ones(numWords); p1Num = ones(numWords)#避免一个概率值为0,最后的乘积也为0  
    p0Denom = 2.0; p1Denom = 2.0  
    for i in range(numTrainDocs):  
        if trainCategory[i] == 1:  
            p1Num += trainMatrix[i]  #按行进行相加,每个词汇自己计算总数
            p1Denom += sum(trainMatrix[i])  #所有词汇一共出现的次数
        else:  
            p0Num += trainMatrix[i]  
            p0Denom += sum(trainMatrix[i])  
    #p1Vect = p1Num / p1Denom  
    #p0Vect = p0Num / p0Denom   #计算获得p(wi|c1),p(wi|c0)
    #print (p1Num)
    #print (p1Denom)
    p1Vect = log(p1Num / p1Denom)  
    p0Vect = log(p0Num / p0Denom)      #避免下溢出或者浮点数舍入导致的错误   下溢出是由太多很小的数相乘得到的  
    return p0Vect, p1Vect, pAbusive

#朴素贝叶斯分类器  
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):  #vec2Classify表示需要分类的向量
    p1 = sum(vec2Classify*p1Vec) + log(pClass1)  
    p0 = sum(vec2Classify*p0Vec) + log(1.0-pClass1)  
    if p1 > p0:  
        return 1  
    else: return 0  
  
def test():
    listPosts,listClasses = loadDataSet()
    myVocablist = createVocabList(listPosts)
    set1 = setOfWords2Vec(myVocablist,listPosts[0])
    #print(set1)
    set2 = setOfWords2Vec(myVocablist,listPosts[1])
    #print(set2)
    trainMat = []
    for postinDoc in listPosts:
        trainMat.append(setOfWords2Vec(myVocablist,postinDoc))
    #print(trainMat)
    #print(listClasses)
    p0V,p1V,pAb = trainNB0(trainMat,listClasses)
    print(pAb)
    print(p1V)
    testEntry = ['love','my','dalmation']  
    thisDoc = array(setOfWords2Vec(myVocablist, testEntry))  
    print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb)  
    testEntry = ['stupid','garbage']  
    thisDoc = array(setOfWords2Vec(myVocablist, testEntry))  
    print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb)

#垃圾邮件过滤的例子:
def textParse(bigString):      #正则表达式进行文本分割  
    import re  
    listOfTokens = re.split(r'\W*',bigString)  
    return [tok.lower() for tok in listOfTokens if len(tok) > 2]  
  
def spamTest():  
    docList = []; classList = []; fullText = []  
    for i in range(1,26):                          #导入并解析文本文件  
        wordList = textParse(open('E:/python project/Bayes/email/spam/%d.txt' % i).read())  
        docList.append(wordList)  
        fullText.extend(wordList)  
        classList.append(1)  
        wordList = textParse(open('E:/python project/Bayes/email/ham/%d.txt' % i).read())  
        docList.append(wordList)  
        fullText.extend(wordList)  
        classList.append(0)  
    vocabList = createVocabList(docList)  
    trainingSet = range(50);testSet = []  
    for i in range(10):                         #随机构建10个测试集  
        randIndex = int(random.uniform(0,len(trainingSet)))  
        testSet.append(trainingSet[randIndex])  
        del(trainingSet[randIndex])  
    trainMat = []; trainClasses = []  
    for docIndex in trainingSet:  
        trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))  
        trainClasses.append(classList[docIndex])  
    p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))  
    errorCount = 0  
    for docIndex in testSet:              #对测试集进行分类  
        wordVector = setOfWords2Vec(vocabList, docList[docIndex])  
        if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:  
            errorCount += 1  
    print 'the error rate is: ', float(errorCount)/len(testSet)  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
贝叶斯算法是一种常用于分类问题的机器学习算法。以下是用 Python 实现的基本步骤: 1. 准备数据集 首先,我们需要准备一个数据集,并将其分为训练集和测试集。数据集应包含已分类的样本。 2. 计算先验概率 先验概率是每个类别出现的概率。我们可以通过计算训练集中每个类别的样本数量除以总样本数来计算先验概率。 3. 计算条件概率 条件概率是指在给定特征的情况下,某个类别出现的概率。我们可以通过计算每个特征在每个类别中出现的次数除以该类别的样本总数来计算条件概率。 4. 计算后验概率 后验概率是指在给定特征的情况下,某个类别出现的概率。我们可以使用贝叶斯公式来计算后验概率。 5. 预测分类 使用测试集中的样本特征,我们可以计算其在每个类别中的后验概率,并选择具有最高后验概率的类别作为预测分类。 下面是一个简单的 Python 实现: ```python class NaiveBayes: def __init__(self): self.classes = None self.priors = None self.likelihoods = None def fit(self, X, y): self.classes = np.unique(y) self.priors = np.zeros(len(self.classes)) self.likelihoods = [] for i, c in enumerate(self.classes): X_c = X[y == c] self.priors[i] = len(X_c) / len(X) self.likelihoods.append({}) for j in range(X.shape[1]): self.likelihoods[i][j] = {} for val in np.unique(X[:, j]): self.likelihoods[i][j][val] = \ len(X_c[X_c[:, j] == val]) / len(X_c) def predict(self, X): posteriors = [] for i, c in enumerate(self.classes): prior = np.log(self.priors[i]) posterior = np.sum(np.log(self.likelihoods[i][j][X[j]]) for j in range(X.shape[1])) + prior posteriors.append(posterior) return self.classes[np.argmax(posteriors)] ``` 这是一个简单的朴素贝叶斯分类器实现。`fit` 方法用于拟合训练数据,而 `predict` 方法用于预测测试数据的分类。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值