基本知识
1.监督学习分为回归问题与分类问题;
2.回归问题输出连续的变量,而分类问题输出离散的变量;
3.回归,指研究一组随机变量(Y1 ,Y2 ,…,Yi)和另一组(X1,X2,…,Xk)变量之间关系的统计分析方法
二分类算法——Logistic回归
起源
人口数量增长、微生物增长…
Logistic分布
X是连续的随机变量
服从Logistic分布是指其分布函数和密度函数如下:
二分类的Logistic回归
目的是找到一个区分度足够好的决策边界。
基本方法是通过决策函数的符号来判断其属于哪一类。
∑
i
=
1
n
ω
i
x
i
+
b
=
0
\sum_{i=1}^n \omega_i x_i + b = 0
i=1∑nωixi+b=0
而logistic回归通过比较概率值来进行分类。
Y只能为0或1。
简单来说就是计算下面两个概率分布:
在X发生的条件下,Y=0或1发生的概率分布。
Logistic函数是事件发生的函数,不过做了变形。
logistic模型的特点
我们首先引入一个概念:
一个事情发生的几率指的是该事情发生的概率和不发生的概率的比值。
如果一个事件发生的概率为p,那么不发生的概率为1-p;该事件发生的几率为
p
1
−
p
\frac{p}{1-p}
1−pp该事件的对数几率或logit函数是
l
o
g
i
t
(
p
)
=
l
o
g
p
1
−
p
logit(p)=log\frac{p}{1-p}
logit(p)=log1−pp
对于Logistic回归而言,
也就是说,Y=1的几率是输入x的线性函数。
线性函数的值越接近正无穷,概率值越接近1 。
因此,Logistic回归的思路是先拟合决策边界(这个决策边界不局限于线性函数,也可以是多项式函数),再建立这个边界和分类概率的关系,从而得到二分类情况下的概率。
似然函数
似然性,在某一参数下的事件发生的概率。
似然函数,在给定x下,关于参数的取值。
最大似然估计法
摘自百度百科:
代码实现
我们在代码中用到的似然函数如下:
找到合适的参数,使得在该点处与分类匹配的概率最大。
BCELoss:BCE binary crossentropy 二分类交叉熵
需要在前面加上Sigmoid函数。
是Crossentropy的一个特例,只用于二分类问题。
monument的作用:
https://blog.csdn.net/u013989576/article/details/70241121
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
import numpy as np
with open('logistic_dataset.txt','r') as f:
data_list = f.readlines() #返回数组,每一行为一个字符串元素,含换行符号
#通过指定字符,把字符串拆分成多个部分,返回数组
data_list = [i.split('\n')[0] for i in data_list]
data_list = [i.split(',') for i in data_list]
data = [(float(i[0]),float(i[1]),float(i[2])) for i in data_list]
x0 = list(filter(lambda x:x[-1] == 0.0,data))
'''
filter(function, iterable)
返回iterable中所有数据经过function后的数据,是filter数据格式,需要转化才可见。
'''
x1 = list(filter(lambda x:x[-1] == 1.0,data))
plot_x0_0 = [i[0] for i in x0]
plot_x0_1 = [i[1] for i in x0]
plot_x1_0 = [i[0] for i in x1]
plot_x1_1 = [i[1] for i in x1]
plt.plot(plot_x0_0,plot_x0_1,'ro',label='x_0') #画点 横坐标 纵坐标
plt.plot(plot_x1_0,plot_x1_1,'bo',label='x_1')
plt.legend(loc='best') #添加图例
#plt.show()
class LogisticRegression(nn.Module):
def __init__(self):
super(LogisticRegression,self).__init__()
self.lr = nn.Linear(2,1)
self.sm = nn.Sigmoid()
# 1/(1+e^(-x))
def forward(self,x):
x = self.lr(x)
x = self.sm(x)
return x
model = LogisticRegression()
criterion = nn.BCELoss() #二分类损失函数
optimizer = optim.SGD(model.parameters(),lr=1e-3,momentum=0.9)
#处理数据
part_data = torch.Tensor(data[0])
location = torch.Tensor([[part_data[0],part_data[1]]])
classification = torch.Tensor([[part_data[2]]])
for i in range(1,len(data)):
part_data = torch.Tensor(data[i])
location_1 = torch.Tensor([[part_data[0],part_data[1]]])
location = torch.cat((location,location_1),0)
classification_1 = torch.Tensor([[part_data[2]]])
classification = torch.cat((classification,classification_1),0)
for epoch in range(5000):
x = Variable(location,requires_grad=True)
y = Variable(classification)
out = model(x)
loss = criterion(out,y)
print_loss = loss.item()
mask = out.ge(0.5).float() #若out大于0.5,则mask得到1
correct = (mask == y).sum() #将mask与y至对应的数量统计起来,即预测正确数
acc = correct.item()/x.size(0) #正确/总量
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch+1)%1000 == 0:
print('*'*10)
print('epoch{}'.format(epoch+1))
print('loss is {:.4f}'.format(print_loss))
print('acc is {:.4f}'.format(acc))
#绘图
w0,w1 = model.lr.weight[0]
w0 = w0.item()
w1 = w1.item()
b = model.lr.bias.item()
plot_x = np.arange(0,100,0.1)
plot_y = (-w0*plot_x-b)/w1
plt.plot(plot_x,plot_y)
plt.show()