逻辑回归是一种广泛使用的统计方法,用于解决分类问题,尤其是二分类问题。与线性回归不同,线性回归用于预测连续变量(例如房价),逻辑回归则用于预测离散变量,即类别。例如,在医学信息数据中,可能想要将人群分类为癌症患者或健康人群。这种分类问题可以通过逻辑回归来解决,其他应用场景还包括电子邮件分类(垃圾邮件/非垃圾邮件)等。
本文将介绍如何使用PyTorch库实现逻辑回归模型。PyTorch是一个流行的开源机器学习库,它提供了强大的工具来构建和训练深度学习模型。将通过一个简单的乳腺癌数据集来演示逻辑回归的实现步骤,包括数据加载、预处理、模型构建、训练优化和准确度计算。
将使用sklearn库中的乳腺癌数据集,这是一个简单的二分类数据集。首先,需要从sklearn.datasets模块加载数据集,并从中提取特征X和目标变量Y。
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
data = load_breast_cancer()
X, y = data.data, data.target
n_samples, n_features = X.shape
print(n_samples)
print(n_features)
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
上述代码中,首先加载了数据集,并提取了特征和目标变量。然后,使用train_test_split函数将数据集分为训练集和测试集,其中20%的数据用于测试,80%的数据用于训练。
在分类问题中,一个常见的预处理步骤是应用标准化缩放转换。这有助于提高模型的性能和收敛速度。
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.fit_transform(x_test)
import numpy as np
x_train = torch.from_numpy(x_train.astype(np.float32))
x_test = torch.from_numpy(x_test.astype(np.float32))
y_train = torch.from_numpy(y_train.astype(np.float32))
y_test = torch.from_numpy(y_test.astype(np.float32))
y_train = y_train.view(y_train.shape[0], 1)
y_test = y_test.view(y_test.shape[0], 1)
在上述代码中,首先使用StandardScaler对训练集和测试集进行标准化处理。然后,将NumPy数组转换为PyTorch张量,并确保数据类型为float32。最后,将目标变量y转换为列向量,以满足PyTorch的要求。
现在已经准备好了输入数据,接下来将编写一个自定义的PyTorch模型来实现逻辑回归。
import torch
import torch.nn as nn
class Logistic_Reg_model(nn.Module):
def __init__(self, no_input_features):
super(Logistic_Reg_model, self).__init__()
self.layer1 = nn.Linear(no_input_features, 20)
self.layer2 = nn.Linear(20, 1)
def forward(self, x):
y_predicted = self.layer1(x)
y_predicted = torch.sigmoid(self.layer2(y_predicted))
return y_predicted
在上述代码中,定义了一个名为Logistic_Reg_model的类,它继承自torch.nn.Module。在__init__方法中,定义了两个线性层,并将输入特征数量传递给第一个线性层。在forward方法中,将输入数据传递给这两个线性层,并在第二个线性层的输出上应用sigmoid激活函数。
在定义了模型类之后,可以初始化一个模型,并定义损失函数和优化算法。
model = Logistic_Reg_model(n_features)
criterion = nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
number_of_epochs = 100
for epoch in range(number_of_epochs):
y_prediction = model(x_train)
loss = criterion(y_prediction, y_train)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if (epoch+1) % 10 == 0:
print('epoch:', epoch+1, ', loss=', loss.item())
在上述代码中,首先初始化了一个模型,并定义了二元交叉熵损失函数(BCELoss)和随机梯度下降(SGD)优化器。然后,设置了训练的轮数,并编写了训练循环。在每个epoch中,执行前向传播,计算损失,执行反向传播,并更新模型权重。
with torch.no_grad():
y_pred = model(x_test)
y_pred_class = y_pred.round()
accuracy = (y_pred_class.eq(y_test).sum()) / float(y_test.shape[0])
print(accuracy.item())