Stanford机器学习课程笔记2-高斯判别分析与朴素贝叶斯

转载请注明出处: http://xiahouzuoxin.github.io/notes/

判别学习算法和生成学习算法

  • 判别学习算法:直接学习p(y|x),即直接通过输入特征空间x去确定目标类型{0,1},比如Logistic Regression和Linear Regression以及感知学习算法都是判别学习算法。

  • 生成学习算法:不直接对p(y|x)建模,而是通过对p(x|y)和p(y)建模。比如,y表示目标是dog(0)还是elephant(1),则p(x|y=1)表示大象的特征分布,p(x|y=0)表示狗的特征分布。下面的高斯判别分析和朴素贝叶斯算法都是生成学习算法。

生成学习算法通过学习p(y|x)和p(y),一般都要通过贝叶斯公式转化为p(x|y)来进行预测。

最大释然估计也可以转换为联合概率的最值。

高斯判别分析(Gaussian Discriminant Analysis)

对于输入特征x是连续值的随机变量,使用高斯判别分析模型非常有效,它对p(x|y)使用高斯分布建模。

,其中p为先验概率

依据前面对生成学习算法的分析,求联合概率的最大似然估计,

求得4个参数值及其直观解释为:

直观含义:类目1的样本数占总样本数的比例,即先验概率,类目0的先验概率刚好是 1????

直观含义:类目0每个维度特征的均值,结果是nx1的向量,n为特征维度

直观含义:类目1每个维度特征的均值,结果是nx1的向量

下面随机产生2类高斯分布的数据,使用高斯判别分析得到的分界线。分界线的确定:P(y=1|x)=p(y=0|x)=0.5

% Gaussian Discriminate Analysis
clc; clf;
clear all

% 随机产生2类高斯分布样本
mu = [2 3];
SIGMA = [1 0; 0 2];
x0 = mvnrnd(mu,SIGMA,500);
y0 = zeros(length(x0),1);
plot(x0(:,1),x0(:,2),‘k+‘, ‘LineWidth‘,1.5, ‘MarkerSize‘, 7);
hold on;
mu = [7 8];
SIGMA = [ 1 0; 0 2];
x1 = mvnrnd(mu,SIGMA,200);
y1 = ones(length(x1),1);
plot(x1(:,1),x1(:,2),‘ro‘, ‘LineWidth‘,1.5, ‘MarkerSize‘, 7)

x = [x0;x1];
y = [y0;y1];
m = length(x);

% 计算参数: \phi,\u0,\u1,\Sigma
phi = (1/m)*sum(y==1);
u0 = mean(x0,1);
u1 = mean(x1,1);
x0_sub_u0 = x0 - u0(ones(length(x0),1), :);
x1_sub_u1 = x1 - u1(ones(length(x1),1), :);
x_sub_u = [x0_sub_u0; x1_sub_u1];
sigma = (1/m)*(x_sub_u‘*x_sub_u);

%% Plot Result
% 画分界线,Ax+By=C
u0 = u0‘;
u1 = u1‘;
a=sigma‘*u1-sigma‘*u0;
b=u1‘*sigma‘-u0‘*sigma‘;
c=u1‘*sigma‘*u1-u0‘*sigma‘*u0;
A=a(1)+b(1);
B=a(2)+b(2);
C=c;
x=-2:10;
y=-(A.*x-C)/B;
hold on;
plot(x,y,‘LineWidth‘,2);

% 画等高线
alpha = 0:pi/30:2*pi;
R = 3.3;
cx = u0(1)+R*cos(alpha);
cy = u0(2)+R*sin(alpha);
hold on;plot(cx,cy,‘b-‘);
cx = u1(1)+R*cos(alpha);
cy = u1(2)+R*sin(alpha);
plot(cx,cy,‘b-‘);

% 加注释
title(‘Gaussian Discriminate Analysis(GDA)‘);
xlabel(‘Feature Dimension (One)‘);
ylabel(‘Feature Dimension (Two)‘);
legend(‘Class 1‘, ‘Class 2‘, ‘Discriminate Boundary‘);

朴素贝叶斯算法(Naive Bayesian)

相较于高斯判别分析,朴素贝叶斯方法的假设特征之间条件条件,即有:

特别注意:特征之间条件独立是强假设。比如文本上下文的词汇之间必然存在关联(比如出现‘qq‘和‘腾讯‘这两个词就存在关联),只是我们的假设不考虑这种关联,即使如此,有时候Bayesian的效果还是非常棒,朴素贝叶斯常用语文本分类(比如最常见的垃圾邮件的检测)。下面是一份非常直观的以实例的方式介绍贝叶斯分类器的文档(如果显示不出来请换用Chrome浏览器或转到原文地址原文,我后面的python代码也将用文档中的数据做example),

