使用logistics回归简单实现垃圾邮件分类

目录

介绍

代码实现

完整代码如下:

运行结果如下:

总结


  • 介绍

        logistics回归是一种广泛应用于分类任务的统计学习方法。该算法的基础是sigmoid函数,也称为逻辑函数。sigmoid函数可以将任意实数映射到区间[0,1],因此可以用来表示概率。

        在logistics回归中,模型通过对输入特征的线性组合进行sigmoid函数变换,得到输出结果。模型参数的学习使用了最大似然估计方法,即使得训练数据样本的条件概率最大化。这样,logistics回归模型就可以对新的样本进行分类,并给出该样本属于每个类别的概率值。

        logistics回归可以用来预测某个事件发生的概率,并将其转化为二元分类问题。例如,预测一个人是否会购买某款产品等。

  • 代码实现

        上次我们使用了朴素贝叶斯来实现垃圾邮件分类,而垃圾邮件分类也是二元分类问题,所以这次我们使用logistics回归来实现相同的垃圾邮件分类

        首先,我们准备测试数据email.txt,其中的数据格式就设定为“邮件信息”+“标签”的形式,方便我们进行数据获取。这里直接再利用一下上次实验使用的测试数据。

        之后,读取数据与处理数据的方法和朴素贝叶斯相同,遍历lines列表中的每一行,使用strip()方法去除多余的空格和换行符,并使用split(';')方法按照分号将每行数据分割成两部分。然后将每行数据转换为元组的形式,并将所有元组组成的列表存储在training_data变量中,最后使用split()将其方法将其分割成单词,转化为词袋文件。

# 读取email.txt文件
with open('C:/Users/86188/Desktop/email.txt', 'r') as file:
    lines = file.readlines()

# 处理数据
training_data = [tuple(line.strip().split(';')) for line in lines]

# 将训练数据转换为词袋模型
word_bag = set([word for email, _ in training_data for word in email.split()])

        然后,我们遍历training_data列表中的每个元组,将每个邮件转换为特征向量和标签向量。首先创建一个长度为词袋模型单词数量的全零列表 x,然后将该邮件中出现的单词在词袋word_bag中对应的位置置为 1。最后,将特征向量 x 添加到特征向量列表 x 中,将标签添加到标签向量列表 y 中。再使用numpy库创建一个长度为词袋模型单词数量的全零向量,并将其存储在theta变量中。

# 构建特征向量和标签向量
X = []
y = []
for email, label in training_data:
    x = [0] * len(word_bag)
    words = email.split()
    for word in words:
        if word in word_bag:
            x[list(word_bag).index(word)] = 1
    X.append(x)
    y.append(int(label))

# 初始化参数向量
theta = np.zeros(len(word_bag))

        logistics重要的一步来了,我们要定义sigmoid函数和代价函数。我们定义一个 sigmoid 函数1 / (1 + np.exp(-z)),用于将输入的值映射到 0 到 1 之间的范围。代价函数是用于计算当前参数向量theta下的损失函数值。其中,m是训练样本的数量,z是特征向量x与参数向量theta的乘积,h是将z应用于sigmoid函数得到的预测结果,cost是代价函数的值。最后,我们再定义了一个梯度下降函数,用于最小化代价函数。在每次迭代中,首先计算特征向量 X 与参数向量theta的乘积,并将其应用于sigmoid函数得到预测结果。然后计算梯度grad,并使用学习率alpha进行参数更新。最后,将每次迭代的代价函数值存储在列表J_history中,并返回最优的参数向量theta和代价函数值列表。

# 定义 sigmoid 函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 定义代价函数
def cost_function(theta, X, y):
    m = len(y)
    z = X @ theta
    h = sigmoid(z)
    cost = -y @ np.log(h) - (1-y) @ np.log(1-h)
    return cost / m

