首页 > 编程知识 正文

python实现贝叶斯算法,python手写单词识别编程

时间:2023-05-05 20:30:53 阅读:151337 作者:884

一.朴素贝叶斯分类器原理

朴素贝叶斯方法是基于贝叶斯公式和特征条件独立这一假设的分类方法。 对给定的训练数据集,基于特征条件的独立假设,通过学习输入输出的联合概率分布,学习生成模型,基于该模型,对给定的测试样本

,利用贝叶斯公式求出输出概率(或概率密度)最大的输出。 具体情况如下

在训练中,被给予的

标记为带标签的数据

其中

维度(特征向量) (即实例点)通常是

点击

此实例点的标签表示此点的类别,位于离散集合中

取值(假设共享

个类别)。 贝叶斯分类器中存在联合分布的假设

、训练数据

是从这个分布中独立出来的。 其次,我想根据训练中的数据推测这个联合分布。 因为

所以我们先做对了

推测的分布。 因为

只取有限个的值。 在训练数据集中,根据频率估计概率。 这也是概率的最大似然估计。

这样就推算出了随机变量

的分布规律。

接下来,在每个类别中

的分布,也就是故意。 因为

维度空间取值。 我们就是这样

的分布分两种简单情况讨论:

1、分门别类:

的各维度

值有限,也就是说

是离散型随机变量,在这种情况下,使用训练数据集进行估计

的分布如下。

第二种估计很难,但加上条件独立性假设。 也就是说,在同一类别内

各成分的可取值是独立的。 这样的假设大大简化了处理问题的难度,但却损害了精度。 这就是朴素贝叶斯名称“朴素”的由来。 这样,上面的公式

这样,这部分的计算就变得简单了。 用频率代替概率。

考虑随机变量

因为的某一维可能值不会出现在训练样本中,所以获得该维具有该值的所有样本的概率为0,且这样的估计被认为是不准确的。 没有出现在训练样本中,说明出现的概率很低。 为了防止出现的概率为0,对上述推测导入霸气的仙人掌进行平滑,即导入正数

,将上述估计公式更改为

容易验证上式也是概率分布。 时光流逝

时间是最大似然估计。

这样就推定了联合分布

、测试集中的数据

中选择所需的族。 根据上述求出的分布函数,计算属于各类别的概率的大小,即

,将该样本预测为条件概率最大的类。 对于同一样品,以上各式的分母相同,只需比较即可

的大小,将该样本预测为条件概率最大的类。

2、各类

都是连续分布

我们必须估计各类的分布。 根据数据推测分布很复杂。 为了简单起见,假设各级分布是多元正态分布,则针对各级的分布估计问题是多元正态分布的参数估计问题。 对于每一类,用样本均值分别替换总体均值,用样本协方差替换总体协方差,就得到了每一类的密度函数。 关于

的报价与情况1相同。 这样就得到了类概率密度的估计值。 测试集中的数据

计算下一个概率

密度:

并将该样本归类到使得上式达到最大的类。同理,由于对于同个样本,上面

个式子的分母是一样的,所以我们只需要计算比较

的大小,并把该数据预测为使得上式达到最大的类。

二、用主成分分析+贝叶斯分类器实现手写数字的分类

这里仍然使用

数据集,该数据集的格式与导入,我们在上文《KNN与手写数字分类的实现》中有详细的介绍

由于这里的每个数据的维数(每张照片,对应训练数据矩阵与测试数据矩阵的每一列)为

,维度较高,直接应用贝叶斯分类器,计算复杂度较高,而这些数据具有较强的相关性,我们先使用主成分分析进行降维:将维度降低到

,然后假设每一类的分布都是多元正态分布,估计类条件概率密度。最后对测试集中的数据进行分类,源代码如下所示(这个代码写得非常垃圾,大量地方可以用矩阵之类的东西代替,可以降低时间复杂度的,但是今天不想动脑,就大量重复了代码片段,使用了大量循环,导致运行非常慢。以后有时间再来更新hhh)

读取训练数据与测试数据的代码

function images = loadMNISTImages(filename)

fp = fopen(filename, 'rb');

assert(fp ~= -1, ['Could not open ', filename, '']);

magic = fread(fp, 1, 'int32', 0, 'ieee-be');

assert(magic == 2051, ['Bad magic number in ', filename, '']);

numImages = fread(fp, 1, 'int32', 0, 'ieee-be');

numRows = fread(fp, 1, 'int32', 0, 'ieee-be');

numCols = fread(fp, 1, 'int32', 0, 'ieee-be');

