樸素貝葉斯算法簡(jiǎn)單高效,在處理分類問(wèn)題上,是應(yīng)該首先考慮的方法之一。
通過(guò)本教程,你將學(xué)到樸素貝葉斯算法的原理和Python版本的逐步實(shí)現(xiàn)。
更新:查看后續(xù)的關(guān)于樸素貝葉斯使用技巧的文章“Better Naive Bayes: 12 Tips To Get The Most From The Naive Bayes Algorithm”
樸素貝葉斯分類器,Matt Buck保留部分版權(quán)
關(guān)于樸素貝葉斯
樸素貝葉斯算法是一個(gè)直觀的方法,使用每個(gè)屬性歸屬于某個(gè)類的概率來(lái)做預(yù)測(cè)。你可以使用這種監(jiān)督性學(xué)習(xí)方法,對(duì)一個(gè)預(yù)測(cè)性建模問(wèn)題進(jìn)行概率建模。
給定一個(gè)類,樸素貝葉斯假設(shè)每個(gè)屬性歸屬于此類的概率獨(dú)立于其余所有屬性,從而簡(jiǎn)化了概率的計(jì)算。這種強(qiáng)假定產(chǎn)生了一個(gè)快速、有效的方法。
給定一個(gè)屬性值,其屬于某個(gè)類的概率叫做條件概率。對(duì)于一個(gè)給定的類值,將每個(gè)屬性的條件概率相乘,便得到一個(gè)數(shù)據(jù)樣本屬于某個(gè)類的概率。
我們可以通過(guò)計(jì)算樣本歸屬于每個(gè)類的概率,然后選擇具有最高概率的類來(lái)做預(yù)測(cè)。
通常,我們使用分類數(shù)據(jù)來(lái)描述樸素貝葉斯,因?yàn)檫@樣容易通過(guò)比率來(lái)描述、計(jì)算。一個(gè)符合我們目的、比較有用的算法需要支持?jǐn)?shù)值屬性,同時(shí)假設(shè)每一個(gè)數(shù)值屬性服從正態(tài)分布(分布在一個(gè)鐘形曲線上),這又是一個(gè)強(qiáng)假設(shè),但是依然能夠給出一個(gè)健壯的結(jié)果。
預(yù)測(cè)糖尿病的發(fā)生
本文使用的測(cè)試問(wèn)題是“皮馬印第安人糖尿病問(wèn)題”。
這個(gè)問(wèn)題包括768個(gè)對(duì)于皮馬印第安患者的醫(yī)療觀測(cè)細(xì)節(jié),記錄所描述的瞬時(shí)測(cè)量取自諸如患者的年紀(jì),懷孕和血液檢查的次數(shù)。所有患者都是21歲以上(含21歲)的女性,所有屬性都是數(shù)值型,而且屬性的單位各不相同。
每一個(gè)記錄歸屬于一個(gè)類,這個(gè)類指明以測(cè)量時(shí)間為止,患者是否是在5年之內(nèi)感染的糖尿病。如果是,則為1,否則為0。
機(jī)器學(xué)習(xí)文獻(xiàn)中已經(jīng)多次研究了這個(gè)標(biāo)準(zhǔn)數(shù)據(jù)集,好的預(yù)測(cè)精度為70%-76%。
下面是pima-indians.data.csv文件中的一個(gè)樣本,了解一下我們將要使用的數(shù)據(jù)。
注意:下載文件,然后以.csv擴(kuò)展名保存(如:pima-indians-diabetes.data.csv)。查看文件中所有屬性的描述。
1
2
3
4
5
|
6 , 148 , 72 , 35 , 0 , 33.6 , 0.627 , 50 , 1 1 , 85 , 66 , 29 , 0 , 26.6 , 0.351 , 31 , 0 8 , 183 , 64 , 0 , 0 , 23.3 , 0.672 , 32 , 1 1 , 89 , 66 , 23 , 94 , 28.1 , 0.167 , 21 , 0 0 , 137 , 40 , 35 , 168 , 43.1 , 2.288 , 33 , 1 |
樸素貝葉斯算法教程
教程分為如下幾步:
1.處理數(shù)據(jù):從CSV文件中載入數(shù)據(jù),然后劃分為訓(xùn)練集和測(cè)試集。
2.提取數(shù)據(jù)特征:提取訓(xùn)練數(shù)據(jù)集的屬性特征,以便我們計(jì)算概率并做出預(yù)測(cè)。
3.單一預(yù)測(cè):使用數(shù)據(jù)集的特征生成單個(gè)預(yù)測(cè)。
4.多重預(yù)測(cè):基于給定測(cè)試數(shù)據(jù)集和一個(gè)已提取特征的訓(xùn)練數(shù)據(jù)集生成預(yù)測(cè)。
5.評(píng)估精度:評(píng)估對(duì)于測(cè)試數(shù)據(jù)集的預(yù)測(cè)精度作為預(yù)測(cè)正確率。
6.合并代碼:使用所有代碼呈現(xiàn)一個(gè)完整的、獨(dú)立的樸素貝葉斯算法的實(shí)現(xiàn)。
1.處理數(shù)據(jù)
首先加載數(shù)據(jù)文件。CSV格式的數(shù)據(jù)沒(méi)有標(biāo)題行和任何引號(hào)。我們可以使用csv模塊中的open函數(shù)打開(kāi)文件,使用reader函數(shù)讀取行數(shù)據(jù)。
我們也需要將以字符串類型加載進(jìn)來(lái)屬性轉(zhuǎn)換為我們可以使用的數(shù)字。下面是用來(lái)加載匹馬印第安人數(shù)據(jù)集(Pima indians dataset)的loadCsv()函數(shù)。
1
2
3
4
5
6
7
|
import csv def loadCsv(filename): lines = csv.reader( open (filename, "rb" )) dataset = list (lines) for i in range ( len (dataset)): dataset[i] = [ float (x) for x in dataset[i]] return dataset |
我們可以通過(guò)加載皮馬印第安人數(shù)據(jù)集,然后打印出數(shù)據(jù)樣本的個(gè)數(shù),以此測(cè)試這個(gè)函數(shù)。
1
2
3
|
filename = 'pima-indians-diabetes.data.csv' dataset = loadCsv(filename) print ( 'Loaded data file {0} with {1} rows' ). format (filename, len (dataset)) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Loaded data file iris.data.csv with 150 rows |
下一步,我們將數(shù)據(jù)分為用于樸素貝葉斯預(yù)測(cè)的訓(xùn)練數(shù)據(jù)集,以及用來(lái)評(píng)估模型精度的測(cè)試數(shù)據(jù)集。我們需要將數(shù)據(jù)集隨機(jī)分為包含67%的訓(xùn)練集合和包含33%的測(cè)試集(這是在此數(shù)據(jù)集上測(cè)試算法的通常比率)。
下面是splitDataset()函數(shù),它以給定的劃分比例將數(shù)據(jù)集進(jìn)行劃分。
1
2
3
4
5
6
7
8
9
|
import random def splitDataset(dataset, splitRatio): trainSize = int ( len (dataset) * splitRatio) trainSet = [] copy = list (dataset) while len (trainSet) < trainSize: index = random.randrange( len (copy)) trainSet.append(copy.pop(index)) return [trainSet, copy] |
我們可以定義一個(gè)具有5個(gè)樣例的數(shù)據(jù)集來(lái)進(jìn)行測(cè)試,首先它分為訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集,然后打印出來(lái),看看每個(gè)數(shù)據(jù)樣本最終落在哪個(gè)數(shù)據(jù)集。
1
2
3
4
|
dataset = [[ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ]] splitRatio = 0.67 train, test = splitDataset(dataset, splitRatio) print ( 'Split {0} rows into train with {1} and test with {2}' ). format ( len (dataset), train, test) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Split 5 rows into train with [[ 4 ], [ 3 ], [ 5 ]] and test with [[ 1 ], [ 2 ]] |
提取數(shù)據(jù)特征
樸素貝葉斯模型包含訓(xùn)練數(shù)據(jù)集中數(shù)據(jù)的特征,然后使用這個(gè)數(shù)據(jù)特征來(lái)做預(yù)測(cè)。
所收集的訓(xùn)練數(shù)據(jù)的特征,包含相對(duì)于每個(gè)類的每個(gè)屬性的均值和標(biāo)準(zhǔn)差。舉例來(lái)說(shuō),如果如果有2個(gè)類和7個(gè)數(shù)值屬性,然后我們需要每一個(gè)屬性(7)和類(2)的組合的均值和標(biāo)準(zhǔn)差,也就是14個(gè)屬性特征。
在對(duì)特定的屬性歸屬于每個(gè)類的概率做計(jì)算、預(yù)測(cè)時(shí),將用到這些特征。
我們將數(shù)據(jù)特征的獲取劃分為以下的子任務(wù):
按類別劃分?jǐn)?shù)據(jù)
計(jì)算均值
計(jì)算標(biāo)準(zhǔn)差
提取數(shù)據(jù)集特征
按類別提取屬性特征
按類別劃分?jǐn)?shù)據(jù)
首先將訓(xùn)練數(shù)據(jù)集中的樣本按照類別進(jìn)行劃分,然后計(jì)算出每個(gè)類的統(tǒng)計(jì)數(shù)據(jù)。我們可以創(chuàng)建一個(gè)類別到屬于此類別的樣本列表的的映射,并將整個(gè)數(shù)據(jù)集中的樣本分類到相應(yīng)的列表。
下面的SeparateByClass()函數(shù)可以完成這個(gè)任務(wù):
1
2
3
4
5
6
7
8
|
def separateByClass(dataset): separated = {} for i in range ( len (dataset)): vector = dataset[i] if (vector[ - 1 ] not in separated): separated[vector[ - 1 ]] = [] separated[vector[ - 1 ]].append(vector) return separated |
可以看出,函數(shù)假設(shè)樣本中最后一個(gè)屬性(-1)為類別值,返回一個(gè)類別值到數(shù)據(jù)樣本列表的映射。
我們可以用一些樣本數(shù)據(jù)測(cè)試如下:
1
2
3
|
dataset = [[ 1 , 20 , 1 ], [ 2 , 21 , 0 ], [ 3 , 22 , 1 ]] separated = separateByClass(dataset) print ( 'Separated instances: {0}' ). format (separated) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Separated instances: { 0 : [[ 2 , 21 , 0 ]], 1 : [[ 1 , 20 , 1 ], [ 3 , 22 , 1 ]]} |
計(jì)算均值
我們需要計(jì)算在每個(gè)類中每個(gè)屬性的均值。均值是數(shù)據(jù)的中點(diǎn)或者集中趨勢(shì),在計(jì)算概率時(shí),我們用它作為高斯分布的中值。
我們也需要計(jì)算每個(gè)類中每個(gè)屬性的標(biāo)準(zhǔn)差。標(biāo)準(zhǔn)差描述了數(shù)據(jù)散布的偏差,在計(jì)算概率時(shí),我們用它來(lái)刻畫(huà)高斯分布中,每個(gè)屬性所期望的散布。
標(biāo)準(zhǔn)差是方差的平方根。方差是每個(gè)屬性值與均值的離差平方的平均數(shù)。注意我們使用N-1的方法(譯者注:參見(jiàn)無(wú)偏估計(jì)),也就是在在計(jì)算方差時(shí),屬性值的個(gè)數(shù)減1。
1
2
3
4
5
6
7
8
|
import math def mean(numbers): return sum (numbers) / float ( len (numbers)) def stdev(numbers): avg = mean(numbers) variance = sum ([ pow (x - avg, 2 ) for x in numbers]) / float ( len (numbers) - 1 ) return math.sqrt(variance) |
通過(guò)計(jì)算從1到5這5個(gè)數(shù)的均值來(lái)測(cè)試函數(shù)。
1
2
|
numbers = [ 1 , 2 , 3 , 4 , 5 ] print ( 'Summary of {0}: mean={1}, stdev={2}' ). format (numbers, mean(numbers), stdev(numbers)) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Summary of [ 1 , 2 , 3 , 4 , 5 ]: mean = 3.0 , stdev = 1.58113883008 |
提取數(shù)據(jù)集的特征
現(xiàn)在我們可以提取數(shù)據(jù)集特征。對(duì)于一個(gè)給定的樣本列表(對(duì)應(yīng)于某個(gè)類),我們可以計(jì)算每個(gè)屬性的均值和標(biāo)準(zhǔn)差。
zip函數(shù)將數(shù)據(jù)樣本按照屬性分組為一個(gè)個(gè)列表,然后可以對(duì)每個(gè)屬性計(jì)算均值和標(biāo)準(zhǔn)差。
1
2
3
4
|
def summarize(dataset): summaries = [(mean(attribute), stdev(attribute)) for attribute in zip ( * dataset)] del summaries[ - 1 ] return summaries |
我們可以使用一些測(cè)試數(shù)據(jù)來(lái)測(cè)試這個(gè)summarize()函數(shù),測(cè)試數(shù)據(jù)對(duì)于第一個(gè)和第二個(gè)數(shù)據(jù)屬性的均值和標(biāo)準(zhǔn)差顯示出顯著的不同。
1
2
3
|
dataset = [[ 1 , 20 , 0 ], [ 2 , 21 , 1 ], [ 3 , 22 , 0 ]] summary = summarize(dataset) print ( 'Attribute summaries: {0}' ). format (summary) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Attribute summaries: [( 2.0 , 1.0 ), ( 21.0 , 1.0 )] |
按類別提取屬性特征
合并代碼,我們首先將訓(xùn)練數(shù)據(jù)集按照類別進(jìn)行劃分,然后計(jì)算每個(gè)屬性的摘要。
1
2
3
4
5
6
|
def summarizeByClass(dataset): separated = separateByClass(dataset) summaries = {} for classValue, instances in separated.iteritems(): summaries[classValue] = summarize(instances) return summaries |
使用小的測(cè)試數(shù)據(jù)集來(lái)測(cè)試summarizeByClass()函數(shù)。
1
2
3
|
dataset = [[ 1 , 20 , 1 ], [ 2 , 21 , 0 ], [ 3 , 22 , 1 ], [ 4 , 22 , 0 ]] summary = summarizeByClass(dataset) print ( 'Summary by class value: {0}' ). format (summary) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
2
3
|
Summary by class value: { 0 : [( 3.0 , 1.4142135623730951 ), ( 21.5 , 0.7071067811865476 )], 1 : [( 2.0 , 1.4142135623730951 ), ( 21.0 , 1.4142135623730951 )]} |
預(yù)測(cè)
我們現(xiàn)在可以使用從訓(xùn)練數(shù)據(jù)中得到的摘要來(lái)做預(yù)測(cè)。做預(yù)測(cè)涉及到對(duì)于給定的數(shù)據(jù)樣本,計(jì)算其歸屬于每個(gè)類的概率,然后選擇具有最大概率的類作為預(yù)測(cè)結(jié)果。
我們可以將這部分劃分成以下任務(wù):
計(jì)算高斯概率密度函數(shù)
計(jì)算對(duì)應(yīng)類的概率
單一預(yù)測(cè)
評(píng)估精度
計(jì)算高斯概率密度函數(shù)
給定來(lái)自訓(xùn)練數(shù)據(jù)中已知屬性的均值和標(biāo)準(zhǔn)差,我們可以使用高斯函數(shù)來(lái)評(píng)估一個(gè)給定的屬性值的概率。
已知每個(gè)屬性和類值的屬性特征,在給定類值的條件下,可以得到給定屬性值的條件概率。
關(guān)于高斯概率密度函數(shù),可以查看參考文獻(xiàn)。總之,我們要把已知的細(xì)節(jié)融入到高斯函數(shù)(屬性值,均值,標(biāo)準(zhǔn)差),并得到屬性值歸屬于某個(gè)類的似然(譯者注:即可能性)。
在calculateProbability()函數(shù)中,我們首先計(jì)算指數(shù)部分,然后計(jì)算等式的主干。這樣可以將其很好地組織成2行。
1
2
3
4
|
import math def calculateProbability(x, mean, stdev): exponent = math.exp( - (math. pow (x - mean, 2 ) / ( 2 * math. pow (stdev, 2 )))) return ( 1 / (math.sqrt( 2 * math.pi) * stdev)) * exponent |
使用一些簡(jiǎn)單的數(shù)據(jù)測(cè)試如下:
1
2
3
4
5
|
x = 71.5 mean = 73 stdev = 6.2 probability = calculateProbability(x, mean, stdev) print ( 'Probability of belonging to this class: {0}' ). format (probability) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Probability of belonging to this class : 0.0624896575937 |
計(jì)算所屬類的概率
既然我們可以計(jì)算一個(gè)屬性屬于某個(gè)類的概率,那么合并一個(gè)數(shù)據(jù)樣本中所有屬性的概率,最后便得到整個(gè)數(shù)據(jù)樣本屬于某個(gè)類的概率。
使用乘法合并概率,在下面的calculClassProbilities()函數(shù)中,給定一個(gè)數(shù)據(jù)樣本,它所屬每個(gè)類別的概率,可以通過(guò)將其屬性概率相乘得到。結(jié)果是一個(gè)類值到概率的映射。
1
2
3
4
5
6
7
8
9
|
def calculateClassProbabilities(summaries, inputVector): probabilities = {} for classValue, classSummaries in summaries.iteritems(): probabilities[classValue] = 1 for i in range ( len (classSummaries)): mean, stdev = classSummaries[i] x = inputVector[i] probabilities[classValue] * = calculateProbability(x, mean, stdev) return probabilities |
測(cè)試calculateClassProbabilities()函數(shù)。
1
2
3
4
|
summaries = { 0 :[( 1 , 0.5 )], 1 :[( 20 , 5.0 )]} inputVector = [ 1.1 , '?' ] probabilities = calculateClassProbabilities(summaries, inputVector) print ( 'Probabilities for each class: {0}' ). format (probabilities) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Probabilities for each class : { 0 : 0.7820853879509118 , 1 : 6.298736258150442e - 05 } |
單一預(yù)測(cè)
既然可以計(jì)算一個(gè)數(shù)據(jù)樣本屬于每個(gè)類的概率,那么我們可以找到最大的概率值,并返回關(guān)聯(lián)的類。
下面的predict()函數(shù)可以完成以上任務(wù)。
1
2
3
4
5
6
7
8
|
def predict(summaries, inputVector): probabilities = calculateClassProbabilities(summaries, inputVector) bestLabel, bestProb = None , - 1 for classValue, probability in probabilities.iteritems(): if bestLabel is None or probability > bestProb: bestProb = probability bestLabel = classValue return bestLabel |
測(cè)試predict()函數(shù)如下:
1
2
3
4
|
summaries = { 'A' :[( 1 , 0.5 )], 'B' :[( 20 , 5.0 )]} inputVector = [ 1.1 , '?' ] result = predict(summaries, inputVector) print ( 'Prediction: {0}' ). format (result) |
運(yùn)行測(cè)試,你會(huì)得到如下結(jié)果:
1
|
Prediction: A |
多重預(yù)測(cè)
最后,通過(guò)對(duì)測(cè)試數(shù)據(jù)集中每個(gè)數(shù)據(jù)樣本的預(yù)測(cè),我們可以評(píng)估模型精度。getPredictions()函數(shù)可以實(shí)現(xiàn)這個(gè)功能,并返回每個(gè)測(cè)試樣本的預(yù)測(cè)列表。
1
2
3
4
5
6
|
def getPredictions(summaries, testSet): predictions = [] for i in range ( len (testSet)): result = predict(summaries, testSet[i]) predictions.append(result) return predictions |
測(cè)試getPredictions()函數(shù)如下。
1
2
3
4
|
summaries = { 'A' :[( 1 , 0.5 )], 'B' :[( 20 , 5.0 )]} testSet = [[ 1.1 , '?' ], [ 19.1 , '?' ]] predictions = getPredictions(summaries, testSet) print ( 'Predictions: {0}' ). format (predictions) |
運(yùn)行測(cè)試,你會(huì)看到如下結(jié)果:
1
|
Predictions: [ 'A' , 'B' ] |
計(jì)算精度
預(yù)測(cè)值和測(cè)試數(shù)據(jù)集中的類別值進(jìn)行比較,可以計(jì)算得到一個(gè)介于0%~100%精確率作為分類的精確度。getAccuracy()函數(shù)可以計(jì)算出這個(gè)精確率。
1
2
3
4
5
6
|
def getAccuracy(testSet, predictions): correct = 0 for x in range ( len (testSet)): if testSet[x][ - 1 ] = = predictions[x]: correct + = 1 return (correct / float ( len (testSet))) * 100.0 |
我們可以使用如下簡(jiǎn)單的代碼來(lái)測(cè)試getAccuracy()函數(shù)。
1
2
3
4
|
testSet = [[ 1 , 1 , 1 , 'a' ], [ 2 , 2 , 2 , 'a' ], [ 3 , 3 , 3 , 'b' ]] predictions = [ 'a' , 'a' , 'a' ] accuracy = getAccuracy(testSet, predictions) print ( 'Accuracy: {0}' ). format (accuracy) |
運(yùn)行測(cè)試,你會(huì)得到如下結(jié)果:
1
|
Accuracy: 66.6666666667 |
合并代碼
最后,我們需要將代碼連貫起來(lái)。
下面是樸素貝葉斯Python版的逐步實(shí)現(xiàn)的全部代碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# Example of Naive Bayes implemented from Scratch in Python import csv import random import math def loadCsv(filename): lines = csv.reader( open (filename, "rb" )) dataset = list (lines) for i in range ( len (dataset)): dataset[i] = [ float (x) for x in dataset[i]] return dataset def splitDataset(dataset, splitRatio): trainSize = int ( len (dataset) * splitRatio) trainSet = [] copy = list (dataset) while len (trainSet) < trainSize: index = random.randrange( len (copy)) trainSet.append(copy.pop(index)) return [trainSet, copy] def separateByClass(dataset): separated = {} for i in range ( len (dataset)): vector = dataset[i] if (vector[ - 1 ] not in separated): separated[vector[ - 1 ]] = [] separated[vector[ - 1 ]].append(vector) return separated def mean(numbers): return sum (numbers) / float ( len (numbers)) def stdev(numbers): avg = mean(numbers) variance = sum ([ pow (x - avg, 2 ) for x in numbers]) / float ( len (numbers) - 1 ) return math.sqrt(variance) def summarize(dataset): summaries = [(mean(attribute), stdev(attribute)) for attribute in zip ( * dataset)] del summaries[ - 1 ] return summaries def summarizeByClass(dataset): separated = separateByClass(dataset) summaries = {} for classValue, instances in separated.iteritems(): summaries[classValue] = summarize(instances) return summaries def calculateProbability(x, mean, stdev): exponent = math.exp( - (math. pow (x - mean, 2 ) / ( 2 * math. pow (stdev, 2 )))) return ( 1 / (math.sqrt( 2 * math.pi) * stdev)) * exponent def calculateClassProbabilities(summaries, inputVector): probabilities = {} for classValue, classSummaries in summaries.iteritems(): probabilities[classValue] = 1 for i in range ( len (classSummaries)): mean, stdev = classSummaries[i] x = inputVector[i] probabilities[classValue] * = calculateProbability(x, mean, stdev) return probabilities def predict(summaries, inputVector): probabilities = calculateClassProbabilities(summaries, inputVector) bestLabel, bestProb = None , - 1 for classValue, probability in probabilities.iteritems(): if bestLabel is None or probability > bestProb: bestProb = probability bestLabel = classValue return bestLabel def getPredictions(summaries, testSet): predictions = [] for i in range ( len (testSet)): result = predict(summaries, testSet[i]) predictions.append(result) return predictions def getAccuracy(testSet, predictions): correct = 0 for i in range ( len (testSet)): if testSet[i][ - 1 ] = = predictions[i]: correct + = 1 return (correct / float ( len (testSet))) * 100.0 def main(): filename = 'pima-indians-diabetes.data.csv' splitRatio = 0.67 dataset = loadCsv(filename) trainingSet, testSet = splitDataset(dataset, splitRatio) print ( 'Split {0} rows into train={1} and test={2} rows' ). format ( len (dataset), len (trainingSet), len (testSet)) # prepare model summaries = summarizeByClass(trainingSet) # test model predictions = getPredictions(summaries, testSet) accuracy = getAccuracy(testSet, predictions) print ( 'Accuracy: {0}%' ). format (accuracy) main() |
運(yùn)行示例,得到如下輸出:
1
2
|
Split 768 rows into train = 514 and test = 254 rows Accuracy: 76.3779527559 % |