四大门户网站的优缺点,推广网络网站,前端开发语言有哪几种,内丘网站开始
其实在学习机器学习的一些算法#xff0c;最近也一直在看这方面的东西#xff0c;并且尝试着使用Matlab进行一些算法的实现。这几天一直在看得就是贝叶斯算法实现一个分类问题。大概经过了一下这个过程#xff1a;
看书→算法公式推演→网上查询资料→进一步理解→搜…开始
其实在学习机器学习的一些算法最近也一直在看这方面的东西并且尝试着使用Matlab进行一些算法的实现。这几天一直在看得就是贝叶斯算法实现一个分类问题。大概经过了一下这个过程
看书→\rightarrow算法公式推演→\rightarrow网上查询资料→\rightarrow进一步理解→\rightarrow搜集数据集开始尝试→\rightarrow写代码→\rightarrow调试→\rightarrow代码整理与优化→\rightarrow自编代码结果与Matlab自带函数fitcnb结果对比验证→\rightarrow朴素贝叶斯算法优缺点总结
经过这几天的努力总算是把这个算法彻底弄明白了也发现很多算法只有自己去亲自写一写才会发现自己的不足还是需要多努力。
贝叶斯分类 分类问题理解 贝叶斯分类是一类分类算法的总称这类算法以贝叶斯定理为基础因此称之为贝叶斯分类。 而对于分类问题其实谁都不会陌生说我们每个人每天都在执行分类操作一点都不夸张只是我们没有意识到罢了。例如当你看到一个陌生人你的脑子下意识判断TA是男是女你可能经常会走在路上对身旁的朋友说“这个人一看就很有钱、那边有个非主流”之类的话其实这就是一种分类操作。 从数学角度来说分类问题可做如下定义 已知集合C{y1,y2,…,yn}\\{C=\{y_1,y_2,\ldots,y_n\}}和I{x1,x2,…,xm,…}\\I=\{x_1,x_2,\ldots,x_m,\ldots\}确定映射规则yf(x)\\y=f(x)使得任意的x∈I\\x\in I有且仅有一个yi∈C\\y_i\in C使得yif(xi)\\y_i=f(x_i)成立。 其中C\\C叫做类别集合其中每一个元素是一个类别而I\\I叫做项集合其中每一个元素是一个待分类项f\\f叫做分类器。分类算法的任务就是构造分类器f\\f。 这里要着重强调分类问题往往采用经验性方法构造映射规则即一般情况下的分类问题缺少足够的信息来构造100%正确的映射规则而是通过对经验数据的学习从而实现一定概率意义上正确的分类因此所训练出的分类器并不是一定能将每个待分类项准确映射到其分类分类器的质量与分类器构造方法、待分类数据的特性以及训练样本数量等诸多因素有关。贝叶斯定理 该定理最早Thomas Bayes发明显然这个定理可能就是为了纪念他而已他的名字命名的吧。这个定理是概率论中的一个结论大学学习概率论的时候学习过的。它是跟随机变量的条件概率以及边缘概率分布有关的。该定理可以让人们知道如何用新的信息进行以后看法或者结论的修改。一般来说事件A在事件B已经发生的条件下发生的概率与事件B在事件A已经发生的条件下发生的概率是不一样的。但是这个两者是有一定的联系的。下面就开始搬出这个伟大的定理 P(X,Y)P(Y|X)P(X)P(X|Y)P(Y)\\P(X,Y)=P(Y|X)P(X)=P(X|Y)P(Y) 那么对这个公式进行变形有 P(Y|X)P(X|Y)P(Y)P(X)\\P(Y|X)=\frac{P(X|Y)P(Y)}{P(X)} 由上面可以看出来这个定理允许使用先验概率P(Y)\\P(Y)、条件概率P(X|Y)\\P(X|Y)和证据P(X)\\P(X)来表示后验概率。朴素贝叶斯分类原理 朴素贝叶斯分类是一种十分简单的分类算法叫它朴素贝叶斯分类是因为这种方法的思想真的很朴素。 朴素贝叶斯的思想基础是这样的对于给出的待分类项求解在此项出现的条件下各个类别出现的概率哪个最大就认为此待分类项属于哪个类别。 通俗来说就好比这么个道理你在街上看到一个黑人我问你你猜这哥们哪里来的你十有八九猜非洲。为什么呢因为黑人中非洲人的比率最高当然人家也可能是美洲人或亚洲人但在没有其它可用信息下我们会选择条件概率最大的类别这就是朴素贝叶斯的思想基础。 朴素贝叶斯分类器建立在一个类条件独立性假设朴素假设的基础之上给定类变量后各个变量之间相互独立。根据朴素贝叶斯独立性假设有 P(X|Ci)∏mk1P(XK|Ci)\\P(X|C_i)=\prod_{k=1}^mP(X_K|C_i) 其中当给定训练数据集的时候条件概率P(X1|Ci)P(X2|Ci),P(X3|Ci),...,P(Xn|Ci)P(X1|Ci)P(X2|Ci),P(X3|Ci),...,P(Xn|Ci)可以算出来因此根据这个方法对一个未知类别的样本X\\X,可以先分别计算X\\X属于每个类别Ci\\C_i的概率P(X|Ci)P(Ci)\\P(X|C_i)P(C_i),然后选择其中概率最大的类别作为其类别。算法流程 朴素贝叶斯分类的一个基本算法流程为 1设x{x1,x2,…,xm}\\x=\{x_1,x_2,\ldots,x_m\}为一个待分类的项而每一个xi\\x_i为x\\x的一个属性每一个属性有k\\k个取值xi{a1,a2,…,ak}\\x_i=\{a_1,a_2,\ldots,a_k\} 2有一个类别集合C{y1,y2,…,yn}\\C=\{y_1,y_2,\ldots,y_n\} 3计算P(y1|x),P(y2|x),...,P(yn|x)\\P(y_1|x),P(y_2|x),...,P(y_n|x) 4如果P(yk|x)max{P(y1|x),P(y2|x),...,P(yn|x)}P(y_k|x)=max\{P(y_1|x),P(y_2|x),...,P(y_n|x)\},则x∈yk\\x\in y_k 因此从上面我们可以看出来该算法的关键步骤就是第3中的各个条件概率的计算基于独立性假设可以这样计算 1、找到一个已知分类的待分类项集合这个集合叫做训练样本集。 2、统计得到在各个类别下各个特征属性的条件概率估计值即 P(a1|y1),P(a2|y1),...,P(am|y1)\\P(a_1|y_1),P(a_2|y_1),...,P(a_m|y_1) P(a1|y2),P(a2|y2),...,P(am|y2)\\P(a_1|y_2),P(a_2|y_2),...,P(a_m|y_2) ⋮\vdots P(a1|y1),P(a2|y1),...,P(am|y1)\\P(a_1|y_1),P(a_2|y_1),...,P(a_m|y_1) 3、如果各个特征属性是条件独立的则根据贝叶斯定理有如下推导 P(yi|x)P(x|yi)P(yi)P(x)\\P(y_i|x)=\frac{P(x|y_i)P(y_i)}{P(x)} 因为分母对于所有类别来说都是常数因此该算法就是求解分子最大化问题。因为各个特征属性之间是条件独立的所以有 依据上面的分析可以得到朴素贝叶斯分类的一个基本流程图如下 Matlab程序实现 程序 使用Matlab实现朴素贝叶斯算法的数据来源http://archive.ics.uci.edu/ml/machine-learning-databases/balance-scale/balance-scale.data。 不多说先开始上程序吧
clc
clear
close all
dataimportdata(data.txt);
wholeDatadata.data;
%交叉验证选取训练集和测试集
cvcvpartition(size(wholeData,1),holdout,0.04);%0.04表明测试数据集占总数据集的比例
trainDatawholeData(training(cv),:);
testDatawholeData(test(cv),:);
labeldata.textdata;
attributeNumbersize(trainData,2);
attributeValueNumber5;
%%
%将分类标签转化为数据
sampleNumbersize(label,1);
labelDatazeros(sampleNumber,1);
for i1:sampleNumberif label{i,1}RlabelData(i,1)1;elseif label{i,1}BlabelData(i,1)2;else labelData(i,1)3;end
end
trainLabellabelData(training(cv),:);
trainSampleNumbersize(trainLabel,1);
testLabellabelData(test(cv),:);
%计算每个分类的样本的概率
labelProbabilitytabulate(trainLabel);
%P_yi,计算P(yi)
P_y1labelProbability(1,3)/100;
P_y2labelProbability(2,3)/100;
P_y3labelProbability(3,3)/100;
%%
%
count_1zeros(attributeNumber,attributeValueNumber);%count_1(i,j):y1情况下第i个属性取j值的数量统计
count_2zeros(attributeNumber,attributeValueNumber);%count_1(i,j):y2情况下第i个属性取j值的数量统计
count_3zeros(attributeNumber,attributeValueNumber);%count_1(i,j):y3情况下第i个属性取j值的数量统计
%统计每一个特征的每个取值的数量
for jj1:3for j1:trainSampleNumberfor ii1:attributeNumberfor k1:attributeValueNumberif jj1if trainLabel(j,1)1trainData(j,ii)kcount_1(ii,k)count_1(ii,k)1;endelseif jj2if trainLabel(j,1)2trainData(j,ii)kcount_2(ii,k)count_2(ii,k)1;endelseif trainLabel(j,1)3trainData(j,ii)kcount_3(ii,k)count_3(ii,k)1;endendendendend
end
%计算第i个属性取j值的概率P_a_y1是分类为y1前提下取值其他依次类推。
P_a_y1count_1./labelProbability(1,2);
P_a_y2count_2./labelProbability(2,2);
P_a_y3count_3./labelProbability(3,2);
%%
%使用测试集进行数据测试
labelPredictNumberzeros(3,1);
predictLabelzeros(size(testData,1),1);
for kk1:size(testData,1)testDataTemptestData(kk,:);Pxy11;Pxy21;Pxy31;%计算Px|yifor iii1:attributeNumberPxy1Pxy1*P_a_y1(iii,testDataTemp(iii));Pxy2Pxy2*P_a_y2(iii,testDataTemp(iii));Pxy3Pxy3*P_a_y3(iii,testDataTemp(iii));end%计算P(x|yi)*P(yi)PxyPy1P_y1*Pxy1;PxyPy2P_y2*Pxy2;PxyPy3P_y3*Pxy3;if PxyPy1PxyPy2PxyPy1PxyPy3predictLabel(kk,1)1;disp([this item belongs to No.,num2str(1), label or the R label])labelPredictNumber(1,1)labelPredictNumber(1,1)1;elseif PxyPy2PxyPy1PxyPy2PxyPy3predictLabel(kk,1)2;labelPredictNumber(2,1)labelPredictNumber(2,1)1;disp([this item belongs to No.,num2str(2), label or the B label])elseif PxyPy3PxyPy2PxyPy3PxyPy1predictLabel(kk,1)3;labelPredictNumber(3,1)labelPredictNumber(3,1)1;disp([this item belongs to No.,num2str(3), label or the L label])end
end
testLabelCounttabulate(testLabel);
% 计算混淆矩阵
disp(the confusion matrix is : )
C_Bayesconfusionmat(testLabel,predictLabel)以上部分就是针对于这个已有的数据集进行的算法的实现。
结果与分析 C_Bayes是计算出来的混淆矩阵。 其结果为 C_Bayes8300000014\begin{matrix}8 我再使用了Matlab自带的贝叶斯算法的函数fitcnb进行该数据的分类测试
Nbfitcnb(trainData,trainLabel);
y_nbNb.predict(testData);
C_nbconfusionmat(testLabel,y_nb)其中C_nb是采用自带函数得到的结果的混淆矩阵 其结果为 C_nb
8300000014
\begin{matrix}8 我改变了交叉验证中训练集和测试集的比例设置为0.2 此时采用自编程序得到的混淆矩阵为 C_Bayes63400000552
\begin{matrix}63 C_nb63400000552
\begin{matrix}63 可以发现整个朴素贝叶斯分类分为三个阶段。 ①. 准备阶段。包括数据搜集数据导入以及数据清洗阶段。获得可以进行分析的质量比较好的结果。然后将数据划分为训练集和测试集。 ②. 构建分类器进行数据训练。要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率估计并将结果记录。其输入是特征属性和训练样本输出是分类器。这一阶段是机械性阶段根据前面讨论的公式可以由程序自动计算完成。 ③. 第三阶段——应用阶段。这个阶段的任务是使用分类器对待分类项进行分类其输入是分类器和待分类项输出是待分类项与类别的映射关系。这一阶段也是机械性阶段由程序完成。朴素贝叶斯算法成立的前提是各个属性之间是相互独立的。当数据集满足这个独立性假设的时候分类的准确率较高否则就可能不是很好。朴素贝叶斯分类算法的特点 ①. 这个算法比较的就简单但是却很高效在朴素贝叶斯的假设前提之下分类结果准确率很高。 ②. 同样如果属性之间存在一个相关性联系的话这个分类的精度就会大大降低。因为此时的独立性假设就会不成立导致计算得到的条件概率均出现不同程度的偏差。
艾勇-上海交通大学 2017/7/19