基于Pytorch进行逻辑回归的一个例子(逻辑回归进行二分类问题处理)
之前我们进行通过线性回归进行了预测,获取连续数据;逻辑回归给出是,否的回答。
这里可以使用Sigmoid函数,将所有数据转换到(0,1]之间。
之前的线性回归使用平方差作为损失函数;逻辑回归的损失函数可以使用交叉熵,交叉熵会输出更大的损失,可以更快的优化。交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离的方法
这里使用心脏病数据集
需要构建多层感知器来实现,这里代码构建了3层
import torch
from torch import nn
import pandas as pd
# 1. 预处理数据
## 加载数据
data = pd.read_csv('heart.csv')
## 结果集和
Y_data = data.target.values.reshape(-1,1)
Y = torch.from_numpy(Y_data).type(torch.float32)
## 特征集合,13个特征值
X_data = data[[c for c in data.columns if c!='target']].values
X = torch.from_numpy(X_data).type(torch.float32)
# 2. 定义模型
class Model(nn.Module):
def __init__(self):
super().__init__()
self.liner_1 = nn.Linear(13, 64) # 输入层
self.liner_2 = nn.Linear(64, 64) # 输入层
self.liner_3 = nn.Linear(64, 1) # 输出层
self.relu = nn.ReLU() # 激活函数
self.sigmoid = nn.Sigmoid() # 激活函数
def forward(self, input):
x = self.liner_1(input)
x = self.relu(x)
x = self.liner_2(x)
x = self.relu(x)
x = self.liner_3(x)
x = self.sigmoid(x)
return x
# 3. 模型实例化
model = Model()
# 4. 训练模型,数据分批处理
lr = 0.0001
# 定义优化函数,使用Adam优化器
opt = torch.optim.Adam(model.parameters(), lr=lr)
# 定义损失函数
loss_fn = nn.BCELoss() # 这个正交熵函数仅能用于二分
batch = 32
no_of_batches = len(data) // batch
epochs = 100
for epoch in range(epochs):
for i in range(no_of_batches):
start = i * batch
end = start + batch
x = X[start:end]
y = Y[start:end]
y_pred = model(x)
loss = loss_fn(y_pred, y)
loss.backward()
opt.step()
with torch.no_grad():
# 打印损失值
print('epoch: ', epoch, ' loss:', loss_fn(model(X),Y).data.item())
上面的例子里面没有对结果的检验,这里可以进行一些修改,还有对于训练批次可以使用更好的方法。
- 使用SKLearn进行训练集,检验集的切分
- 使用dataloder进行批量处理:TensorDataSet
- 增加争取率验证
可以使用DataSet进行包装,分片
from torch.utils.data import TensorDataset
## 进行数据集合包装
heartDataSet = TensorDataset(X,Y)
## 模型训练
for epoch in range(epochs):
for i in range(no_of_batches):
# 通过DataSet进行数据分片
x,y = heartDataSet[i*batch: i*batch + batch]
y_pred = model(x)
loss = loss_fn(y_pred, y)
loss.backward()
opt.step()
with torch.no_grad():
# 打印损失值
print('epoch: ', epoch, ' loss:', loss_fn(model(X),Y).data.item())
使用DataLoad可以不用进行数据切片,增加最终进行争取率的校验
import torch
from torch import nn
import pandas as pd
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
from sklearn.model_selection import train_test_split
# 1. 预处理数据
## 加载数据
data = pd.read_csv('heart.csv')
## 结果集和
Y_data = data.target.values.reshape(-1,1)
Y = torch.from_numpy(Y_data).type(torch.float32)
## 特征集合,13个特征值
X_data = data[[c for c in data.columns if c!='target']].values
X = torch.from_numpy(X_data).type(torch.float32)
# train_data:所要划分的样本特征集
# train_target:所要划分的样本结果
# test_size:样本占比,如果是整数的话就是样本的数量
# random_state:是随机数的种子。
X_train,X_test, y_train, y_test = train_test_split(X,Y,test_size=0.25, random_state=0)
## 进行数据集合包装
heartDataSet = TensorDataset(X_train, y_train)
batch = 32
heartDataLoad = DataLoader(heartDataSet, batch_size=batch)
# 计算正确率的函数,如果概率>0.5就分类为1,
def accuracy(y_pred, y_true):
y_pred = (y_pred > 0.5).type(torch.int32)
acc = (y_pred == y_true).float().mean()
return acc
# 2. 定义模型
class Model(nn.Module):
def __init__(self):
super().__init__()
self.liner_1 = nn.Linear(13, 64) # 输入层
self.liner_2 = nn.Linear(64, 64) # 输入层
self.liner_3 = nn.Linear(64, 1) # 输出层
self.relu = nn.ReLU() # 激活函数
self.sigmoid = nn.Sigmoid() # 激活函数
def forward(self, input):
x = self.liner_1(input)
x = self.relu(x)
x = self.liner_2(x)
x = self.relu(x)
x = self.liner_3(x)
x = self.sigmoid(x)
return x
# 3. 模型实例化
model = Model()
# 4. 训练模型,数据分批处理
lr = 0.0001
# 定义优化函数,使用Adam优化器
opt = torch.optim.Adam(model.parameters(), lr=lr)
# 定义损失函数
loss_fn = nn.BCELoss() # 这个正交熵函数仅能用于二分
# 计算模型正确率,二分类模型通过概率进行验证,是否大于0.5
epochs = 100
for epoch in range(epochs):
for x, y in heartDataLoad:
y_pred = model(x)
loss = loss_fn(y_pred, y)
opt.zero_grad()
loss.backward()
opt.step()
with torch.no_grad():
epoch_accuracy = accuracy(model(X_train), y_train)
# 打印损失值
print('epoch: ', epoch, ' loss:', loss_fn(model(X),Y).data.item(), ' accuracy:', epoch_accuracy.item())