看完上面的文稿,我们再来说明理论点的建模。Naive Bayesian对先验概率和似然概率进行建模,不妨设 ?i|y?=?1?=?p(xi?=?1|y?=?1) , ?i|y?=?0?=?p(xi?=?1|y?=?0) , ?y?=?p(y?=?1) , 则又联合概率的似然函数最大,

求解得到先验概率和似然概率:

直观含义:类目1中出现特征xj的频率,实际实现时只要通过频次进行计数即可

直观含义:类目0中出现特征xj的频率,实际实现时只要通过频次进行计数即可

直观含义:类目1的样本数占总样本数的比例,即先验概率,类目0的先验概率刚好是 1???? ,这个和GDA的结果是相同的。

这里有个Trick,为什么不要对“证据因子”p(x)建模呢,(1)首先,p(x)可以通过似然概率和先验概率求得;(2)其次,p(x)的作用主要是起到概率归一化的效果,我们可以直接在程序中对最后的p(x,y)进行归一化就得到了p(y|x)。有了上面的结论,即已知先验概率和似然概率,很容易求的p(y=1|x)和p(y=0|x)。比较p(y=1|x)与p(y=0|x)的大小,若p(y=1|x)>p(y=0|x)则分类到类目1,p(y=0|x)>p(y=1|x)则分类为类目0。下面是我用python实现的Naive Bayesian(今后还是少用Matlab,多用python吧,毕竟Matlab只适合研究不能成产品。。。),

#!/usr/bin/env python
# *-* coding=utf-8 *-*

‘Bayesian Classification‘

__author__=‘xiahouzuoxin‘

import logging
logging.basicConfig(level=logging.INFO)

class NaiveBayesian(object):

    def __init__(self, train_data, train_label, predict_data=None, predict_label=None):
        self.train_data = train_data
        self.train_label = train_label
        self.m = len(self.train_label)  # 样本数目
        self.n = len(train_data[1]);  # 特征数目,假设特征维度一样
        self.cls = list(set(train_label));
        self.predict_data = predict_data
        self.predict_label = predict_label
        self.__prio_p = {}
        self.__likelihood_p = {}
        self.__evidence_p = 1
        self.__predict_p = [];

    def train(self):
        # 统计目标出现概率:先验概率
        p_lb = {}
        for lb in self.train_label:
            if lb in p_lb:
                p_lb[lb] = p_lb[lb] + 1
            else:
                p_lb[lb] = 1+1  # Laplace smoothing,初始为1,计数+1
        for lb in p_lb.keys():
            p_lb[lb] = float(p_lb[lb]) / (self.m+len(self.cls))
        self.__prio_p = p_lb

        # 统计都有啥特征
        p_v = {}
        feat_key = [];
        for sample in self.train_data:
            #print sample
            for k,v in sample.iteritems():
                feat_key.append((k,v))
                if (k,v) in p_v:
                    p_v[(k,v)] = p_v[(k,v)] + 1
                else:
                    p_v[(k,v)] = 1+1  # Laplace smoothing
        for v in p_v:
            p_v[v] = float(p_v[v]) / (self.m+p_v[v])
            self.__evidence_p *= p_v[v]  # 条件独立假设

        # 统计似然概率
        keys = [(x,y) for x in self.cls for y in feat_key]
        keys = set(keys)
        p_likelihood = {};
        for val in keys:
            p_likelihood[val]=1    # Laplace smoothing, 初始计数为1
        for idx in range(self.m):  # 统计频次
            p_likelihood[(self.train_label[idx],feat_key[idx])] = p_likelihood[(self.train_label[idx],feat_key[idx])] + 1
        for k in p_likelihood:  # 求概率
            if self.cls[0] in k:
                p_likelihood[k] = float(p_likelihood[k]) / (self.m*self.__prio_p[self.cls[0]]+2)
            else:
                p_likelihood[k] = float(p_likelihood[k]) / (self.m*self.__prio_p[self.cls[1]]+2)
        self.__likelihood_p = p_likelihood

    def predict(self):
        label = [];
        for x_dict in self.predict_data:  # 可以处理多维特征的情况
            likeli_p = [1,1];
            for key,val in x_dict.iteritems():
                likeli_p[0] = likeli_p[0] * self.__likelihood_p[(self.cls[0], (key,val))]  # 条件独立假设
                likeli_p[1] = likeli_p[1] * self.__likelihood_p[(self.cls[1], (key,val))]

            p_predict_cls0 = likeli_p[0] * self.__prio_p[self.cls[0]] / self.__evidence_p
            p_predict_cls1 = likeli_p[1] * self.__prio_p[self.cls[1]] / self.__evidence_p
            norm = p_predict_cls0 + p_predict_cls1
            p_predict_cls0 = p_predict_cls0/norm
            p_predict_cls1 = p_predict_cls1/norm
            self.__predict_p.append({self.cls[0]:p_predict_cls0})
            self.__predict_p.append({self.cls[1]:p_predict_cls1})
            if p_predict_cls1 > p_predict_cls0:
                label.append(self.cls[1])
            else:
                label.append(self.cls[0])

        return label,self.__predict_p

    def get_prio(self):
        return self.__prio_p

    def get_likelyhood(self):
        return self.__likelihood_p

