朴素贝叶斯分类器c语言实现
时间: 2023-07-13 13:31:22 浏览: 121
朴素贝叶斯分类器是一种常见的文本分类算法,它的主要思想是利用贝叶斯定理计算出文本属于某个类别的概率,然后选择概率最大的类别作为分类结果。下面是一个简单的朴素贝叶斯分类器的C语言实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_FEATURES 1000
#define MAX_SAMPLES 1000
int num_features; // 特征数
int num_samples; // 样本数
int num_classes; // 类别数
// 存储训练数据
double features[MAX_SAMPLES][MAX_FEATURES];
int classes[MAX_SAMPLES];
// 统计每个类别的样本数
int class_sizes[MAX_SAMPLES];
// 统计每个类别中每个特征的出现次数
int feature_counts[MAX_SAMPLES][MAX_FEATURES];
// 统计每个类别中所有特征的出现次数之和
int feature_sums[MAX_SAMPLES];
// 计算每个类别中每个特征的概率
double feature_probs[MAX_SAMPLES][MAX_FEATURES];
// 计算每个类别的概率
double class_probs[MAX_SAMPLES];
// 训练模型
void train()
{
int i, j, k;
// 统计每个类别的样本数
for (i = 0; i < num_samples; i++) {
class_sizes[classes[i]]++;
}
// 统计每个类别中每个特征的出现次数
for (i = 0; i < num_samples; i++) {
for (j = 0; j < num_features; j++) {
feature_counts[classes[i]][j] += features[i][j];
feature_sums[classes[i]] += features[i][j];
}
}
// 计算每个类别中每个特征的概率
for (i = 0; i < num_classes; i++) {
for (j = 0; j < num_features; j++) {
feature_probs[i][j] = (double)(feature_counts[i][j] + 1) / (double)(feature_sums[i] + num_features);
}
}
// 计算每个类别的概率
for (i = 0; i < num_classes; i++) {
class_probs[i] = (double)class_sizes[i] / (double)num_samples;
}
}
// 对测试数据进行分类
int classify(double *test_features)
{
int i, j;
double prob, max_prob = 0.0;
int max_class = 0;
// 对每个类别计算概率,选择概率最大的类别作为分类结果
for (i = 0; i < num_classes; i++) {
prob = log(class_probs[i]);
for (j = 0; j < num_features; j++) {
prob += test_features[j] * log(feature_probs[i][j]);
}
if (prob > max_prob) {
max_prob = prob;
max_class = i;
}
}
return max_class;
}
// 从文件中读取训练数据
void read_data(char *filename)
{
int i, j;
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("Error: cannot open file %s\n", filename);
exit(1);
}
fscanf(fp, "%d %d %d", &num_samples, &num_features, &num_classes);
for (i = 0; i < num_samples; i++) {
for (j = 0; j < num_features; j++) {
fscanf(fp, "%lf", &features[i][j]);
}
fscanf(fp, "%d", &classes[i]);
}
fclose(fp);
}
int main(int argc, char **argv)
{
if (argc != 3) {
printf("Usage: %s train_file test_file\n", argv[0]);
exit(1);
}
read_data(argv[1]);
train();
int i, j;
double test_features[MAX_FEATURES];
FILE *fp = fopen(argv[2], "r");
if (fp == NULL) {
printf("Error: cannot open file %s\n", argv[2]);
exit(1);
}
while (fscanf(fp, "%lf", &test_features[0]) != EOF) {
for (i = 1; i < num_features; i++) {
fscanf(fp, "%lf", &test_features[i]);
}
int result = classify(test_features);
printf("%d\n", result);
}
fclose(fp);
return 0;
}
```
这个实现比较简单,主要包括以下几个步骤:
1. 读取训练数据,包括特征和类别,存储到相应的数组中;
2. 统计每个类别的样本数以及每个类别中每个特征的出现次数;
3. 计算每个类别中每个特征的概率以及每个类别的概率;
4. 读取测试数据,对每个测试样本进行分类,输出分类结果。
需要注意的是,在计算概率时,为了避免出现下溢现象,通常将概率取对数进行计算。
阅读全文