来自 奥门威尼斯网址 2019-10-04 14:11 的文章
当前位置: 威尼斯国际官方网站 > 奥门威尼斯网址 > 正文

机器学习之用Python从零落到实处贝叶斯分类器,

该系列由于种种因素更新会较慢,请多包涵!

使用乘法合并概率,在下面的calculClassProbilities()函数中,给定一个数据样本,它所属每个类别的概率,可以通过将其属性概率相乘得到。结果是一个类值到概率的映射。

由于笔者水平有限,目前由两种方式去预判:

Split 768 rows into train=514 and test=254 rows  Accuracy: 76.3779527559%  

笔者已提供一套已经搭建70%的基础,剩下30%的算法可以自行实现。比如爬取数据,从2000年开始(只要你愿意,从1976年开始爬取都行)的数据样本;比如规则数据样本;比如分布式协同运算(名词真拗口,就是多台机器一起算)等等。

x = 71.5  mean = 73  stdev = 6.2  probability = calculateProbability(x, mean, stdev)  print('Probability of belonging to this class: {0}').format(probability)  

呀,这是打算要卖什么狗皮膏药的广告吗?不是,其实我们程序员,或多或少,都会去研究某某抽奖平台的概率问题,笔者也不例外,说不定哪天就会天上掉下个大馅饼了呢!有些平台在我们伟大的天朝是被严厉禁止的,尽一切可能保证社会主义核心价值观...这些话咱不多说哈,以免招来杀生之祸^_^。详细内容可以下载本人的源码进行调试就可以知道结果,纯脚本式代码,写的搓,有强迫症的朋友请多包涵。

summaries = {'A':[(1, 0.5)], 'B':[(20, 5.0)]}  inputVector = [1.1, '?']  result = predict(summaries, inputVector)  print('Prediction: {0}').format(result)  

2:采用“组合算法”,组合了几十亿组公式来进行运算,结果嘛,算法写得搓,手头服务器资源不够,没有结果,要算半年多......

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  

 

我们也需要将以字符串类型加载进来属性转换为我们可以使用的数字。下面是用来加载匹马印第安人数据集(Pima indians dataset)的loadCsv()函数。

目录(忐忑的更新中)

用Python预测某某国际平台概率分析(一):这个到底是什么,是什么样的规则?

用Python预测某某国际平台概率分析(二):如何运行你的代码,这结果又是什么意思?

用Python预测某某国际平台概率分析(三):如何实现python爬虫?

用Python预测某某国际平台概率分析(四):如何预测某个数字不会在这个集合中?

用Python预测某某国际平台概率分析(五):组合算法很渣,有没有更好的算法实现?

......

我们可以定义一个具有5个样例的数据集来进行测试,首先它分为训练数据集和测试数据集,然后打印出来,看看每个数据样本最终落在哪个数据集。

重要提示:本着分享为目的,才能使技术进步,但是笔者还是希望,我们只是在讨论算法问题,就像在监督机器人如何去学习、去预测这过程中的实现问题,懂了就行,表要声张,也千万不要陷入进去,不然谁都救不了你的哦,笔者身边就有这样的朋友,最后家破人亡...

1.处理数据

1:通过统计学以及长久的一些猜想规则,记录并运算能准确取消的数字(也就是它不会出现在集合中),正确率高达90%以上。

计算所属类的概率:将一个数据样本归属于每个类的概率更新为一个比率。计算上就是将一个样本数据归属于某个类的概率,比上其归属于每一个类的概率的和。举例来说,一个样本属于类A的概率时0.02,属于类B的概率时0.001,那么样本属于类A的可能性是(0.02/(0.02+0.001))*100 大约为95.23%。

再次提示:世上没有100%的绝对,笔者分享的源码只是为了学习和研究概率方法论,千万不要陷入到这个圈子里面去了,否者一切跟笔者和平台无关。

提取数据特征

奥门威尼斯网址 1

合并代码

下面的predict()函数可以完成以上任务。

教程分为如下几步:

运行测试,你会看到如下结果:

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  

运行测试,你会看到如下结果:

在calculateProbability()函数中,我们首先计算指数部分,然后计算等式的主干。这样可以将其很好地组织成2行。

测试predict()函数如下:

关于朴素贝叶斯

计算均值

关于高斯概率密度函数,可以查看参考文献。总之,我们要把已知的细节融入到高斯函数(属性值,均值,标准差),并得到属性值归属于某个类的似然(译者注:即可能性)。

Attribute summaries: [(2.0, 1.0), (21.0, 1.0)] 

通过本教程,你将学到朴素贝叶斯算法的原理和Python版本的逐步实现。

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 summarize(dataset):  summaries = [(mean(attribute), stdev(attribute)) for attribute in zip(*dataset)]  del summaries[-1]  return summaries  
  1. 按类别划分数据
  2. 计算均值
  3. 计算标准差
  4. 提取数据集特征
  5. 按类别提取属性特征

多重预测

通过计算从1到5这5个数的均值来测试函数。

朴素贝叶斯模型包含训练数据集中数据的特征,然后使用这个数据特征来做预测。

已知每个属性和类值的属性特征,在给定类值的条件下,可以得到给定属性值的条件概率。

我们可以通过计算样本归属于每个类的概率,然后选择具有最高概率的类来做预测。

