logistic回归
使用logistic回归对结构化数据进行简单的分类。
1. 模型介绍
Logistic Regression 虽然被称为回归,但其实际上是分类模型,并常用于二分类。Logistic Regression 因其简单、可并行化、可解释强深受工业界喜爱。 Logistic 回归的本质是:假设数据服从这个分布,然后使用极大似然估计做参数的估计。Sigmod函数是最常见的logistic函数,因为Sigmod函数的输出的是是对于0~1之间的概率值,当概率大于0.5预测为1,小于0.5预测为0,所以这里会用到它。
Logistic 回归的本质是:假设数据服从这个分布,然后使用极大似然估计做参数的估计。
logistic回归可以用于通过相似度数据来得到图片是否相似,也就是对于多个数据进行计算得到相似与不相似两个结果,由于本人对于机器学习造诣不深,所以不会涉及回归模型的原理讲解。
2.UCI German Credit 数据集
UCI German Credit是UCI的德国信用数据集,里面有原数据和数值化后的数据。
German Credit数据是根据个人的银行贷款信息和申请客户贷款逾期发生情况来预测贷款违约倾向的数据集,数据集包含24个维度的,1000条数据,
在这里我们直接使用处理好的数值化的数据,作为展示。
3.代码实战
同样的,你也可以从这里下载 资源
在这里我会进行分段的讲解,最后给出最后的代码:
我们这里使用的 german.data-numeric是numpy处理好数值化数据,我们直接使用numpy的load方法读取即可
import torch
import torch.nn as nn
import numpy as np
data=np.loadtxt("./resource/german.data-numeric")
print(data)
输出:
[[ 1. 6. 4. ... 0. 1. 1.]
[ 2. 48. 2. ... 0. 1. 2.]
[ 4. 12. 4. ... 1. 0. 1.]
...
[ 4. 12. 2. ... 0. 1. 1.]
[ 1. 45. 2. ... 0. 1. 2.]
[ 2. 45. 4. ... 0. 1. 1.]]
没有问题,接下来我需要的是获得这个数据的shape,以便于我对数据进行操作。来看
h,w=data.shape
print(h,w) #1000 25
读取完数据后,要对其进行归一化处理。
for j in range(w-1):
meanVal=np.mean(data[:,j]) #获取每一列的平均值
stdVal=np.std(data[:,j]) #获取每一列的标准差
data[:,j]=(data[:,j]-meanVal)/stdVal #z标准化
打乱数据,每次运行打乱的情况不同,最后获得的准确率得到过79%与80%。
np.random.shuffle(data)
区分训练集和测试集,由于这里没有验证集,所以我们直接使用测试集的准确度作为评判好坏的标准
区分规则:900条用于训练,100条作为测试
german.data-numeric的格式为,前24列为24个维度,最后一个为要打的标签(0,1),所以我们将数据和标签一起区分出来
train_data=data[:900,:w-1] #列取900,横取24
train_lab=data[:900,w-1]-1
test_data=data[900:,:w-1]
test_lab=data[900:,w-1]-1
下面我们定义模型,模型很简单
class LR(nn.Module):
def __init__(self):
super(LR,self).__init__()
self.fc=nn.Linear(24,2) # 由于24个维度已经固定了,所以这里写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
return torch.mean(t.float())
下面就是对一些设置
net=LR()
criterion=nn.CrossEntropyLoss() # 使用CrossEntropyLoss损失
optm=torch.optim.Adam(net.parameters()) # Adam优化
epochs=1000 # 训练1000次
接下来进行训练
for i in range(epochs):
# 指定模型为训练模式,计算梯度
net.train()
# 输入值都需要转化成torch的Tensor
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 : # 这里我们每100次输出相关的信息
# 指定模型为计算模式
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))
输出:
Epoch:100,Loss:0.6480,Accuracy:0.68
Epoch:200,Loss:0.6180,Accuracy:0.73
Epoch:300,Loss:0.6000,Accuracy:0.76
Epoch:400,Loss:0.5877,Accuracy:0.76
Epoch:500,Loss:0.5785,Accuracy:0.77
Epoch:600,Loss:0.5713,Accuracy:0.77
Epoch:700,Loss:0.5653,Accuracy:0.77
Epoch:800,Loss:0.5603,Accuracy:0.77
Epoch:900,Loss:0.5560,Accuracy:0.77
Epoch:1000,Loss:0.5523,Accuracy:0.79
训练完成,精度达到79%,而我在用pycharm时获得过80%。
import torch
import torch.nn as nn
import numpy as np
data=np.loadtxt("./resource/german.data-numeric")
print(data)
h,w=data.shape
print(h,w)
for j in range(w-1):
meanVal=np.mean(data[:,j])
stdVal=np.std(data[:,j])
data[:,j]=(data[:,j]-meanVal)/stdVal
np.random.shuffle(data)
train_data=data[:900,:w-1]
train_lab=data[:900,w-1]-1
test_data=data[900:,:w-1]
test_lab=data[900:,w-1]-1
# print(train_data[0],"\n", train_data)
# print(train_lab)
class LR(nn.Module):
def __init__(self):
super(LR,self).__init__()
self.fc=nn.Linear(24,2) # 由于24个维度已经固定了,所以这里写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
return torch.mean(t.float())
net=LR()
criterion=nn.CrossEntropyLoss() # 使用CrossEntropyLoss损失
optm=torch.optim.Adam(net.parameters()) # Adam优化
epochs=1000 # 训练1000次
for i in range(epochs):
# 指定模型为训练模式,计算梯度
net.train()
# 输入值都需要转化成torch的Tensor
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 : # 这里我们每100次输出相关的信息
# 指定模型为计算模式
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))