# 定义梯度下降函数
def gradient_descent(theta, X, y, alpha, num_iters):
    m = len(y)
    J_history = []
    for i in range(num_iters):
        z = X @ theta
        h = sigmoid(z)
        grad = X.T @ (h - y)
        theta -= alpha / m * grad
        J_history.append(cost_function(theta, X, y))
    return theta, J_history

        最后的步骤就是就行模型的训练了。我们设置学习率alpha和迭代次数num_iters,然后使用上一步定义的梯度下降函数来训练模型,得到最优的参数向量theta和代价函数值列表J_history。再定义了一个预测函数,用于将测试数据转换为特征向量并进行预测。首先计算特征向量x与参数向量theta的乘积,并将其应用于sigmoid函数得到预测结果。如果预测结果大于等于 0.5,则判断为垃圾邮件,否则判断为非垃圾邮件。最后通过输入函数手动输入测试数据,将该数据转换为特征向量,并使用预测函数进行预测。最后将预测结果打印输出。

# 训练模型
alpha = 0.1
num_iters = 100
theta, J_history = gradient_descent(theta, np.array(X), np.array(y), alpha, num_iters)

# 定义预测函数
def predict(theta, x):
    z = x @ theta
    h = sigmoid(z)
    if h >= 0.5:
        return '这是垃圾邮件'
    else:
        return '这不是垃圾邮件'

# 手动输入测试数据
test_email = input("请输入邮件内容:")
x = [0] * len(word_bag)
words = test_email.split()
for word in words:
    if word in word_bag:
        x[list(word_bag).index(word)] = 1
result = predict(theta, np.array(x))
print(result)
完整代码如下:
import numpy as np
import math

# 读取email.txt文件
with open('C:/Users/86188/Desktop/email.txt', 'r') as file:
    lines = file.readlines()

# 处理数据
training_data = [tuple(line.strip().split(';')) for line in lines]

# 将训练数据转换为词袋模型
word_bag = set([word for email, _ in training_data for word in email.split()])

# 构建特征向量和标签向量
X = []
y = []
for email, label in training_data:
    x = [0] * len(word_bag)
    words = email.split()
    for word in words:
        if word in word_bag:
            x[list(word_bag).index(word)] = 1
    X.append(x)
    y.append(int(label))

# 初始化参数向量
theta = np.zeros(len(word_bag))

# 定义 sigmoid 函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 定义代价函数
def cost_function(theta, X, y):
    m = len(y)
    z = X @ theta
    h = sigmoid(z)
    cost = -y @ np.log(h) - (1-y) @ np.log(1-h)
    return cost / m

# 定义梯度下降函数
def gradient_descent(theta, X, y, alpha, num_iters):
    m = len(y)
    J_history = []
    for i in range(num_iters):
        z = X @ theta
        h = sigmoid(z)
        grad = X.T @ (h - y)
        theta -= alpha / m * grad
        J_history.append(cost_function(theta, X, y))
    return theta, J_history

# 训练模型
alpha = 0.1
num_iters = 100
theta, J_history = gradient_descent(theta, np.array(X), np.array(y), alpha, num_iters)

# 定义预测函数
def predict(theta, x):
    z = x @ theta
    h = sigmoid(z)
    if h >= 0.5:
        return '这是垃圾邮件'
    else:
        return '这不是垃圾邮件'

# 手动输入测试数据
test_email = input("请输入邮件内容:")
x = [0] * len(word_bag)
words = test_email.split()
for word in words:
    if word in word_bag:
        x[list(word_bag).index(word)] = 1
result = predict(theta, np.array(x))
print(result)
运行结果如下:

  • 总结

        在logistics回归实现中,首先需要收集合适的数据集,并进行必要的预处理。这包括数据清洗、特征选择、缺失值处理等,确保数据集的质量和完整性对于实验结果的准确性非常重要。而特征工程和数据划分也会影响着模型性能和表达能力以及模型的泛化能力。

        而与其他机器学习算法相比,logistics回归具有以下特点:1.参数易于解释:logistics回归模型中的每个参数都可以理解为对应特征的权重,可以帮助研究者更好地理解模型的作用和影响;2.计算速度快:logistics回归算法的计算量较小,可以快速处理大规模数据集;3.适用性广泛:logistics回归可以用于二元分类问题,也可以扩展到多元分类问题,同时也可以处理连续和离散型的特征。

        总之,机器学习中logistics回归的实验过程需要合理的数据处理、特征工程、模型训练与优化,以及结果评估和分析。通过不断迭代改进,可以得到适用于特定任务的高性能logistics回归模型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值