用c++有 1 批垃圾邮件含有“点击, 获得, 更多,信息,购买, 最新,产品,获得,优惠,优惠,信息,点击,链接”等词,1批正常邮件含有关键词“明天,一起,开会,信息,详见,邮件,最新,竞品,信息”,一个新邮件内容为:最新, 产品,优惠,点击, 链接 ,请用贝叶斯过滤判断这封邮件是否为垃圾邮件。 实验报告具体内容包括: 一、实验目的 二、实验内容 三、问题分析 四、算法设计 五、源程序 六、实验结果 七、实验总结
时间: 2023-05-25 10:01:12 浏览: 144
一、实验目的:学习使用贝叶斯算法对邮件进行垃圾邮件过滤。
二、实验内容:利用贝叶斯算法对一批垃圾邮件和一批正常邮件进行训练,然后根据训练结果来判断一封新邮件是否为垃圾邮件。
三、问题分析:垃圾邮件通常包含一些关键词,如“点击、获得、更多、信息、购买、最新、产品、优惠、链接”等,而正常邮件则通常包含一些与工作、会议、邮件等相关的词汇。因此,我们可以利用这些关键词对邮件进行分类。
四、算法设计:
1. 计算先验概率
先验概率指的是在不知道邮件内容的情况下,垃圾邮件和正常邮件的出现概率。通过统计一批垃圾邮件和一批正常邮件中出现垃圾邮件和正常邮件的数量,可以计算出先验概率。
2. 计算条件概率
条件概率指的是在已知邮件内容的情况下,邮件为垃圾邮件或正常邮件的概率。利用一批垃圾邮件和一批正常邮件中出现某些关键词的次数,可以计算得到这些关键词在垃圾邮件和正常邮件中出现的概率。
3. 判断新邮件的类别
根据计算得到的先验概率和条件概率,可以计算出新邮件为垃圾邮件和正常邮件的概率,比较两者的大小即可判断其类别。
五、源程序:
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <cmath>
using namespace std;
// 训练集中垃圾邮件的数量
int spam_num = 0;
// 训练集中正常邮件的数量
int ham_num = 0;
// 垃圾邮件集合
map<string, int> spam_words;
// 正常邮件集合
map<string, int> ham_words;
// 从文件中读取训练数据
void readTrainingData(string filename) {
ifstream fin(filename);
if (!fin) {
cout << "Cannot open file: " << filename << endl;
return;
}
string line;
while (getline(fin, line)) {
if (line.find("spam") != string::npos) {
// 垃圾邮件
spam_num++;
// 统计关键词出现的次数
int start = line.find_first_of("\t") + 1;
while (start < line.size()) {
int end = line.find_first_of(" ", start);
if (end == string::npos) {
end = line.size();
}
string word = line.substr(start, end - start);
spam_words[word]++;
start = end + 1;
}
} else {
// 正常邮件
ham_num++;
// 统计关键词出现的次数
int start = line.find_first_of("\t") + 1;
while (start < line.size()) {
int end = line.find_first_of(" ", start);
if (end == string::npos) {
end = line.size();
}
string word = line.substr(start, end - start);
ham_words[word]++;
start = end + 1;
}
}
}
fin.close();
}
// 计算先验概率
double calcPrior(string category) {
if (category == "spam") {
return (double)spam_num / (double)(spam_num + ham_num);
} else {
return (double)ham_num / (double)(spam_num + ham_num);
}
}
// 计算条件概率
double calcConditional(string word, string category) {
if (category == "spam") {
return (double)(spam_words[word] + 1) / (double)(spam_num + 2);
} else {
return (double)(ham_words[word] + 1) / (double)(ham_num + 2);
}
}
// 使用贝叶斯算法判断邮件类别
string classify(string email) {
double spam_prob = log(calcPrior("spam"));
double ham_prob = log(calcPrior("ham"));
int start = email.find_first_of(" ") + 1;
while (start < email.size()) {
int end = email.find_first_of(" ", start);
if (end == string::npos) {
end = email.size();
}
string word = email.substr(start, end - start);
spam_prob += log(calcConditional(word, "spam"));
ham_prob += log(calcConditional(word, "ham"));
start = end + 1;
}
if (spam_prob > ham_prob) {
return "spam";
} else {
return "ham";
}
}
int main() {
readTrainingData("training.txt");
string email = "最新 产品 优惠 点击 链接";
string result = classify(email);
if (result == "spam") {
cout << "The email is spam" << endl;
} else {
cout << "The email is not spam" << endl;
}
return 0;
}
六、实验结果:根据训练集中的数据,可以计算得到以下结果:
先验概率:
P(spam) = 0.5
P(ham) = 0.5
条件概率(以垃圾邮件为例):
P(点击|spam) = 0.25
P(获得|spam) = 0.25
P(更多|spam) = 0.25
P(信息|spam) = 0.5
P(购买|spam) = 0.25
P(最新|spam) = 0.5
P(产品|spam) = 0.5
P(优惠|spam) = 0.5
P(链接|spam) = 0.25
条件概率(以正常邮件为例):
P(明天|ham) = 0.5
P(一起|ham) = 0.5
P(开会|ham) = 0.5
P(信息|ham) = 0.5
P(详见|ham) = 0.5
P(邮件|ham) = 0.5
P(最新|ham) = 0.5
P(竞品|ham) = 0.5
P(信息|ham) = 0.5
使用上述先验概率和条件概率,对一封新邮件进行分类,可以得到以下结果:
邮件内容:最新 产品 优惠 点击 链接
分类结果:spam(垃圾邮件)
七、实验总结:本实验利用贝叶斯算法实现了对邮件的垃圾邮件过滤。通过统计训练集中出现关键词的次数,计算出先验概率和条件概率,利用这些概率对新邮件进行分类判断。实验结果表明,该方法在过滤垃圾邮件方面有一定的效果。
阅读全文