逻辑回归
逻辑回归是一种用于分类的机器学习算法,尽管名字中有“回归”,但它主要用于二分类问题。
它的核心思想是:通过一个逻辑函数(通常是 Sigmoid 函数)将线性回归的结果映射到 0 到 1 之间,这样输出就可以表示为某个类别的概率。
简单来说,逻辑回归的流程是:
- 用一些特征来描述数据(比如一个人的年龄、收入等)。
- 定义一个线性方程,将这些特征组合起来。
- 把线性方程的结果通过 Sigmoid 函数转换成概率值(0 到 1 之间)。
- 根据概率值来判断数据属于哪个类别(比如概率大于 0.5 划为类别 1,否则划为类别 0)。
案例:判断一个游戏账号是否存在安全风险
假设我们有一个游戏平台,想判断一个账号是否存在被盗用或存在安全风险的情况。我们可以用账号的以下特征来判断:
- 账号最近一次登录距离上次登录的时间间隔(秒)
- 账号最近一次登录的地点变更次数
- 账号是否开启了双重认证(1 表示开启,0 表示未开启)
我们可以将账号分为两类:
- 类别 1:存在安全风险
- 类别 0:不存在安全风险
# 导入必要的库
import numpy as np # 用于数组和数学运算
import matplotlib.pyplot as plt # 用于数据可视化
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 定义数据集
# 每一行表示一个游戏账号的特征和标签(是否存在安全风险)
# 第一列:最近一次登录距离上次登录的时间间隔(秒)
# 第二列:最近一次登录的地点变更次数
# 第三列:是否开启了双重认证(1 表示开启,0 表示未开启)
# 第四列:标签(1 表示存在安全风险,0 表示不存在安全风险)
data = np.array([
[3600, 2, 0, 1], # 存在安全风险的账号
[7200, 3, 0, 1],
[1800, 1, 1, 0], # 不存在安全风险的账号
[900, 0, 1, 0],
[10800, 4, 0, 1],
[1200, 1, 1, 0],
[2400, 2, 0, 1],
[600, 0, 1, 0]
])
# 提取特征(前三列)和标签(最后一列)
X = data[:, :3] # 提取特征数据
y = data[:, 3] # 提取标签数据
# 数据标准化(特征缩放)
from sklearn.preprocessing import StandardScaler # 导入标准化工具
scaler = StandardScaler() # 创建标准化对象
X = scaler.fit_transform(X) # 对特征数据进行标准化处理
# 定义逻辑回归类
class LogisticRegression:
def __init__(self, learning_rate=0.01, num_iterations=1000):
self.learning_rate = learning_rate # 设置学习率,默认值为0.01
self.num_iterations = num_iterations # 设置迭代次数,默认值为1000
self.weights = None # 初始化权重为None
self.bias = None # 初始化偏置为None
# Sigmoid 函数(改进版本,避免溢出)
def sigmoid(self, z):
z = np.clip(z, -500, 500) # 限制输入值范围,防止计算溢出
return 1 / (1 + np.exp(-z)) # 计算Sigmoid函数值
# 训练模型方法
def fit(self, X, y):
# 初始化权重和偏置
n_samples, n_features = X.shape # 获取样本数和特征数
self.weights = np.zeros(n_features) # 权重初始化为0
self.bias = 0 # 偏置初始化为0
# 梯度下降优化
for i in range(self.num_iterations): # 迭代指定次数
# 计算线性组合
linear_model = np.dot(X, self.weights) + self.bias
# 通过 Sigmoid 函数得到预测概率
y_predicted = self.sigmoid(linear_model)
# 计算梯度
dw = (1 / n_samples) * np.dot(X.T, (y_predicted - y)) # 权重梯度
db = (1 / n_samples) * np.sum(y_predicted - y) # 偏置梯度
# 更新权重和偏置
self.weights -= self.learning_rate * dw # 根据梯度更新权重
self.bias -= self.learning_rate * db # 根据梯度更新偏置
# 预测函数
def predict(self, X):
linear_model = np.dot(X, self.weights) + self.bias # 计算线性组合
y_predicted = self.sigmoid(linear_model) # 转换为概率
# 将概率转换为类别(大于 0.5 划为类别 1,否则划为类别 0)
y_predicted_cls = [1 if i > 0.5 else 0 for i in y_predicted]
return np.array(y_predicted_cls) # 返回预测类别
# 创建逻辑回归实例并训练
model = LogisticRegression(learning_rate=0.01, num_iterations=1000) # 创建模型实例
model.fit(X, y) # 使用训练数据拟合模型
# 测试新数据
new_data = np.array([
[3000, 2, 0], # 预测这个账号是否存在安全风险
[1500, 0, 1]
])
# 对新数据进行标准化处理
new_data_scaled = scaler.transform(new_data) # 使用训练集的标准化参数对新数据进行标准化
# 预测结果
predictions = model.predict(new_data_scaled) # 对新数据进行预测
# 输出预测结果
for i in range(len(new_data)):
print(
f"账号 {
i + 1} 特征:最近登录时间间隔 {
new_data[i, 0]} 秒,地点变更次数 {
new_data[i, 1]} 次,双重认证 {
'开启' if new_data[i, 2] == 1 else '未开启'}")
print(f"预测结果:{
'存在安全风险' if predictions[i] == 1 else '不存在安全风险'}\n")
# 绘制决策边界(简化为二维特征可视化)
plt.figure(figsize=(10, 6)) # 设置图像大小
# 绘制已知数据点
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='green', label='不存在安全风险') # 绘制没有风险的点
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='red', label='存在安全风险') # 绘制存在风险的点
# 计算决策边界
x_values = np.linspace(-2, 2, 2) # 生成x轴的值
y_values =