逻辑回归是一种“监督式机器学习”算法,用于模拟某个类别或事件的概率。当数据线性可分且结果为二元或二分性质时,通常使用逻辑回归。这意味着逻辑回归通常用于二元分类问题。二元分类指的是预测输出变量为两个离散类别的情况,例如是/否、通过/失败、赢/输、癌症/非癌症等。
简单逻辑回归:使用单个独立变量来预测输出。多重逻辑回归:使用多个独立变量来预测输出。
尽管逻辑回归通常用于二元分类,但它可以扩展到解决多类分类问题。多项式逻辑回归:输出变量为三个或更多无自然排序的离散类别,例如食物质地:脆、软、脆,或头发颜色:金发、棕色、深褐色、红色。有序逻辑回归:输出变量为三个或更多有序级别的离散类别,例如客户评级:极度不喜欢、不喜欢、中立、喜欢、极度喜欢,或收入水平:低收入、中等收入、高收入。
在深入逻辑回归之前,建议阅读有关简单线性回归的文章,以便复习。现在,尝试使用线性回归来解决二元分类问题。假设有一个数据集,它是线性可分的,并且输出为两个离散类别(0,1)。在线性回归中,绘制一条直线(最佳拟合线)L1,使得所有数据点到该线的距离之和最小。直线L1的方程是y=mx+c,其中m是斜率,c是y截距。
# 线性回归模型示例
y = mx + c
定义一个阈值T=0.5,超过该阈值的输出属于类别1,否则属于类别0。然而,线性回归模型在预测值可能超出(0,1)范围以及数据中存在异常值时会增加错误率的情况下存在问题。因此,逻辑回归在这里是必要的。
逻辑回归方程与线性回归模型非常相似。假设有一个模型,其中有一个预测变量“x”和一个伯努利响应变量“ŷ”,p是ŷ=1的概率。线性方程可以写成:
p = b0 + b1 * x
方程右侧(b0 + b1 * x)是一个线性方程,可能包含超出范围(0,1)的值。但知道概率总是在(0,1)范围内。为了解决这个问题,预测赔率而不是概率。赔率是事件发生概率与不发生概率的比率。赔率 = p / (1-p)。方程1可以重写为:
p / (1 - p) = b0 + b1 * x
为了处理负数,预测赔率的对数。对数赔率 = ln(p / (1-p))。方程2可以重写为:
ln(p / (1 - p)) = b0 + b1 * x
为了从方程3中恢复p,在两边应用指数。exp(ln(p / (1-p))) = exp(b0 + b1 * x)。根据对数的反规则,p / (1 - p) = e^(b0 + b1 * x)。通过简单的代数操作,得到:
p = e^(b0 + b1 * x) / (1 + e^(b0 + b1 * x))
类似地,具有‘n’个预测变量的逻辑模型的方程如下:
p = 1 / (1 + e^-(b0 + b1 * x1 + b2 * x2 + ... + bn * xn))
右侧的部分看起来熟悉吗?是的,它是sigmoid函数。它有助于将输出压缩在0和1之间。sigmoid函数:sigmoid函数有助于将任何预测值的概率映射到0和1之间的另一个值。从线性方程开始,最终得到了逻辑回归模型,这得益于sigmoid函数。
# 定义数据集URL
dataset_url = "https://raw.githubusercontent.com/harika-bonthu/02-linear-regression-fish/master/datasets_229906_491820_Fish.csv"
# 从鱼类数据集创建pandas数据框
import pandas as pd
fish = pd.read_csv(dataset_url, error_bad_lines=False)
fish.head()
# 检查目标特征的唯一类别。数据集包含关于7种鱼类的信息
fish['Species'].unique()
# 检查是否有任何空值。数据集没有空值。
fish.isnull().sum()
# 定义输入和目标变量
X = fish.iloc[:, 1:]
y = fish.loc[:, 'Species']
# 使用MinMaxScaler缩放输入特征
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
# 使用LabelEncoder对目标变量进行标签编码
from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y)
# 使用train_test_split将数据集分割为训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 构建和训练模型
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
# 训练模型
clf.fit(X_train, y_train)
# 预测输出
y_pred = clf.predict(X_test)
# 计算准确率
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy: {:.2f}%".format(accuracy * 100))
from sklearn.metrics import confusion_matrix
cf = confusion_matrix(y_test, y_pred)
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure()
sns.heatmap(cf, annot=True)
plt.xlabel('Prediction')
plt.ylabel('Target')
plt.title('Confusion Matrix')