解释一下下面这个代码 # 自己实现 # 计算 每个词在垃圾邮件中出现的概率和在正常邮件中出现的概率 # 统计正常邮件和垃圾邮件的个数 def calEmailsFreq(Emails): WordsCount={} # 概率表:{词:[垃圾概率,正常概率]} HamCount = 0 # 正常邮件的个数 SpamCount = 0 # 垃圾邮件的个数 # 遍历邮件列表 for email in Emails: label = email[0] words = email[1] if label == "spam": SpamCount += 1 # 垃圾邮件计数 for word in words: if word in WordsCount: WordsCount[word][0] += 1 else: WordsCount[word] = [1,0] else: HamCount += 1 # 正常邮件计数 for word in words: if word in WordsCount: WordsCount[word][1] += 1 else: WordsCount[word] = [0,1] for word in WordsCount.keys(): WordsCount[word][0] /= SpamCount WordsCount[word][1]/= HamCount return WordsCount,HamCount,SpamCount
时间: 2024-02-14 07:14:32 浏览: 20
这段代码实现了统计邮件数据集中每个词在垃圾邮件和正常邮件中出现的概率,并返回概率表、正常邮件个数和垃圾邮件个数。
首先定义了一个空字典`WordsCount`,用于统计每个词在垃圾邮件和正常邮件中出现的次数。同时,定义了变量`HamCount`和`SpamCount`,分别表示正常邮件和垃圾邮件的个数,初始值均为0。
然后,遍历邮件列表,对于每封邮件,获取它的标签和内容。如果标签是"spam",则将`SpamCount`加1,同时遍历邮件内容中的每个词,如果词已经在`WordsCount`中出现过,则将它在垃圾邮件中出现的次数加1;否则,将它添加到`WordsCount`中,并将它在垃圾邮件中出现的次数初始化为1,正常邮件中出现的次数初始化为0。如果标签是"ham",则类似地更新`HamCount`和`WordsCount`中每个词在正常邮件中出现的次数。
接着,遍历`WordsCount`中的每个词,将它在垃圾邮件中出现的次数除以`SpamCount`,将它在正常邮件中出现的次数除以`HamCount`,得到它在垃圾邮件和正常邮件中出现的概率。最后,返回概率表、正常邮件个数和垃圾邮件个数。
需要注意的是,该代码中并未进行平滑处理,有可能会出现概率为0的情况,导致后续计算出错。在实际应用中,建议对概率进行平滑处理,例如使用拉普拉斯平滑。
相关问题
计算每个词在垃圾邮件和正常频率的概率代码
好的,以下是一个简单的代码例子,假设我们已经有了垃圾邮件和正常邮件的数据集:
```
# 垃圾邮件和正常邮件的词频统计
spam_word_counts = {}
ham_word_counts = {}
# 统计垃圾邮件中每个词的出现次数
for email in spam_emails:
for word in email.split():
if word not in spam_word_counts:
spam_word_counts[word] = 1
else:
spam_word_counts[word] += 1
# 统计正常邮件中每个词的出现次数
for email in ham_emails:
for word in email.split():
if word not in ham_word_counts:
ham_word_counts[word] = 1
else:
ham_word_counts[word] += 1
# 计算每个词在垃圾邮件和正常频率的概率
word_probabilities = {}
for word in set(list(spam_word_counts.keys()) + list(ham_word_counts.keys())):
spam_frequency = spam_word_counts.get(word, 0) / len(spam_emails)
ham_frequency = ham_word_counts.get(word, 0) / len(ham_emails)
word_probabilities[word] = {
'spam_probability': spam_frequency / (spam_frequency + ham_frequency),
'ham_probability': ham_frequency / (spam_frequency + ham_frequency)
}
```
这段代码中,我们首先定义了两个空字典`spam_word_counts`和`ham_word_counts`,用于统计垃圾邮件和正常邮件中每个词的出现次数。然后,我们分别遍历垃圾邮件和正常邮件的数据集,对于每个邮件中出现的每个词,我们在相应的字典中增加对应的计数。
接着,我们定义了一个新的字典`word_probabilities`,用于存储每个词在垃圾邮件和正常邮件中出现的概率。我们遍历了所有出现过的词,计算它在垃圾邮件和正常邮件中的频率,并将它们归一化后得到对应的概率。
最终,我们得到了一个字典`word_probabilities`,它的每个键值对表示一个词在垃圾邮件和正常邮件中出现的概率。我们可以通过查询这个字典来判断一个邮件是垃圾邮件还是正常邮件。
手写代码实现朴素贝叶斯分类器(采用拉普拉斯修正)过滤垃圾邮件,在程序中自行下载所需的数据集,给出完整代码
好的,以下是手写代码实现朴素贝叶斯分类器进行垃圾邮件过滤的完整代码:
```python
import os
import random
import math
import re
from collections import defaultdict
# 定义数据集路径
HAM_DIR = 'data/ham'
SPAM_DIR = 'data/spam'
# 定义常量
TRAIN_RATIO = 0.8 # 训练集占总数据集比例
ALPHA = 1 # 拉普拉斯平滑参数
# 定义全局变量
vocab = set() # 词库
ham_word_count = defaultdict(int) # 非垃圾邮件中每个词出现的次数
spam_word_count = defaultdict(int) # 垃圾邮件中每个词出现的次数
ham_doc_count = 0 # 非垃圾邮件数量
spam_doc_count = 0 # 垃圾邮件数量
def read_files(dir_path):
"""
读取文件,返回文件内容和是否为垃圾邮件标记
"""
files = os.listdir(dir_path)
data = []
for file_name in files:
with open(os.path.join(dir_path, file_name), 'r', encoding='utf8', errors='ignore') as f:
content = f.read()
is_spam = 1 if dir_path == SPAM_DIR else 0
data.append((content, is_spam))
return data
def train(train_data):
"""
训练朴素贝叶斯分类器
"""
global ham_doc_count, spam_doc_count
for content, is_spam in train_data:
if is_spam:
spam_doc_count += 1
else:
ham_doc_count += 1
words = re.findall('\w+', content.lower())
for word in words:
vocab.add(word)
if is_spam:
spam_word_count[word] += 1
else:
ham_word_count[word] += 1
def predict(content):
"""
预测邮件是否为垃圾邮件
"""
words = re.findall('\w+', content.lower())
# 计算先验概率
ham_prob = math.log(ham_doc_count / (ham_doc_count + spam_doc_count))
spam_prob = math.log(spam_doc_count / (ham_doc_count + spam_doc_count))
# 计算条件概率
for word in vocab:
ham_prob += math.log((ham_word_count[word] + ALPHA) / (sum(ham_word_count.values()) + ALPHA * len(vocab)))
spam_prob += math.log((spam_word_count[word] + ALPHA) / (sum(spam_word_count.values()) + ALPHA * len(vocab)))
# 预测
return 1 if spam_prob > ham_prob else 0
if __name__ == '__main__':
# 读取数据
ham_data = read_files(HAM_DIR)
spam_data = read_files(SPAM_DIR)
# 划分训练集和测试集
train_data = ham_data[:int(len(ham_data) * TRAIN_RATIO)] + spam_data[:int(len(spam_data) * TRAIN_RATIO)]
test_data = ham_data[int(len(ham_data) * TRAIN_RATIO):] + spam_data[int(len(spam_data) * TRAIN_RATIO):]
# 训练模型
train(train_data)
# 测试模型
correct_count = 0
for content, is_spam in test_data:
if predict(content) == is_spam:
correct_count += 1
accuracy = correct_count / len(test_data)
print(f'Test accuracy: {accuracy:.2%}')
```
在这个实现中,我们先读取数据集,并将数据集划分为训练集和测试集。然后,在训练集上训练朴素贝叶斯分类器,计算词汇表、每个词在垃圾邮件和非垃圾邮件中出现的次数以及垃圾邮件和非垃圾邮件的数量。最后,在测试集上测试模型的准确率。
需要注意的是,在计算条件概率时,我们采用了拉普拉斯平滑,将每个词在垃圾邮件和非垃圾邮件中出现的次数加上了一个常数 ALPHA,以避免出现概率为 0 的情况。
希望这个实现能对你有所帮助!