奥门威尼斯网址 2

既然可以计算一个数据样本属于每个类的概率,那么我们可以找到最大的概率值,并返回关联的类。

更新:查看后续的关于朴素贝叶斯使用技巧的文章“Better Naive Bayes: 12 Tips To Get The Most From The Naive Bayes Algorithm”

【编辑推荐】

filename = 'pima-indians-diabetes.data.csv'  dataset = loadCsv(filename)  print('Loaded data file {0} with {1} rows').format(filename, len(dataset))  

学习资源及深入阅读

每一个记录归属于一个类,这个类指明以测量时间为止,患者是否是在5年之内感染的糖尿病。如果是,则为1,否则为0。

Probability of belonging to this class: 0.0624896575937 

我们可以将这部分划分成以下任务:

def summarizeByClass(dataset):      separated = separateByClass(dataset)      summaries = {}      for classValue, instances in separated.iteritems():          summaries[classValue] = summarize(instances)      return summaries  
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  

对数概率:对于一个给定的属性值,每个类的条件概率很小。当将其相乘时结果会更小,那么存在浮点溢出的可能(数值太小,以至于在Python中不能表示)。一个常用的修复方案是,合并其概率的对数值。可以研究实现下这个改进。

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  

运行测试,你会得到如下结果:

dataset = [[1,20,1], [2,21,0], [3,22,1], [4,22,0]]  summary = summarizeByClass(dataset)  print('Summary by class value: {0}').format(summary)  

我们也需要计算每个类中每个属性的标准差。标准差描述了数据散布的偏差,在计算概率时,我们用它来刻画高斯分布中,每个属性所期望的散布。

测试calculateClassProbabilities()函数。

Split 5 rows into train with [[4], [3], [5]] and test with [[1], [2]] 
dataset = [[1,20,0], [2,21,1], [3,22,0]]  summary = summarize(dataset)  print('Attribute summaries: {0}').format(summary)  
summaries = {'A':[(1, 0.5)], 'B':[(20, 5.0)]}  testSet = [[1.1, '?'], [19.1, '?']]  predictions = getPredictions(summaries, testSet)  print('Predictions: {0}').format(predictions)  

这个问题包括768个对于皮马印第安患者的医疗观测细节,记录所描述的瞬时测量取自诸如患者的年纪,怀孕和血液检查的次数。所有患者都是21岁以上(含21岁)的女性,所有属性都是数值型,而且属性的单位各不相同。

既然我们可以计算一个属性属于某个类的概率,那么合并一个数据样本中所有属性的概率,最后便得到整个数据样本属于某个类的概率。

下面是朴素贝叶斯Python版的逐步实现的全部代码。

标准差是方差的平方根。方差是每个属性值与均值的离差平方的平均数。注意我们使用N-1的方法(译者注:参见无偏估计),也就是在在计算方差时,属性值的个数减1。

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)  

不同的密度函数(伯努利或者多项式):我们已经尝试了高斯朴素贝叶斯,你也可以尝试下其他分布。实现一个不同的分布诸如多项分布、伯努利分布或者内核朴素贝叶斯,他们对于属性值的分布 和/或 与类值之间的关系有不同的假设。

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  
Predictions: ['A', 'B'] 

预测

这一部分提供了一些用于学习更多朴素贝叶斯算法的资源,包括算法理论和工作原理,以及代码实现中的实际问题。

  • Applied Predictive Modeling, page 353
  • Data Mining: Practical Machine Learning Tools and Techniques, page 94
  • Machine Learning for Hackers, page 78
  • An Introduction to Statistical Learning: with Applications in R, page 138
  • Machine Learning: An Algorithmic Perspective, page 171
  • Machine Learning in Action, page 61 (Chapter 4)
  • Machine Learning, page 177 (chapter 6) 

计算高斯概率密度函数

  • Naive Bayes in Scikit-Learn:scikit-learn库中朴素贝叶斯的实现
  • Naive Bayes documentation:scikit-learn库中关于朴素贝叶斯的文档和样例代码
  • Simple Naive Bayes in Weka:朴素贝叶斯的Weka实现

下一步,我们将数据分为用于朴素贝叶斯预测的训练数据集,以及用来评估模型精度的测试数据集。我们需要将数据集随机分为包含67%的训练集合和包含33%的测试集(这是在此数据集上测试算法的通常比率)。

提取数据集的特征

奥门威尼斯网址 ,朴素贝叶斯分类器,Matt Buck保留部分版权

朴素贝叶斯算法是一个直观的方法,使用每个属性归属于某个类的概率来做预测。你可以使用这种监督性学习方法,对一个预测性建模问题进行概率建模。

到此,你已经使用Python一步步完成了高斯版本的朴素贝叶斯。

下面是pima-indians.data.csv文件中的一个样本,了解一下我们将要使用的数据。

我们现在可以使用从训练数据中得到的摘要来做预测。做预测涉及到对于给定的数据样本,计算其归属于每个类的概率,然后选择具有最大概率的类作为预测结果。

运行测试,你会看到如下结果:

本文由威尼斯国际官方网站发布于奥门威尼斯网址,转载请注明出处:机器学习之用Python从零落到实处贝叶斯分类器,

关键词: