机器学习--朴素贝叶斯的分析与实现


贝叶斯定理:
p(a|b) = p(b|a)*p(a)/p(b)
假设:时间a,b相互独立。


由于朴素贝叶斯基于贝叶斯定理,因此,在应用贝叶斯分类器时,所选的特征也应当是不相关的。


例:
训练数据: 四维向量数组,共15个元素。
inputs ={
    new int[] { 0, 1, 1, 0 }, //  c=0 
    new int[] { 0, 1, 0, 0 }, //  c=0
    new int[] { 0, 0, 1, 0 }, //  c=0
    new int[] { 0, 1, 1, 0 }, //  c=0
    new int[] { 0, 1, 0, 0 }, //  c=0
    new int[] { 1, 0, 0, 0 }, //  c=1
    new int[] { 1, 0, 0, 0 }, //  c=1
    new int[] { 1, 0, 0, 1 }, //  c=1
    new int[] { 0, 0, 0, 1 }, //  c=1
    new int[] { 0, 0, 0, 1 }, //  c=1
    new int[] { 1, 1, 1, 1 }, //  c=2
    new int[] { 1, 0, 1, 1 }, //  c=2
    new int[] { 1, 1, 0, 1 }, //  c=2
    new int[] { 0, 1, 1, 1 }, //  c=2
    new int[] { 1, 1, 1, 1 }, //  c=2
};



前5个分类为0,中间五个分类为1,后五个分类为2。


现在需要预测向量v{0,1,1,0}的分类。
即分别求:
p(c=0, inputs[0]=0, inputs[1]=1, inputs[2]=1, inputs[3]=0)的概率
p(c=1, inputs[0]=0, inputs[1]=1, inputs[2]=1, inputs[3]=0)的概率
p(c=2, inputs[0]=0, inputs[1]=1, inputs[2]=1, inputs[3]=0)的概率


,然后选出最大值。


根据贝叶斯定理,并假设4个维度的特征不相关:
p(c=0,v={0,1,1,0}) = p(input[0]=0,c=0)*p(input[1]=1,c=0)*p(input[2]=1,c=0)*p(input[3]=0,c=0)*p(c=0)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)
p(c=1,v={0,1,1,0}) = p(input[0]=0,c=1)*p(input[1]=1,c=1)*p(input[2]=1,c=1)*p(input[3]=0,c=1)*p(c=1)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)
p(c=2,v={0,1,1,0}) = p(input[0]=0,c=2)*p(input[1]=1,c=2)*p(input[2]=1,c=2)*p(input[3]=0,c=2)*p(c=2)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)


,对于本例,p(c=0) == p(c=1) == p(c=2),因此可将p(c={0|1|2})/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)视为常数。


设,

C = {p(c=0)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)}



p(c=0,v={0,1,1,0}) = p(input[0]=0,c=0)*p(input[1]=1,c=0)*p(input[2]=1,c=0)*p(input[3]=0,c=0)*C
p(c=1,v={0,1,1,0}) = p(input[0]=0,c=1)*p(input[1]=1,c=1)*p(input[2]=1,c=1)*p(input[3]=0,c=1)*C
p(c=2,v={0,1,1,0}) = p(input[0]=0,c=2)*p(input[1]=1,c=2)*p(input[2]=1,c=2)*p(input[3]=0,c=2)*C



求出以上3个概率后,取最大值即得到了分类。


本例实现代码:


void Main()
{
	
//p(a|b) = p(b|a)*p(a)/p(b)


//to calculate : p(c={0,1,2}, input = [0,1,1,0]):
//p(c=0,input={0,1,1,0}) = p(input[0]=0,c=0)*p(input[1]=1,c=0)*p(input[2]=1,c=0)*p(input[3]=0,c=0)*p(c=0)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)
//p(c=1,input={0,1,1,0}) = p(input[0]=0,c=1)*p(input[1]=1,c=1)*p(input[2]=1,c=1)*p(input[3]=0,c=1)*p(c=1)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)
//p(c=2,input={0,1,1,0}) = p(input[0]=0,c=2)*p(input[1]=1,c=2)*p(input[2]=1,c=2)*p(input[3]=0,c=2)*p(c=2)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)


//since p(c=0) == p(c=1) == p(c=2), set C = {p(c=0)/p(input[0]=0)*p(input[1]=1)*p(input[2]=1)*p(input[3]=0)}


//p(c=0,input={0,1,1,0}) = p(input[0]=0,c=0)*p(input[1]=1,c=0)*p(input[2]=1,c=0)*p(input[3]=0,c=0)*C
//p(c=1,input={0,1,1,0}) = p(input[0]=0,c=1)*p(input[1]=1,c=1)*p(input[2]=1,c=1)*p(input[3]=0,c=1)*C
//p(c=2,input={0,1,1,0}) = p(input[0]=0,c=2)*p(input[1]=1,c=2)*p(input[2]=1,c=2)*p(input[3]=0,c=2)*C


	var f0=0;
	var f1=1;
	var f2=1;
	var f3=0;
	
	var p_input_equals_0_1_2_3 = 8*8*7*7/15*15*15*15.0;
	var p_c_0_1_2 = 1/3;
	var C = p_c_0_1_2 / p_input_equals_0_1_2_3;
	
	var p_c_0 = P_c_0(Feature(inputs,0), f0) * P_c_0(Feature(inputs,1),f1)* P_c_0(Feature(inputs,2),f2)* P_c_0(Feature(inputs,3),f3) * C;
	//Console.WriteLine(p0);
	var p_c_1 = P_c_1(Feature(inputs,0), f0) * P_c_1(Feature(inputs,1),f1)* P_c_1(Feature(inputs,2),f2)* P_c_1(Feature(inputs,3),f3) * C;
	var p_c_2 = P_c_2(Feature(inputs,0), f0) * P_c_2(Feature(inputs,1),f1)* P_c_2(Feature(inputs,2),f2)* P_c_2(Feature(inputs,3),f3) * C;


	var max = Math.Max(Math.Max(p_c_0,p_c_1),p_c_2);
	if(max == p_c_0){
		Console.WriteLine("category is 0");
	}
	else if(max == p_c_1){
		Console.WriteLine("category is 1");
	}
	else{
		Console.WriteLine("category is 2");
	}
}