我们将上面的python代码保存为bayesian.py文件,下面是python代码的Example测试实例(example.py):

#!/usr/bin/env python
# *-* coding=utf-8 *-*

__author__=‘xiahouzuoxin‘

import bayesian

# 一维特征情况
# train_data = [ {‘Name‘:‘Drew‘},
#         {‘Name‘:‘Claudia‘},
#         {‘Name‘:‘Drew‘},
#         {‘Name‘:‘Drew‘},
#         {‘Name‘:‘Alberto‘},
#         {‘Name‘:‘Karin‘},
#         {‘Name‘:‘Nina‘},
#         {‘Name‘:‘Sergio‘} ]
# train_label = [‘Male‘,‘Female‘,‘Female‘,‘Female‘,‘Male‘,‘Female‘,‘Female‘,‘Male‘]
# predict_data = [{‘Name‘:‘Drew‘}]
# predict_label = None;

# 多维特征的情况
train_data = [ {‘Name‘:‘Drew‘,‘Over170‘:‘No‘,‘Eye‘:‘Blue‘,‘Hair‘:‘Short‘},
        {‘Name‘:‘Claudia‘,‘Over170‘:‘Yes‘,‘Eye‘:‘Brown‘,‘Hair‘:‘Long‘},
        {‘Name‘:‘Drew‘,‘Over170‘:‘No‘,‘Eye‘:‘Blue‘,‘Hair‘:‘Long‘},
        {‘Name‘:‘Drew‘,‘Over170‘:‘No‘,‘Eye‘:‘Blue‘,‘Hair‘:‘Long‘},
        {‘Name‘:‘Alberto‘,‘Over170‘:‘Yes‘,‘Eye‘:‘Brown‘,‘Hair‘:‘Short‘},
        {‘Name‘:‘Karin‘,‘Over170‘:‘No‘,‘Eye‘:‘Blue‘,‘Hair‘:‘Long‘},
        {‘Name‘:‘Nina‘,‘Over170‘:‘Yes‘,‘Eye‘:‘Brown‘,‘Hair‘:‘Short‘},
        {‘Name‘:‘Sergio‘,‘Over170‘:‘Yes‘,‘Eye‘:‘Blue‘,‘Hair‘:‘Long‘} ]
train_label = [‘Male‘,‘Female‘,‘Female‘,‘Female‘,‘Male‘,‘Female‘,‘Female‘,‘Male‘]
predict_data = [{‘Name‘:‘Drew‘,‘Over170‘:‘Yes‘,‘Eye‘:‘Blue‘,‘Hair‘:‘Long‘}]
predict_label = None;

model = bayesian.NaiveBayesian(train_data, train_label, predict_data, predict_label)
model.train()
result = model.predict()
print result

输出结果:

拉普拉斯平滑(Laplace smoothing)

当某个特征未出现时,比如 p(x1000|y)?=?0 , 则由于独立条件必然使 p(x1,?x2,?...,?x5000)?=?0 , 这样就造成贝叶斯公式中的分子为0。我们不能因为某个特征(词汇)没在训练数据中出现过就认为目标出现这个特征的概率为0(正常情况没出现的概率应该是1/2才合理)。为了应对这种情况,拉普拉斯平滑就能应对这种贝叶斯推断中的0概率情况。

上面的python源代码中就考虑了Laplace smoothing。

时间: 2024-11-11 08:04:38

Stanford机器学习课程笔记2-高斯判别分析与朴素贝叶斯的相关文章

斯坦福CS229机器学习课程笔记四:GDA、朴素贝叶斯、多项事件模型

生成学习与判别学习 像逻辑回归,用hθ(x) = g(θTx) 直接地来建模 p(y|x; θ) :或者像感知机,直接从输入空间映射到输出空间(0或1),它们都被称作判别学习(discriminative learning).与之相对的是生成学习(generative learning),先对 p(x|y) 与 p(y) 建模,然后通过贝叶斯法则导出后验条件概率分布分母的计算规则为全概率公式:p(x) = p(x|y = 1)p(y = 1) + p(x|y =0)p(y = 0).这一节介绍的

高斯判别分析、朴素贝叶斯和逻辑回归

