机器学习——朴素贝叶斯算法

一.贝叶斯公式

1.先验概率

 P(cj)代表还没有训练模型之前,根据历史数据/经验估算cj拥有的初始概率。P(cj)常被称为cj的先验概率(prior probability) ,它反映了cj的概率分布,该分布独立于样本。

通常可以用样例中属于cj的样例数|cj|比上总样例数|D|来近似,即:

                                            

2.后验概率

 给定数据样本x时cj成立的概率P(cj  | x )被称为后验概率(posterior probability),因为它反映了在看到数据样本 x后 cj 成立的置信度。(大部分机器学习模型尝试得到后验概率。

3.贝叶斯定理

                                       

已知两个独立事件A和B,事件B发生的前提下,事件A发生的概率可以表示为P(A|B),即上图中橙色部分占红色部分的比例,即: 

                                  

4.机器学习两大视角

·生成式模型:

估计的是联合概率分布,然后求出条件概率分布P(Y|X)作为预测的模型,即生成模型:P(Y|X)= P(X,Y)/ P(X)。

生成方法关心的是给定输入x产生输出y的生成关系。

·判别式模型:

估计的是条件概率分布,有数据直接学得决策函数P(X)或者条件概率分布P(Y|X)作为预测的模型。

判别式方法关心的是给定输入X,应该预测什么样的输出Y。

二.基于贝叶斯的垃圾邮件分类

·基本流程

1.准备数据集:收集一定数量的垃圾邮件和正常邮件,并标记好它们的分类。

2.分词:对每封邮件进行分词处理,将邮件内容拆分成单词。

3.统计词频:统计每个单词在垃圾邮件和正常邮件中出现的频率,并计算其在垃圾邮件和正常邮件中出现的概率。

4.计算联合概率:对于每封邮件,根据其包含的单词及其出现概率,计算它属于垃圾邮件和正常邮件的联合概率。

5.决策分类:选择联合概率更高的分类作为该封邮件的分类。

·代码如下

import os
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

# 下载停用词列表
nltk.download('stopwords')

# 加载英语停用词
stop_words = set(stopwords.words('english'))

# 定义文本处理函数
def process_text(text):
    # 将文本转换为小写
    text = text.lower()
    # 分词
    tokens = word_tokenize(text)
    # 去除停用词
    tokens = [token for token in tokens if token not in stop_words]
    # 仅保留字母字符
    tokens = [token for token in tokens if token.isalpha()]
    # 将词汇转换为词干
    stemmer = nltk.PorterStemmer()
    tokens = [stemmer.stem(token) for token in tokens]
    # 将所有词汇连接为一个字符串
    text = ' '.join(tokens)
    return text

# 定义读取文件函数
def read_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        text = f.read()
    return text

# 定义获取文件列表函数
# 定义获取文件列表函数
def get_files(data_dir):
    spam_files = [os.path.join(data_dir, 'spam', file) for file in os.listdir(os.path.join(data_dir, 'spam'))]
    ham_files = [os.path.join(data_dir, 'ham', file) for file in os.listdir(os.path.join(data_dir, 'ham'))]
    return spam_files, ham_files

# 使用新的文件路径调用函数
data_dir = r'D:\新建文件夹\pythonTest\email'
spam_files, ham_files = get_files(data_dir)
print(spam_files)
print(ham_files)
# 定义生成特征集函数
def get_features(text):
    features = {}
    for word in text.split():
        features[word] = True
    return features

# 加载数据集
data_dir = './email'
spam_files, ham_files = get_files(data_dir)

# 处理文本并生成特征集
spam_data = [(get_features(process_text(read_file(file))), 'spam') for file in spam_files]
ham_data = [(get_features(process_text(read_file(file))), 'ham') for file in ham_files]
all_data = spam_data + ham_data

# 划分训练集和测试集
train_size = int(len(all_data) * 0.8)
train_data = all_data[:train_size]
test_data = all_data[train_size:]

# 训练朴素贝叶斯分类器
classifier = nltk.NaiveBayesClassifier.train(train_data)

# 在测试集上评估分类器的性能
accuracy = nltk.classify.accuracy(classifier, test_data)
print('Accuracy:', accuracy)

# 对新邮件进行分类
new_email = 'Dear customer, your account has been selected to receive a prize of $1,000,000! Click here to claim your prize now!'
new_email_features = get_features(process_text(new_email))
prediction = classifier.classify(new_email_features)
print('Prediction:', prediction)

·代码解析

  1. 定义文本处理函数process_text(),用于将文本转换为小写、分词、去除停用词、只保留字母字符、将词汇转换为词干等操作,以减少特征数量。
  2. 定义读取文件函数read_file(),用于读取指定文件的内容。
  3. 定义获取文件列表函数get_files(),用于获取指定文件夹中的所有文件路径列表。
  4. 定义生成特征集函数get_features(),用于将文本转换为特征集,其中特征为单词,值为True或False,表示单词是否在文本中出现过。
  5. 加载数据集,包括垃圾邮件和非垃圾邮件,对每个邮件生成特征集,并按照80%的比例划分训练集和测试集。
  6. 使用朴素贝叶斯分类器训练模型,并在测试集上评估模型的性能。
  7. 对新邮件进行分类,并输出结果。

·运行结果

从输出结果可以看出,数据集已成功加载,并且训练集和测试集已正确划分。模型在测试集上的准确率为0.975,预测一封新邮件为垃圾邮件。

三.实验小结

1.我们可能发生的错误

由于涉及到数据集问题,我们要将正确的数据集路径写进代码,否则很可能就会出现我这样的问题

2.在处理 NLTK stopwords 资源加载错误时,大概率就是资源加载路径的问题,我也查询了很多资料,这个命令会输出所有 NLTK 数据的路径列表:

import nltk
print(nltk.data.path)

希望大家共同进步!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值