static int[][] inputs ={
    new int[] { 0, 1, 1, 0 }, //  c=0 
    new int[] { 0, 1, 0, 0 }, //  c=0
    new int[] { 0, 0, 1, 0 }, //  c=0
    new int[] { 0, 1, 1, 0 }, //  c=0
    new int[] { 0, 1, 0, 0 }, //  c=0
    new int[] { 1, 0, 0, 0 }, //  c=1
    new int[] { 1, 0, 0, 0 }, //  c=1
    new int[] { 1, 0, 0, 1 }, //  c=1
    new int[] { 0, 0, 0, 1 }, //  c=1
    new int[] { 0, 0, 0, 1 }, //  c=1
    new int[] { 1, 1, 1, 1 }, //  c=2
    new int[] { 1, 0, 1, 1 }, //  c=2
    new int[] { 1, 1, 0, 1 }, //  c=2
    new int[] { 0, 1, 1, 1 }, //  c=2
    new int[] { 1, 1, 1, 1 }, //  c=2
};


public static double P_c_0(int[] feature,int v){
	var r = feature.Take(5).Count(x=>x == v)/5.0 /*from 1-5 , category is 0*/;
	//Console.WriteLine(r);
	return r;
}
public static double P_c_1(int[] feature,int v){
	var r = feature.Skip(5).Take(5).Count(x=>x == v)/5.0 /*from 6-10 , category is 1*/;
	//Console.WriteLine(r);
	return r;
}
public static double P_c_2(int[] feature,int v){
	var r = feature.Skip(10).Take(5).Count(x=>x == v)/5.0 /*from 11-15 , category is 2*/;
	//Console.WriteLine(r);
	return r;
}




public static int[] Feature(int[][] inputs, int c){
	var result = new int[inputs.Length];
	for(var i =0 ;i < inputs.Length; i++){
		result[i] = inputs[i][c];
	}
	return result;
}
// Define other methods and classes here






注,以上代码只用于对本例的朴素贝叶斯分类过程的分析,很多条件是hardcode的。




以下是使用accord-framework实现的贝叶斯分类:


public class BayesianDemo
    {
        public static void Execute()
        {
            int[][] inputs =
            {
                //input                     output
                new int[] { 0, 1, 1, 0 }, //  0 
                new int[] { 0, 1, 0, 0 }, //  0
                new int[] { 0, 0, 1, 0 }, //  0
                new int[] { 0, 1, 1, 0 }, //  0
                new int[] { 0, 1, 0, 0 }, //  0
                new int[] { 1, 0, 0, 0 }, //  1
                new int[] { 1, 0, 0, 0 }, //  1
                new int[] { 1, 0, 0, 1 }, //  1
                new int[] { 0, 0, 0, 1 }, //  1
                new int[] { 0, 0, 0, 1 }, //  1
                new int[] { 1, 1, 1, 1 }, //  2
                new int[] { 1, 0, 1, 1 }, //  2
                new int[] { 1, 1, 0, 1 }, //  2
                new int[] { 0, 1, 1, 1 }, //  2
                new int[] { 1, 1, 1, 1 }, //  2
            };


            int[] outputs = // those are the class labels
            {
                0, 0, 0, 0, 0,
                1, 1, 1, 1, 1,
                2, 2, 2, 2, 2,
            };
             
            // Create a discrete naive Bayes model for 3 classes and 4 binary inputs
            var bayes = new NaiveBayes(classes: 3, symbols: new int[] { 2, 2, 2, 2 });


            // Teach the model. The error should be zero:
            double error = bayes.Estimate(inputs, outputs);


            int answer = bayes.Compute(new int[] { 0, 1, 1, 0 });


            Console.WriteLine("category is : {0}",answer);
        }
    }


class Program
    {
        static void Main(string[] args)
        {
            BayesianDemo.Execute();
            Console.ReadLine();
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值