朴素贝叶斯分类器

一、实验目的
1、 用朴素贝叶斯分类器完成对未知样本的类型分类
二、 实验内容:
1、 实验题目:设某网球俱乐部由下表给出的打球与气候情况的历史数据样本集S。
朴素贝叶斯分类器_第1张图片
俱乐部计划后天安排一次网球比赛活动,而后天的天气预报情况如下:
Z=(天气=“晴”,温度=“高”,湿度=“小”,风力=“无”) 根据历史样本集S,利用朴素贝叶斯分类器,判断后天是否适宜进行网球比赛

过程代码

#include "stdio.h"

//天气
enum enum_outlook
{
	sunny = 0,
	overcast = 1,
	rain = 2
}_outlook;

//温度
enum enum_temperature
{
	hot = 0,
	mild = 1,
	cool = 2
}_temperature;

//湿度
enum enum_humidity
{
	high = 0,
	normal = 1,
}_humidity;

//风力 
enum enum_wind
{
	weak = 0,
	strong = 1
}_wind;

//类别 
enum enum_targetAttribute
{
	yes = 0,
	no = 1
}_targetAttribute;


#define TRAIN_NUM 14      //定义14个训练实例
#define ATTR_NUM 4        //每个训练实例有4个属性
//初始化训练实例 
int trainSample[][ATTR_NUM + 1] = {
	{
		sunny,hot,high,weak,no
	},
	{
		sunny,hot,high,weak,no
	},
	{
		overcast,hot,high,weak,yes
	},
	{
		rain,mild,high,weak,yes
	},
	{
		rain,cool,normal,weak,yes
	},
	{
		rain,cool,normal,strong,no
	},
	{
		overcast,cool,normal,strong,yes
	},
	{
		sunny,mild,high,weak,no
	},
	{
		sunny,cool,normal,weak,yes
	},
	{
		rain,mild,normal,weak,yes
	},
	{
		sunny,mild,normal,strong,yes
	},
	{
		overcast,mild,high,strong,yes
	},
	{
		overcast,hot,normal,weak,yes
	},
	{
		rain,mild,high,strong,no
	},
};

int newSanple[ATTR_NUM] = { sunny,cool,high,strong };                             //定义需要分类的新实例
float preP[ATTR_NUM] = { (float)0.333,(float)0.333,(float)0.50,(float)0.50 };     //m-估计每个属性对应的先验概率

#define m TRAIN_NUM                                                                //m-估计的m值等于训练样例数
                                                           
void CalcposAndNegNum(int*pPosNum, int*pNegNum)
{
	int i;

	*pPosNum = 0;
	*pNegNum = 0;
	for (i = 0; i<TRAIN_NUM; i++)
	{
		if (trainSample[i][ATTR_NUM] == yes)
		{
			(*pPosNum)++;
		}
		else
		{
			(*pNegNum)++;
		}
	}
	
	return;
}

//朴素贝叶斯分类器 
void NaiveBayes(void)
{
	int x;
	for (int i = 0; i <ATTR_NUM; i++)
	{
	scanf("%d", &newSanple[i]);
	}

	int j, cntY, cntN;
        //存储训练样例目标属性为yes或no的样本数
	int posNum, negNum;
        //存储目标值yes和no的概率
	float PVyes, PVno, PVyesTemp, PVnoTemp;
        //存储目标值为yes时需分类的每个属性的概率
	float PAttrYes[ATTR_NUM];
        //存储目标值为no时需分类的每个属性的概率
	float PAttrNo[ATTR_NUM];
        //计算训练样例集的正样本数和负样本数
	CalcposAndNegNum(&posNum, &negNum);
        //计算目标值 yes 的概率
	PVyes = (float)posNum / (float)TRAIN_NUM;
        //计算目标值 no 的概率
	PVno = (float)negNum / (float)TRAIN_NUM;
        printf("目标值概率PVyes=%f\n\n",PVyes);
	printf("目标值概率PVno=%f\n\n", PVno);
        //计算目标值分别为 yes 和 no 时各个需分类属性对应的概率
	for (j = 0; j<ATTR_NUM; j++)
	{
                //清 0 计数变量
		cntY = 0;
		cntN = 0;
		for (int i = 0; i<TRAIN_NUM; i++)

		{
                        //统计目标值为 yes 时各个需分类的属性在训练样例中的个数
			if (trainSample[i][ATTR_NUM] == yes)
			{
                                //如果训练样例的目标属性是 yes
                                //且该训练样例的属性值和需要分类的样例的属性值相等,则计数 
				if (trainSample[i][j] == newSanple[j])
				{
					cntY++;
				}
			
			}
                        //统计目标值为 no 时各个需分类的属性在训练样例中的个数

			else if (trainSample[i][ATTR_NUM] == no)
			{
                                //如果训练样例的目标属性是 no
                                //且该训练样例的属性值和需要分类的样例的属性值相等,则计数
				if (trainSample[i][j] == newSanple[j])
				{
					cntN++;
				}
			}
		}
		printf("统计输入样例属性下Yes的个数cntY=%d\n\n",cntY);
		printf("统计输入样例属性下No的个数cntN=%d\n\n",cntN);
	 
                //计算目标值为 yes 时需分类的各个属性的概率
                PAttrYes[j] = ((float)cntY + (float)m*preP[j]) / ((float)(posNum + m));
                //计算目标值为 no 时需分类的各个属性的概率
		PAttrNo[j] = ((float)cntN + (float)m*preP[j])/((float)(negNum + m));
		printf("目标值为Yes时输入属性的概率:%f\n\n",PAttrYes[j]);

		printf("目标值为No时输入属性的概率:%f\n\n",PAttrNo[j]);
	}
        //分别计算需要分类的样例的目标值为 yes 和 no 的概率
	for (int i = 0; i<ATTR_NUM; i++)
	{
		PVyes = PVyes*PAttrYes[i];
		PVno = PVno*PAttrNo[i];
	}
	printf("概率PVyes=%f\n\n",PVyes);
	printf("概率PVno=%f\n\n",PVno);
        //做归一化处理
	PVyesTemp = PVyes / (PVyes + PVno);
	PVnoTemp = PVno / (PVyes + PVno);
	printf("归一化后实例被分为yes的概率:%f\n\n", PVyesTemp);
	printf("归一化后实例被分为no的概率:%f\n\n", PVnoTemp);
	if (PVyesTemp>PVnoTemp)
	{
		printf("所以实例被分类为:yes\n\n");

	}
	else
	{
		printf("所以实例被分类为:no\n");
	}
	return;
}
//主函数
int main(void)
{
    printf("请输入样例属性:\n");
       //调用朴素贝叶斯学习器算法 
	NaiveBayes();
	return 1;
}

朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。2)需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。3)由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。

你可能感兴趣的:(算法,朴素贝叶斯算法,c语言)