images = fread(fp, inf, 'unsigned char');

images = reshape(images, numCols, numRows, numImages);

images = permute(images,[2 1 3]);

fclose(fp);

% Reshape to #pixels x #examples

images = reshape(images, size(images, 1) * size(images, 2), size(images, 3));

% Convert to double and rescale to [0,1]

images = double(images) / 255;

end

读取标签的代码

function labels = loadMNISTLabels(filename)

fp = fopen(filename, 'rb');

assert(fp ~= -1, ['Could not open ', filename, '']);

magic = fread(fp, 1, 'int32', 0, 'ieee-be');

assert(magic == 2049, ['Bad magic number in ', filename, '']);

numLabels = fread(fp, 1, 'int32', 0, 'ieee-be');

labels = fread(fp, inf, 'unsigned char');

assert(size(labels,1) == numLabels, 'Mismatch in label count');

fclose(fp);

end

分类源代码

%调用自定义函数,读取60000张照片,记为Train

Train=loadMNISTImages('train-images.idx3-ubyte');

%读入标签,对60000时尚的吐司图片进行分类

Trainlabels=loadMNISTLabels('train-labels.idx1-ubyte');

%调用自定义函数,读取10000张测试照片,记为Test

Test=loadMNISTImages('t10k-images.idx3-ubyte');

%读取测试集标签

Testlabel=loadMNISTLabels('t10k-labels.idx1-ubyte');

[m1,n1]=size(Train);

[m2,n2]=size(Test);

%求总体协方差矩阵COV(X,Y)=E{(X-u)(X-u)'}

u=sum(Train,2)/n1;

COV=(Train-u*ones(1,n1))*(Train-u*ones(1,n1))'/n1;

%求前50个主成分方向

[eigenvactor,eigenvalue]=eig(COV);

P=(eigenvactor(:,m1-50+1:m1))';

%投影得到每个照片的50个新特征

newfeature=P*Train;

%将用PCA降维之后的数据按标签分成10类,分别为M{1,1}...M{1,10}

count=ones(1,10);

for i=1:60000

M{1,Trainlabels(i,1)+1}(:,count(1,Trainlabels(i,1)+1))=newfeature(:,i);

count(1,Trainlabels(i,1)+1)=count(1,Trainlabels(i,1)+1)+1;

end

%计算每一类的均值向量,第i类的均值向量为矩阵u1的第i列

for i=1:10

[SIZE(i,1),SIZE(i,2)]=size(M{1,i});

u1(:,i)=(sum(M{1,i},2))/SIZE(i,2);

end

%计算每一类的协方差矩阵,记为COV1{1,1}...COV1{1,10}

for i=1:10

COV1{1,i}=(M{1,i}-u1(:,i)*ones(1,SIZE(i,2)))*(M{1,i}-u1(:,i)*ones(1,SIZE(i,2)))'/SIZE(i,2);

end

%计算每一类的先验概率,pr的第i行为第i类的先验概率

pr=SIZE(:,2)/n1;

%测试集投影到50个主方向

X=P*Test;

%计算测试集中的每个照片属于每类的后验概率,并通过最大值进行分类

for i=1:10000;

for j=1:10;

Q(1,j)=-(X(:,i)-u1(:,j))'*(inv(COV1{1,j}))*(X(:,i)-u1(:,j))-2*log(det(COV1{1,j}))+2*log(pr(j,1));

end

[m,n]=max(Q);

k=n-1;

NL(i,1)=k;

end

T=NL(:,1);

%统计分类正确的照片个数,记为s

s=0;

for i=1:10000

if Testlabel(i,1)==T(i,1)

s=s+1;

end

end

%输出准确率

accuracy=s/n2;

分类的准确率为

,在我电脑上运行时间10s左右。

在上文中,我用主成分分析将

维数据降低成

维。下面讨论降低到的维数

与准确率的关系,可得到如图所示的数据

与准确率的关系拟合拟合出来,如下所示

从实验结果可以看出,随着

的增加,准确率先增大,后几乎维持不变。一开始准确率随

增大而增大,因为m过小,不足以包含原数据大部分信息,所以随着 m 增大,原数据保留的有用信息越来越多, 所以准确率越来越高。当

充分大时,原数据有用的信息几乎被全部利用了,再增大

,反而会引入大量冗余信息,准确率不会继续提高。由于在实验原理中做了大量理想化假设,而且该实验方法是基于数理统计的,即使不压缩准确率也不可能达到百分之百,这是由统计学习方法本身所决定的。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。