近来看论文中经常看到GDA和朴素贝叶斯,并且论文中说的算法中用到的贝叶斯公式,对怎么用的原理比较困惑,今天主要看了斯坦福机器学习的关于GDA,NB和LR的讲义部分.理解了贝叶斯公式在GDA和NB中的原理,以及GDA和LR的关系. 与以前学习贝叶斯公式相比贝叶斯公式:对于目标B有不同的到达方式Ai,i=1,2,3,...,n.已知p(Ai)和p(B|Ai)的话,如果知道B发生了,可以知道Ai的后验概率. 贝叶斯公式图示 在GDA和NB中,类别标签就相当于Ai,每一个特征相当于B的一个分量.根据采集

Stanford机器学习课程笔记——神经网络的表示

Stanford机器学习课程笔记--神经网络的表示 1. 为什么要引入神经网络 其实这个问题等价与神经网络和之前的回归模型有什么区别,如果你没有学过其他机器学习算法的话.这个问题可以通过一个例子来说明:如果样本都是60*60的图像,那么每个样本的特征维数都是3600个,使用前面讲的线性回归模型,那么需要建立的参数个数就有3600的:如果是非线性回归模型,还要考虑高次项的情况,需要求解的参数就更加多了.此时的回归模型将会变得异常复杂,故我们需要其余比较高效的模型来解决这些实际的问题.这个时候我们就

Stanford机器学习课程笔记——SVM

Stanford机器学习课程笔记--SVM 前面已经学习过SVM,写了几片博文,如下: 入门SVM:http://blog.csdn.net/puqutogether/article/details/39894835 SVM中的线性不可分情况:http://blog.csdn.net/puqutogether/article/details/41309745 SVM中的多类分类问题:http://blog.csdn.net/puqutogether/article/details/4167960

Stanford机器学习课程笔记——单变量线性回归和梯度下降法

Stanford机器学习课程笔记--单变量线性回归和梯度下降法 1. 问题引入 单变量线性回归就是我们通常说的线性模型,而且其中只有一个自变量x,一个因变量y的那种最简单直接的模型.模型的数学表达式为y=ax+b那种,形式上比较简单.Stanford的机器学习课程引入这个问题也想让我们亲近一下machine learning这个领域吧~吴恩达大神通过一个房屋交易的问题背景,带领我们理解Linear regression with one variable.如下: 不要看这个问题简答,大神就是大神

机器学习实战教程(五):朴素贝叶斯实战篇之新浪新闻分类

原文链接: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_5_bayes_2.html 一.前言 上篇文章机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器讲解了朴素贝叶斯的基础知识.本篇文章将在此基础上进行扩展,你将看到以下内容: 拉普拉斯平滑 垃圾邮件过滤(Python3) 新浪新闻分类(sklearn) 二.朴素贝叶斯改进之拉普拉斯平滑 上篇文章提到过,算法存在一定的问题,需要进行改进.那么需要改进的地方在哪里呢?利用贝叶斯分类器对文档进行

Stanford机器学习课程笔记4-Kmeans与高斯混合模型

这一部分属于无监督学习的内容,无监督学习内容主要包括:Kmeans聚类算法.高斯混合模型及EM算法.Factor Analysis.PCA.ICA等.本文是Kmeans聚类算法.高斯混合模型的笔记,EM算法是适用于存在latent/hidden变量的通用算法,高斯混合模型仅仅是EM算法的一种特殊情况,关于EM算法的推到参见Andrew Ng讲义.由于公式太多,最近时间又忙实习的事就简单写一些,回头看时还得参考Ng的笔记和自己的打印Notes上的笔记,这里的程序对理解可能能提供另外的一些帮助. K

Stanford大学机器学习公开课(五):生成学习算法、高斯判别、朴素贝叶斯

(一)生成学习算法 在线性回归和Logistic回归这种类型的学习算法中我们探讨的模型都是p(y|x;θ),即给定x的情况探讨y的条件概率分布.如二分类问题,不管是感知器算法还是逻辑回归算法,都是在解空间中寻找一条直线从而把两种类别的样例分开,对于新的样例,只要判断在直线的哪一侧即可:这种直接对问题求解的方法可以称为判别学习方法. 而生成学习算法则是对两个类别分别进行建模,用新的样例去匹配两个模板,匹配度较高的作为新样例的类别,比如分辨大象(y=1)和狗(y=0),首先,观察大象,然后建立一个大

Stanford大学机器学习公开课(六):朴素贝叶斯多项式模型、神经网络、SVM初步

(一)朴素贝叶斯多项式事件模型 在上篇笔记中,那个最基本的NB模型被称为多元伯努利事件模型(Multivariate Bernoulli Event Model,以下简称 NB-MBEM).该模型有多种扩展,一种是在上一篇笔记中已经提到的每个分量的多值化,即将p(xi|y)由伯努利分布扩展到多项式分布:还有一种在上一篇笔记中也已经提到,即将连续变量值离散化.本文将要介绍一种与多元伯努利事件模型有较大区别的NB模型,即多项式事件模型(Multinomial Event Model,一下简称NB-M