逻辑回归
逻辑回归是一种用于二分类问题的算法,它使用逻辑函数(通常是Sigmoid函数)将线性模型的输出转换为0到1之间的概率。
用途
预测一个事件是否发生,或者是不是某个类别(即分类问题,尤其是二分类)。
比如:
- 邮件是不是垃圾邮件(是/不是)
- 用户是否会购买商品
- 一张图片是不是猫
应用场景
- 垃圾邮件检测
- 疾病诊断
- 客户流失预测
- 信用评分
优缺点
优点 | 缺点 |
---|---|
输出是概率,便于解释 | 只适用于线性可分问题 |
不易过拟合 | 预测能力可能不如复杂模型 |
训练快速 | 无法处理非线性决策边界 |
模型形式
逻辑回归先算一个线性组合的值,再通过一个 sigmoid 函数把值"压缩"到 0~1 之间,变成概率如果结果大于 0.5,通常就预测是"1类",否则是"0类"。
逻辑回归原理代码
# 公式y = wx + b
# w为权重,b为偏置值
import numpy as np
from matplotlib import pyplot as plt
class Sline:
def __init__(self):
# 设置初始的w与b
self.w = 0
self.b = 0
# 设置每次移动的角度,精确度
self.learn_rate = 0.01
# 创建一个两行一列的窗口和两个画布
self.fig, (self.ax1, self.ax2) = plt.subplots(2, 1)
# 创建一个获取损失值的数组
self.loss_list = []
# 获取传入的数据,散点
def get_data(self, data):
# 获取数据的初始x与y
self.X = np.array(data)[:,0]
self.y = np.array(data)[:,1]
# 将函数组合
def predict(self, x):
return 1 / (1 + np.exp(-(self.w * x + self.b)))
# 进行模型训练,提供训练次数
def train(self, epoch_times):
for epoch in range(epoch_times):
# 统计损失次数
totle_loss = 0
# 遍历数据中所有对应的x与y
for x, y in zip(self.X, self.y):
# 计算在函数上的y值
y_pred = self.predict(x)
# 自求导,求出当前w与b
grad = -2 * (y - y_pred) * (1 - y_pred) * y_pred * x
# 更新新的w与b
self.w -= self.learn_rate * grad * x
self.b -= self.learn_rate * grad
# 计算均值方差,使用原y值减去在函数上的y值,计算损失值e
loss = (y - y_pred) ** 2
totle_loss += loss
epoch_loss = totle_loss / len(self.X)
self.loss_list.append(epoch_loss)
# 训练10次后打印训练十次后的缺失值
if epoch % 10 == 0:
print(f"loss: {epoch_loss}")
self.plot()
plt.ioff()
plt.show()
def plot(self):
plt.ion()
self.ax1.clear()
self.ax2.clear()
x = np.linspace(0, 10, 100)
self.ax1.scatter(self.X, self.y, c = "g")
self.ax1.plot(x, self.predict(x), c = "b")
self.ax2.plot(list(range(len(self.loss_list))), self.loss_list)
plt.show()
plt.pause(0.1)
if __name__ == '__main__':
data = [(1, 0), (1.8, 0), (2.5, 0), (4.2, 1), (5, 1), (6, 1), (7, 1)]
s = Sline()
s.get_data(data)
s.train(1000)
使用sklearn模块
"""
@Author: Anziron
@Email: 1312235991@qq.com
@FileName: 04-逻辑回归sklearn.py
@DateTime: 2025/04/11 16:13
@SoftWare: VSCode
"""
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# 加载数据集,手写数据集
digits = datasets.load_digits()
# 获取特征和目标变量
X = digits.data
y = digits.target
# 数据预处理:随机分割训练集和测试集 , 如果不指定 random_state,每次运行结果都不一样。42为约定俗成的随机数种子
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数据标准化
scaler = StandardScaler()
# .fit_transform()方法先拟合数据,再标准化。和降维算法的语法一致
X_train = scaler.fit_transform(X_train)
# .transform()方法直接使用在测试集上进行标准化操作
X_test = scaler.transform(X_test)
# 创建Logistic Regression模型 , 如果不指定 random_state,每次运行结果都不一样。42为约定俗成的随机数种子
model = LogisticRegression(random_state=42)
# .fit()方法用于拟合模型,即训练模型
model.fit(X_train, y_train)
# .predict()方法预测新数据点的类别
y_pred = model.predict(X_test)
from sklearn.metrics import accuracy_score
# accuracy_score()方法计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')
from matplotlib import pyplot as plt
# 选出预测错误的样本
index = []
# 遍历所有样本
for i in range(len(y_pred)):
# 判断是否相等
if y_pred[i] != y_test[i]:
# 如果不相等,添加到index中:预测值,真实值,图片(注意要变换形状为8*8)
index.append((
y_pred[i],
y_test[i],
X_test[i].reshape((8, 8))))
# 创建一个正方形画布
# nrows:子图的行数
# ncols:子图的列数
# print(len(index)) // 10
# 因为一共有10张图片,所以行数为2,列数为5,即2*5=10
fig, ax = plt.subplots(
nrows=3,
ncols=5,
)
# 实例化子画布
ax = ax.flatten()
for i in range(len(index)):
p = index[i][0] # 取出预测值
a = index[i][1] # 取出真实值
img = index[i][2] # 取出图片
# 在子画布上画出图片,格式为灰度图
ax[i].imshow(img)
ax[i].set_title(f'{p}-{a}')
plt.show()
实战示例
from sklearn.linear_model import LogisticRegression
# 特征
X = [
[5.2, 30, 8],
[10.5, 50, 12],
[2.3, 20, 10],
[0.9, 10, 2]
]
# 标签(多个类别)
y = ['猫', '狗', '兔子', '鸟']
# 模型训练
model = LogisticRegression(multi_class='multinomial', solver='lbfgs', max_iter=1000)
model.fit(X, y)
# 新动物识别
new_animal = [[4.5, 25, 7],[2, 3, 4]]
pred = model.predict(new_animal)
# 内置Softmax,会将新预测值传入训练好的公式中
# 将每一个y求出来进行概率判断
# 选择最大概率返回
print("预测结果是:", pred[0])
print("预测结果是:", pred[1])