#!/usr/bin/env python
# coding: utf-8
#
Table of Contents
#
# ## 机器学习
# ### 基本概念
# 样本、
# 属性、
# 样本空间、
# 样例:(属性)$\rightarrow$ 标记、
# 标记:关于事例结果的信息、
# 分类:预测对象为离散值;
# 回归:预测对象为连续值。
# 监督学习:训练数据有标记信息;
# 无监督学习:训练数据无标记信息。
# 学得模型适用于新样本的能力,称为泛化能力。
# ### 样本集、训练集、测试集
# 
# #### 欠拟合 过拟合
# 
# 
# 
# #### 样本集 测试集 的 选取方法
# ##### 留出法
# "留出法"(hold-out)直接将数据集D划分为两个互斥的集和。
# 训练/测试集的划分要尽可能保持数据分布的一致性, 避免因数据划分过程引入额外的偏差而对最终结果产生影响。 如果从采样的角度来看待数据集的划分过程, 则保留类别比列的采样方式通常称为“分层采样”。
# 通常的做法是将大约2/3~4/5的样本用于训练, 剩余样本用于测试。
#
# ##### 交叉验证法
# “交叉验证法”(cross validation)先将数据集D划分为k个大小相似的互斥子集, 每个子集都尽可能保持数据分布的一致性, 也就是从D中通过分层采样得到。 然后每次选k-1个子集的并集作为训练集, 剩余的那个子集作为测试集, 这样就可以得到k组训练/测试集。然后进行k次训练和测试, 最终返回的是k个测试结果的均值。
# 显然, 交叉验证法评估结果的稳定性和保真性在很大程度上取决于k的取值。通常交叉验证法又称为“k折(倍)交叉验证”(k-fold cross validation)。k通常的取值是10、5、20。
# 对数据集D划分为k个子集有多种不同的划分。 为减少因样本划分不同而引入的误差, k折交叉验证通常要随机使用不同的划分重复p次, 最终的评估结果是p次k折交叉验证结果的均值。 例如常见的有“10次10折交叉验证”。
# 
# ## 贝叶斯分类器
# ### 贝叶斯概念
# $$P(A∩B)=P(B\mid A)P(A)=P(A\mid B)P(B)$$
# $$P(A\mid B) = \frac{P(B\mid A)P(A)}{P(B)}$$
# 通常,事件A在事件B(发生)的条件下的概率,与事件B在事件A的条件下的概率是不一样的
# 教学提示:
# 学生需要的前期数学知识
# 1、概率基本公理
# 工具:维恩图(Venn diagram)
# 2、条件概率、全概率公式
# 3、贝叶斯公式
# 4、概率分布
# 均值、方差、密度函数、高斯分布
#
# 
# ### Native Bayes
# 朴素贝叶斯分类器,即Native Bayes,简称NB算法。
#
# 给定一个训练数据集,对新的输入实例,在训练数据集上采用“属性条件独立假设”并使用联合概率进行计算的分类器。
# #### 实践
# 某网站需要对用户进行Pop Window广告推荐,方法是根据用户之前的数据进行计算,需要根据计算结果 推荐不同的商品广告。
# 某购物网站用户信息
# 
# 新来了两个用户,知道他们的嗜好,该给他们推送哪个?
# 样本集划分
# 
# #### 第一步 Bayes公式的分析
# 公式一:
# 公式二:
# 公式三:
# #### 第二步 数据集与贝叶斯公式的关系
# P(C)=Dc/D ,classify
#
# 比如本例:
#
# P(B)=7/12
#
# P(Ls)=5/12
# 
# 公式4:
# 注意这里的分母是Dc,指“分类(c)的样本计数”,而不是整体样本数。
# 而P(Xi|C) 按分类标记和成分统计条件概率为:
# 例如 “电玩”成分
#
# P(电玩T|B)=6/7=0.857
#
# P(电玩F|B)=1/7=0.143
#
# P(电玩T|Ls)=2/5=0.4
#
# P(电玩F|Ls)=3/5=0.6
# 
# ##### 0值处理
# 
# ##### 第三步 实际数据分析示例
# 
# 为了简化示例,只看后面四个属性
# 
# 测试样本8 $\frac{7}{12}*\frac{4}{7}*\frac{2}{7}*\frac{6}{7}*\frac{6}{7}=0.06997$
#
# $\frac{5}{12}*\frac{1}{5}*\frac{3}{5}*\frac{1}{5}*\frac{2}{5}=0.004$
#
# $0.06997>0.004$
# 得到结果是啤酒,同理算出测试样本9,也是口红,说明刚才建立的模型测试准确率是100%
# #### 用scikit-learn实现
# 在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB,MultinomialNB和BernoulliNB。其中GaussianNB就是先验为高斯分布的朴素贝叶斯,MultinomialNB就是先验为多项式分布的朴素贝叶斯,而BernoulliNB就是先验为伯努利分布的朴素贝叶斯。
#
# 这三个类适用的分类场景各不相同,一般来说,如果样本特征的分布大部分是连续值,使用GaussianNB会比较好。如果如果样本特征的分大部分是多元离散值,使用MultinomialNB比较合适。而如果样本特征是二元离散值或者很稀疏的多元离散值,应该使用BernoulliNB。
# In[6]:
#coding:utf-8
import pandas as pd
import numpy as np
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
# from sklearn import neighbors
# of=open('data.csv','rb')
# da1=[]
# da2=[]
#获取数据,调整格式
# for line in of:
# li_t=line.split(',')
# da2.append(int(li_t[0]))
# da1.append([int(li_t[1]),int(li_t[2]),int(li_t[3]),int(li_t[4]),int(li_t[5])])
da1=[[3, 1, 0, 0, 1], [4, 0, 0, 1, 0], [2, 1, 1, 0, 1], [2, 0, 0, 0, 1],
[0, 1, 1, 0, 1], [1, 0, 0, 0, 1], [1, 1, 0, 0, 1], [0, 0, 1, 1, 0],
[1, 0, 1, 1, 0], [1, 1, 0, 1, 0], [3, 0, 1, 0, 1], [1, 0, 0, 1, 1],
[0, 1, 1, 0, 1], [2, 0, 1, 1, 0]]
da2=[0, 0, 0, 0, 0, 0,0, 1, 1, 1, 1, 1, 0, 1]
cou=int(len(da1)*0.9)
#获取训练数据和测试数据
train_x=da1[:cou]#训练数据x
test_x=da1[cou:]#测试数据y
train_y=da2[:cou]#训练数据y
test_y=da2[cou:]#测试数据y
gnb=GaussianNB()#定义高斯贝叶斯
fit1=gnb.fit(train_x,train_y)#训练
pre=gnb.predict(test_x)#测试
r_n=(test_y==pre).sum()#比较测试结果和正确结果,得到正确率
print "高斯贝叶斯:总测试条数:%d, 贝叶斯正确率:%f%%"%(len(test_x),float(r_n/len(test_x)*100))
pp=gnb.predict([[2,1,0,0,1]])#利用训练得到的模型,预测一个数据
print pp[0]
mnb=MultinomialNB()
fit1=mnb.fit(train_x,train_y)#训练
pre=mnb.predict(test_x)#测试
r_n=(test_y==pre).sum()#比较测试结果和正确结果,得到正确率
print "多项式贝叶斯:总测试条数:%d, 贝叶斯正确率:%f%%"%(len(test_x),float(r_n/len(test_x)*100))
pp=mnb.predict([[2,1,0,0,1]])#利用训练得到的模型,预测一个数据
print pp[0]
# knn=neighbors.KNeighborsClassifier()
# fit2=knn.fit(train_x,train_y)
# pre1=knn.predict(test_x)
# r_n1=(test_y==pre1).sum()
# print "总测试条数:%d, KNN正确率:%f%%"%(len(test_x),float(r_n1/len(test_x)*100))
# In[ ]: