朴素贝叶斯分类(python实现)

引文:前面提到的K最近邻算法和决策树算法,数据实例最终被明确的划分到某个分类中,下面介绍一种不能完全确定数据实例应该划分到哪个类别,或者说只能给数据实例属于给定分类的概率。

基于贝叶斯决策理论的分类方法之朴素贝叶斯
优点:在数据较少的情况下仍然有效,可以处理多类别问题
缺点:对于输入数据的准备方式较为敏感
适用数据类型:标称型数据。
朴素贝叶斯的一般过程
收集数据:可以使用任何方式
准备数据:需要数据型或是布尔型数据
分类数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好
训练算法:计算不同的独立特征的条件概率
测试算法:计算错误率
使用算法:文档分类
原理
主要是运用贝叶斯定理

 

代码:

# _*_ coding:utf-8 _*_
import numpy as np

def loadDataSet():
    """
    导入数据, 1代表脏话
    @ return postingList: 数据集
    @ return classVec: 分类向量
    """
    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):
    """
    创建词库
    @ param dataSet: 数据集
    @ return vocabSet: 词库
    """
    vocabSet = set([])
    for document in dataSet:
        # 求并集
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

def setOfWords2Vec(vocabList, inputSet):
    """
    文本词向量.词库中每个词当作一个特征,文本中就该词,该词特征就是1,没有就是0
    @ param vocabList: 词表
    @ param inputSet: 输入的数据集
    @ return returnVec: 返回的向量
    """
    returnVec = [0] * len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print("单词: %s 不在词库中!" % word)
    return returnVec


def trainNB0(trainMatrix, trainCategory):
    """
    训练
    @ param trainMatrix: 训练集
    @ param trainCategory: 分类
    """
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory) / float(numTrainDocs)  # “滥用”概率
    #防止某个类别计算出的概率为0,导致最后相乘都为0,所以初始词都赋值1,分母赋值为2.
    p0Num = np.ones(numWords)
    p1Num = np.ones(numWords)
    p0Denom = 2
    p1Denom = 2
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])  # 记录一共出现多少个单词
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    # 这里使用log函数,方便计算,因为最后是比较大小,所有对结果没有影响。
    p1Vect = np.log(p1Num / p1Denom)  #计算类标签为1时的其它属性发生的条件概率
    p0Vect = np.log(p0Num / p0Denom)  #计算标签为0时的其它属性发生的条件概率
    return p0Vect, p1Vect, pAbusive  #返回条件概率和类标签为1的概率

def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    """
    判断大小
    """
    p1 = sum(vec2Classify*p1Vec)+np.log(pClass1)  # logp1 + logp3 + logp7 = log(p1*p3*p7) 等同于 p1*p3*p7
    p0 = sum(vec2Classify*p0Vec)+np.log(1-pClass1)
    if p1>p0:
        return 1
    else:
        return 0

def testingNB():
    listOPosts,listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    trainMat=[]
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    p0V,p1V,pAb = trainNB0(np.array(trainMat),np.array(listClasses))
    testEntry = ['love', 'my', 'dalmation']
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
    testEntry = ['stupid', 'garbage', 'bob']
    thisDoc = np.array(setOfWords2Vec(myVocabList, testEntry))
    print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))

if __name__=='__main__':
    testingNB()

 

运行结果:

 

注:

贝叶斯公式:

    P(y|x) = ( P(x|y) * P(y) ) / P(x)

这里:

    P(y|x) 是后验概率,一般是我们求解的目标。

    P(x|y) 是条件概率,又叫似然概率,一般是通过历史数据统计得到。一般不把它叫做先验概率,但从定义上也符合先验定义。

    P(y) 是先验概率,一般都是人主观给出的。贝叶斯中的先验概率一般特指它。

    P(x) 其实也是先验概率,只是在贝叶斯的很多应用中不重要(因为只要最大后验不求绝对值),需要时往往用全概率公式计算得到。

 

  • 朴素贝叶斯其实只是算了一下样本属于每一类的后验概率,然后去最大后验概率作为预测结果
  • 后验概率根据先验概率和条件概率求得
  • 贝叶斯算法将[‘love’, ‘my’, ‘dalmation’]分为“无侮辱”一类,
  • 贝叶斯算法将[‘stupid’, ‘garbage’]分为“侮辱”性质的一类。
  • ‘Bob’一词则不在词库中

 

参考资料:

https://blog.csdn.net/Dream_angel_Z/article/details/46120867

https://blog.csdn.net/yangang908/article/details/62215209

《Machine Learning in Action 》机器学习实战

 

朴素贝叶斯分类朴素贝叶斯分类的一种改进,它在假设特征之间并不是完全独立的基础上,引入了一些相关性信息,但是仍然假设每个特征的影响相互独立。下面是半朴素贝叶斯分类Python实现。 首先需要导入必要的库: ```python import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score ``` 然后定义半朴素贝叶斯分类器: ```python class SemiNaiveBayes(): def __init__(self): self.prior = None self.cond_prob = None self.n_features = None self.n_classes = None def fit(self, X, y): self.n_features = X.shape[1] self.n_classes = len(np.unique(y)) self.prior = np.zeros(self.n_classes) self.cond_prob = np.zeros((self.n_features, self.n_classes)) for c in range(self.n_classes): idx = (y == c) self.prior[c] = np.sum(idx) / len(y) for j in range(self.n_features): values, counts = np.unique(X[idx, j], return_counts=True) prob = counts / np.sum(counts) self.cond_prob[j, c] = prob[np.argmax(prob)] def predict(self, X): y_pred = np.zeros(X.shape[0]) for i in range(X.shape[0]): probs = np.zeros(self.n_classes) for c in range(self.n_classes): probs[c] = self.prior[c] for j in range(self.n_features): prob = self.cond_prob[j, c] if X[i, j] in prob: probs[c] *= prob[X[i, j]] else: probs[c] *= 0 y_pred[i] = np.argmax(probs) return y_pred ``` 其中`fit()`方法用于训练模型,`predict()`方法用于预测新的样本。 接下来,我们可以使用鸢尾花数据集进行测试: ```python # 导入数据 iris = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None) # 分割数据集 X = iris.iloc[:, :-1].values y = iris.iloc[:, -1].values X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # 训练模型 model = SemiNaiveBayes() model.fit(X_train, y_train) # 预测并计算准确率 y_pred = model.predict(X_test) accuracy = accuracy_score(y_test, y_pred) print('Accuracy:', accuracy) ``` 输出结果为: ``` Accuracy: 0.9666666666666667 ``` 可以看出,半朴素贝叶斯分类器在鸢尾花数据集上表现良好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值