跳转至

逻辑回归模型

机器学习的分类

机器学习的两个种类:

  1. 有监督学习:数据集带标签(题目有正确答案)
  2. 无监督学习:数据集不带有标签,比如聚类算法

有监督学习两大任务:

  1. 回归任务:预测结果是无限个值,是连续值(体重值、分数值、可能性百分比...)
  2. 分类任务:预测结果的种类有限,是离散值(是/不是、健康/不健康...)

逻辑回归模型原理

逻辑回归是利用回归的方法进行二分类。

常用 \(σ(x)\) 或者 \(sig(x)\) 表示 sigmoid 函数。

线性回归模型的结果通过 sigmoid 函数映射到0-1的区间,通过阈值将其二分类。

损失函数

定义损失函数(以一维为例):

\(J(w,b) = y \cdot \log{σ(wx+b)}+(1-y) \cdot \log(1-σ(wx+b))\)

  • 对于一个样本,其真实标签为 \(y\)(取值为 0 或 1)。我们希望当 \(y=1\) 时,\(σ(wx+b)\) 尽可能地接近 1,当 \(y=0\) 时,\(σ(wx+b)\) 尽可能地接近 0。
  • 可以通过最大化 \(y\)\(σ(wx+b)\) 的乘积来实现这一点,即 \(y \cdot \log{σ(wx+b)}\)
  • 同时,也希望最小化 \((1-y)\)\((1-σ(wx+b))\) 的乘积,这样能使预测为负类时的概率尽可能地小,即 \((1-y) \cdot \log(1-σ(wx+b))\)
  • 对数函数有助于更方便地处理概率,提高计算稳定性。

权重 w 的更新

使用梯度下降更新 w 权重值:\(w=w-a\frac{dJ(w,b)}{dw}\)

偏置 b 的更新

使用梯度下降更新 b 偏置值:\(w=w-a\frac{dJ(w,b)}{db}\)

模型的评价指标

分类模型(离散结果)

定义正类。比如及格为正类,不及格为负类。

  1. 真正(TP):真实及格,预测也是及格
  2. 真负(TN):真实不及格,预测也是不及格
  3. 假正、误报(FP):真实为不及格,预测成了及格
  4. 假负、漏报(FN):真实为及格,预测成了不及格

准确率:\(ACC=\frac{TP+TN}{TP+TN+FP+FN}=\frac{\text{猜对的数量}}{\text{所有样本数量}}\)

对于样本不均衡数据(原始的数据中,正类和负类数量不一致),准确率ACC不能完全衡量模型好坏。

精确率:在正类中猜对的概率。 \(P=\frac{TP}{TP+FP}=\frac{\text{猜对正类的数量}}{\text{预测为正类数量}}\)

召回率(查全率):在所有正类中,预测到的概率。\(\text{召回率}=\frac{TP}{TP+FN}=\frac{\text{猜对正类的数量}}{\text{真实正类的数量}}\)

召回率有局限性:若全猜正类,FN(漏报)为0,召回率100%。

F1值:精确率和召回率的均值。\(\text{F1}= \frac{2TP}{2TP+FP+FN}\)

回归模型(连续结果)

平均绝对误差(MAE)

均方误差(MSE)

均方根误差(RMSE)

MAPE

代码实现

特征数据 x 中不同特征的物理量纲不同,模型依赖数值较大的特征。

解决办法:归一化(求平均值化为0~1之间)

# 0. 导入模块
# 数据处理
import numpy as np
import pandas as pd

# 划分数据集合测试集
from sklearn.model_selection import train_test_split

# 用于特征数据的归一化
from sklearn.preprocessing import MinMaxScaler

# 导入逻辑回归模型
from sklearn.linear_model import LogisticRegression

# 计算评价指标
from sklearn.metrics import classification_report

# 1. 读取数据
dataset = pd.read_csv('heart_disease.csv')
# print(dataset)

# 2. 划分特征与标签
# [:, :-1] 表示选择所有的行(":")和除了最后一列之外的所有列(":-1")
X = dataset.iloc[:, :-1]
Y = dataset.iloc[:, -1]

# 3. 对特征值进行归一化
scaler = MinMaxScaler(feature_range=(0, 1))
X = scaler.fit_transform(X)

# 4. 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=.2)

# 5. 实例化模型
lr = LogisticRegression()
lr.fit(x_train, y_train)

# 6. 训练完成,输出w和b的值
print(f'w: {lr.coef_}')
print(f'b: {lr.intercept_}')

# 7. 使用模型数据进行预测
result = lr.predict(x_test)
# print(f'预测结果: {result}')
# print(f'y_test: {y_test.values}')
check = 0
for i, j in zip(result, y_test.values):
    if i == j:
        check += 1
print(f"准确率: {check / len(result) * 100 : .5f}%")

# 8. 查看模型评测结果
report = classification_report(y_test, result, labels=[0, 1])
print(report)