机器学习_朴素贝叶斯算法识别手写数字

来源:互联网 发布:微信js sdk 分享 编辑:程序博客网 时间:2024/06/01 09:16

朴素贝叶斯算法是基于条件概率的一种分类算法,通过概率大小来进行分类,经常用于分类文档。本文用python实现朴素贝叶斯算法,并用kaggle识别手写数字的数据集来训练,得到81%的准确率。虽然准确率可能比不上其它如SVM、神经网络等算法,但是朴素贝叶斯算法相对来说简单,计算速度也较快。

朴素贝叶斯理论说明

朴素贝叶斯的基本公式:
P(c1|w)>P(c0|w) ,则w样本属于c1 类别;
P(c1|w)<P(c0|w) ,则w样本属于c0 类别。
同样在多分类问题中,P(ci|w) 最大时表示样本w 属于ci 分类。其中P(ci|w) 表示挑选出来的样本w 属于ci 的概率。

  • 通常P(ci|w) 难以直接求得,可用条件概率间接求,公式如下:
    P(ci|w)=P(w|ci)P(ci)P(w)
    其中P(w|ci) 表示从ci 类中取出样本w的概率,P(ci) 表示类别ci 的概率,以上公式的由来相信学过概率论的同学应该都比较清楚这是条件概率。

  • 主要过程

    1. 计算条件概率P(w|ci)P(ci) ,假设各特征相互独立,则P(w|ci)=P(w0|ci)P(w1|ci)....P(wn|ci)
    2. 对于一个数据集,取出每一个样本概率 P(w) 值是一样的,因此只需要比较P(ci|w) 的值,最大值条件下的ci 即分类结果
    3. 为防止概率数值过小(接近于0)而出现下溢,因而采用logP(w|ci)P(ci) 来表示概率。

python实现

通过Kaggle识别手写数字来实现朴素贝叶斯算法。
* 训练数据集

import numpy as npdef trainMethod(dataSet, classesLabel):    m,n = dataSet.shape    labelSet = set(classesLabel)    numLabel = len(labelSet)    numFeat = np.ones((numLabel,n))    piLabel = np.zeros(numLabel)    piDenom = np.ones(numLabel)+1    for label in labelSet:        for i in range(m):            if classesLabel[i] == label:                numFeat[label] += dataSet[i]                piDenom[label] += sum(dataSet[i])                piLabel[label] +=1    for j in labelSet:        numFeat[j] = np.log(numFeat[j]/piDenom[j])    piLabel = piLabel/m    return numFeat, piLabel
  • 测试算法
import numpy as npimport pandas as pdimport csv#图片二像素化,即把图片变为黑白,没有灰度def normalizing(array):    m,n = array.shape    for i in range(m):        for j in range(n):            if array[i, j]!=0:                array[i, j]=1  #非零全部转化为1    return array# 定义数据集加载函数def loadTrainData():    csv_data = np.array(pd.read_csv('kaggle_dataset/digit_recognize/train.csv'))    label = csv_data[:,0]  #取值label    data = csv_data[:,1:]  #取像素质值    return label, normalizing(data)# 加载测试数据,测试数据中没有labeldef loadTestData():    csv_test = np.array(pd.read_csv('kaggle_dataset/digit_recognize/test.csv'))    return csv_test# 将数据写入到csv中,python3读写def saveResultCsv(result, csvName):    with open(csvName, 'w', newline='') as myFile:        writer = csv.writer(myFile)        heads = ['ImageId', 'Label']        writer.writerow(heads)        j = 1        for i in result:            temp = [j, i]            writer.writerow(temp)            j += 1label,dataSet= loadTrainData()dataTest = loadTestData()piFeat, piLabel = trainMethod(dataSet, label)result = []for i in range(len(dataTest)):    result.append(predict(dataTest[i], piFeat, piLabel))saveResultCsv(result, 'kaggle_dataset/digit_recognize/result_NB.csv')
  • 提交结果,准确率为81%

朴素贝叶斯分类结果

阅读全文
0 0
原创粉丝点击