Logistic回归介绍
logistic回归是一种广义线性回归,与多重线性回归有很多相同之处。它们的模型形式基本上相同,都有wx+b,但是区别在于,多重线性回归直接将y=wx+b作为因变量,而logistic回归是通过一个函数L将wx+b对应一个隐状态p, p = L(wx+b),然后根据p和1-p的大小决定因变量的值。如果L是logistic,那么就是logistic回归,如果L是多项式,那么就是多项式回归。
说的简单点,就是logistic回归就是在线性回归外边加一层logistic函数的调用。
logistic回归主要是进行二分类预测,Sigmoid函数就是最常见的Logistic函数,因为sigmoid函数的输出是0-1之前的值,大于0.5概率预测为1,小于0.5预测为0
UCI German Credit 数据集
是德国信用数据集,里边有原数据和数值化后的数据。
German Credit 数据是根据个人的银行贷款信息和申请客户贷款逾期发生情况来预测贷款违约倾向的数据集,数据集包含24个维度的1000条数据,数据集地址
代码实战
这里使用的german.data-numeric是numpy处理好的数值化数据,直接使用load方法读取。
import torch
import torch.nn as nn
import numpy as np
#读取数据
data = np.loadtxt("german.data-numeric")
#数据归一化处理
n, l = data.shape #n, l = data.shape --读取 data 的大小;n 代表行数,l 代表列数
for j in range(l-1):
meanVal = np.mean(data[:,j]) # 求 data 所有行 j 列所有数的平均值
stdVal = np.std(data[:,j]) # 求 data 所有行 j 列所有数的方差
data[:,j] = (data[:,j]-meanVal)/stdVal # 归一化
#打乱数据
np.random.shuffle(data) #shuffle() 方法将序列的所有元素随机排序,通过 random 静态对象调用该方法。
#直接将900条用于训练,100条作为测试,没有验证集
#german.data-numeric的格式为,前24列为24个维度,最后一个为要打的标签(0,1),所以我们将数据和标签一起区分出来
train_data = data[:900, :l-1]
train_lab = data[:900, l-1]-1 #原数据中的label是1和2,减一将其变为0和1
test_data = data[900:,:l-1]
test_lab = data[900:,l-1]-1
#定义模型
class LR(nn.Module):
def __init__(self):
super(LR,self).__init__()
self.fc = nn.Linear(24,2) #24个维度
def forward(self, x):
out = self.fc(x)
out = torch.sigmoid(out)
return out
#测试集上准确率
def test(pred, lab):
t = pred.max(-1)[1] == lab #pred.max(-1) --- 表示取 pred 每一行的最大值; Pred.max(-1)[1] --- 表示取 pred 每一行最大值的索引
return torch.mean(t.float())
#t = pred.max(-1)[1] == lab --- 返回的是一个长度为样本个数的 0,1 向量
#torch.mean(t.float()) --- 准确率的定义,其实就是计算 1 占整个样本的比率
#设置参数
net = LR()
criterion = nn.CrossEntropyLoss() #交叉熵损失
optm = torch.optim.Adam(net.parameters()) #Adam优化
epochs = 1000 #训练次数
#开始训练
for i in range(epochs):
# 指定模型为训练模式,计算梯度
net.train()
x = torch.from_numpy(train_data).float()
y = torch.from_numpy(train_lab).long()
y_hat = net(x)
loss = criterion(y_hat,y)
optm.zero_grad()
loss.backward()
optm.step()
if (i+1)%100 == 0:
net.eval()
test_in = torch.from_numpy(test_data).float()
test_l = torch.from_numpy(test_lab).long()
test_out = net(test_in)
accu = test(test_out,test_l)
print("Epoch:{}, loss:{:.4f}, Accuracy: {:.2f}".format(i+1, loss.item(), accu))
神经网络模块存在两种模式,train模式(net.train())和eval模式(net.eval())。一般的神经网络中,这两种模式是一样的,只有当模型中存在dropout和batchnorm的时候才有区别。
一旦我们用测试集进行结果测试的时候,一定要使用net.eval()把dropout关掉,因为这里我们的目的是测试训练好的网络,而不是在训练网络,没有必要再dropout和再计算BN的方差和均值(BN使用训练的历史值)。