《统计学习方法》——第四章朴素贝叶斯及C++实现

Input: 特征向量
Output : 实例类别
可用于多分类,属于生成模型,先估计X,Y的联合概率分布P(X,Y),再计算条件概率P(Y|X)
朴素贝叶斯法和朴素贝叶斯估计是两种不同的概念
朴素贝叶斯法(model)---->参数估计
参 数 估 计 = { 最 大 似 然 估 计 贝 叶 斯 估 计 参数估计=\left\{ \begin{aligned} 最大似然估计\\ 贝叶斯估计 \\ \end{aligned} \right. ={改进原因,如果某一个要估计的P为0,例如NLP应用中,某个词向量出现的次数为0,影响后验概率的计算,因此使用贝叶斯估计方法。最大似然估计,最大可能性估计。

强条件独立性的基本假设

用于分类的特征在类确定的条件下都是条件独立的,在这种强条件独立性假设下,可以省去每种特征向量的参数估计,复杂度降低,但是会降低估计的准确性。
P ( X = x ∣ Y = C k ) = P ( X ( 1 ) = x ( 1 ) , X ( 2 ) = x ( 2 ) , ⋯   , X ( n ) = x ( n ) ∣ Y = C k ) = ∏ i = 1 n P ( X ( i ) = x ( i ) ∣ Y = C k ) P(X=x|Y=C_k)=P(X^{(1)} =x^{(1)},X^{(2)} =x^{(2)},\cdots,X^{(n)} =x^{(n)}|Y=C_k)\\ =\prod_{i=1}^{n}P(X^{(i)} =x^{(i)}|Y=C_k) P(X=xY=Ck)=P(X(1)=x(1),X(2)=x(2),,X(n)=x(n)Y=Ck)=i=1nP(X(i)=x(i)Y=Ck)

P(X,Y)是怎么求出来的呢?

{ 贝 叶 斯 定 理 P ( X , Y ) = P ( X ∣ Y ) P ( Y ) 强 条 件 假 设 P ( X ∣ Y ) = P ( X = x ∣ Y = C k ) \left\{ \begin{aligned} 贝叶斯定理 P(X,Y)=P(X|Y)P(Y)\\ 强条件假设 P(X|Y) = P(X=x|Y=Ck) \\ \end{aligned} \right. {P(X,Y)=P(XY)P(Y)P(XY)=P(X=xY=Ck)根据前面强条件假设可以求得P(X|Y),P(Y)也可求
所以 P ( Y = C k ∣ X = x ) = P ( X , Y ) P ( Y ) = P ( X = x ∣ Y = C k ) P ( Y = C k ) ∑ k P ( X = x ∣ Y = C k ) P ( Y = C k ) P(Y=C_k|X=x)=\frac{P(X,Y)}{P(Y)} =\frac{P(X=x|Y=C_k)P(Y=C_k)}{\sum_{k}P(X=x|Y=C_k)P(Y=C_k)} P(Y=CkX=x)=P(Y)P(X,Y)=kP(X=xY=Ck)P(Y=Ck)P(X=xY=Ck)P(Y=Ck) = P ( Y = C k ) ∏ i = 1 n P ( X ( i ) = x ( i ) ∣ Y = C k ) ∑ k P ( Y = C k ) ∏ j P ( X ( j ) ∣ Y = C k ) =\frac{P(Y=C_k)\prod_{i=1}^{n}P(X^{(i)} =x^{(i)}|Y=C_k)} {\sum_{k}P(Y=C_k)\prod_{j}P(X^{(j)}|Y=C_k)} =kP(Y=Ck)jP(X(j)Y=Ck)P(Y=Ck)i=1nP(X(i)=x(i)Y=Ck)
因为分母部分都是一样的,所以最后只需 y = a r g m a x C k P ( Y = C k ) ∏ i = 1 n P ( X ( i ) = x ( i ) ∣ Y = C k ) y=argmax_{C_k}P(Y=C_k)\prod_{i=1}^{n}P(X^{(i)} =x^{(i)}|Y=C_k) y=argmaxCkP(Y=Ck)i=1nP(X(i)=x(i)Y=Ck)

极大似然估计:

P ( Y = C k ) = ∑ i = 1 N I ( y i = C k ) N P(Y=C_k)=\frac{\sum_{i=1}^{N}I(y_i=C_k)}{N} P(Y=Ck)=Ni=1NI(yi=Ck) P ( X ( j ) = a j l ∣ Y = C k ) = ∑ i = 1 N I ( X I ( j ) = a j l , y i = C k ) ∑ i = 1 N I ( y i = C k ) P(X^{(j)} =a_{jl}|Y=C_k)=\frac{\sum_{i=1}^{N}I(X_I^{(j)}=a_{jl},y_i=C_k)}{\sum_{i=1}^{N}I(y_i=C_k)} P(X(j)=ajlY=Ck)=i=1NI(yi=Ck)i=1NI(XI(j)=ajl,yi=Ck)
《统计学习方法》——第四章朴素贝叶斯及C++实现_第1张图片
《统计学习方法》——第四章朴素贝叶斯及C++实现_第2张图片

贝叶斯估计:

P ( Y = C k ) = ∑ i = 1 N I ( y i = C k ) + λ N + k λ P(Y=C_k)=\frac{\sum_{i=1}^{N}I(y_i=C_k)+\lambda}{N+k\lambda} P(Y=Ck)=N+kλi=1NI(yi=Ck)+λ P ( X ( j ) = a j l ∣ Y = C k ) = ∑ i = 1 N I ( X I ( j ) = a j l , y i = C k ) + λ ∑ i = 1 N I ( y i = C k ) + S j λ P(X^{(j)} =a_{jl}|Y=C_k)=\frac{\sum_{i=1}^{N}I(X_I^{(j)}=a_{jl},y_i=C_k)+\lambda}{\sum_{i=1}^{N}I(y_i=C_k)+S_j\lambda} P(X(j)=ajlY=Ck)=i=1NI(yi=Ck)+Sjλi=1NI(XI(j)=ajl,yi=Ck)+λ S j 表 示 每 类 特 征 的 可 能 性 S_j表示每类特征的可能性 Sj$
《统计学习方法》——第四章朴素贝叶斯及C++实现_第3张图片

按照书上例子以及算法流程使用C++实现如下:

#include  
#include  
#include 
using namespace std;c
onst int MaxNum = 20;
struct DataSet
{
    vector samples;
    int labels;
}data[MaxNum];
class Bayes
{
public:    
/**加载数据**/
    int loadData()
    {
        fstream f ;
        int countNum = 0;
        f.open("data.txt");
        int i = 0; double temp1,temp2;        while(!f.eof())
        {
            f>>temp1>>temp2>>data[i].labels;
            data[i].samples.push_back(temp1);
            data[i].samples.push_back(temp2);
            i++;
            countNum++;
        }
        f.close();
        return countNum;
    }    
    /**指示函数,如果A==B 返回1,若果不相等返回0**/
    bool Indication_function(double a,double b)
    {
        if(a==b)
            return true;
        else
            return false;
    }
    /**找到一个向量中不同的数值,并返回向量**/
    vector find_different(vector arg)
    {
        int K = arg.size();
        vector Ck;
        Ck.push_back(arg[0]);
        int flag =0;
        for (int i=1;i find_different(vector arg)
    {
        int K = arg.size();
        vector Ck;
        Ck.push_back(arg[0]);
        int flag =0;
        for (int i=1;i Priori_Probability(vector Ck,DataSet *data,int N)
    {
        int k = Ck.size();
        vector pp;
        int countNum = 0;
        for(int i=0;i> find_features(DataSet data[],int N)
    {
        int K=2; //data.samples.size();
        vector> features(K);
        vector a;
        for(int k=0;k temp;
        for(int i=0;i>> Conditional_Probability(vector Ck,vector> features,DataSet *data,int N)
    {
        int ck_N = Ck.size();//ck_N是类别的不同
        int feature_k = features.size();
        //定义每一类的坟墓个数
        vector fenmu(ck_N);
        for(int k=0;k>> res(ck_N);
        for(int n=0;n>> fenzi(ck_N);
        for(int n=0;n Predict(vector x,vector Ck,vector Priori_Probability,
                           vector>> Conditional_Probability,vector> features)
    {
        int ck_N = Ck.size();
        vector res;
        vector temp;
        double temp1=1;        for(int i=0;i res,vector Ck)
    {
        int n= res.size();
        double temp=res[0];
        int orth=0;
        for(int i=1;itemp)
            {
                temp = res[i];
                orth =i;
            }
        }
        return Ck[orth];
    }
};
int main()
{
    Bayes by;
    int N = by.loadData();
    cout<<"样本总数: "<< N < C ;//Ck是类别的不同
    for(int i=0;i Ck = by.find_different(C);    vector pp = by.Priori_Probability(Ck,data,N);
    cout<<"测试先验概率是否正确:"<> Features = by.find_features(data,N);    cout<<"测试特征及特征取值是否正确:"<>> res = by.Conditional_Probability(Ck,Features,data,N);
    for(int i=0;i x;
    x.push_back(2);
    x.push_back(9);
    vector predict= by.Predict(x,Ck,pp,res,Features);
    cout<<"样本x预测为每一个类别的概率:"<

你可能感兴趣的:(机器学习,统计学习方法学习总结与实现,统计学习方法)