逻辑回归
逻辑回归是一种分类算法
统计学上的定义和计算公式
逻辑回归分析定义:逻辑回归分析是对定性变量的回归分析。
在前面学到的回归模型中,我们处理的因变量都是数值型区间变量(负无穷到正无穷),建立的模型描述的是因变量的期望与自变量之间的线性关系。
线性回归模型:
然而,在许多实际问题中,我们需要研究的响应变量不是区间变量而是顺序变量或名义变量这样的属性变量。
因为Y只能取0或1,而 的取值是连续的。显然不能用
来预测因变量 Y 。
我们注意到,对于0-1型变量,E(Y)=P(Y=1)=p
因而,我们似乎可以用 来预测Y=1的概率,
即:
Y=1的概率与自变量之间的关系不是线性的,概率与自变量之间的关系图形往往是一个S型曲线。概率的取值应该在0~1之间
我们可以通过对P进行一种变换(logit变换)
使得logit(p)与自变量之间存在线性相关的关系。
同时,经过变换得到的模型也解决了概率的预测值可能是[0,1]之外的数的缺陷。上式建立的模型,我们称为logistic模型(逻辑回归模型)。
最终,我们可能关心的是根据自变量的值来对Y的取值0或1进行预测。而我们的逻辑回归模型得到的只是关于P{Y=1|x}的预测概率。但是,我们可以根据模型给出的Y=1的概率(可能性)的大小来判断预测Y的取值。一般,以0.5为界限,预测p大于0.5时,我们判断此时Y更可能为1,否则认为Y=0
对于逻辑模型:
模型系数的估计不能适用最小二乘估计(OLS)(服从高斯分布)。这里,我可以运用最大似然估计(MLE)的方法。OLS通过使得样本观测数据的残差平方和最小来选择参数,而MLE通过最大化对数似然值来估计参数
设y是0-1型变量, 是与y相关的自变量,n组观测数据为
于是y1,y2,…,yn的似然函数(在已知某些观测所得到的结果时,对有关事物的性质的参数进行估计)为:
对数似然函数为:
最大似然估计就是选取的估计值
使得对数似然函数
最大化
对数似然函数的随机梯度为:
Logisti回归参数的求解过程为(类似梯度下降方法,往正梯度方向迭代)
批量:
随机:
#y = theta0+theta1*x1+theta2x2
import numpy as np
from sklearn.model_selection import train_test_split
def sigmoid(x):
return 1/(1+np.exp(-x))
def weights(x_train,y_train):
m,n = x_train.shape
#初始化参数
theta = np.random.rand(n)
# 学习率
alpha = 0.001
# 迭代次数
cnt = 0
max_iter=500000
# 误差
# error0=error1 = 0
# 指定一个阈值 用于检查两次误差的差 以便停止迭代
threshold = 0.01
while cnt<max_iter:
cnt += 1
diff = np.full(n,0)
for i in range(m):
diff =(y_train[i]-sigmoid(theta.T@x_train[i]))*x_train[i]
theta = theta + alpha * diff
if (abs(diff) < threshold).all():
break
return theta
def predict(x_test,weights):
if sigmoid(weights.T@x_test)>0.5:
return 1
else:
return 0
if __name__ =="__main__":
x_train = np.array([[1, 2.697, 6.254],
[1, 1.872, 2.014 ],
[1, 2.312, 0.812],
[1, 1.983, 4.990],
[1, 0.932, 3.920],
[1, 1.321, 5.583],
[1, 2.215,1.560],
[1,1.659,2.932],
[1,0.865,7.362],
[1,1.685,4.763],
[1,1.786,2.523]])
# y[i] 样本点对应的输出
y_train = np.array([1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1])
dataset = np.loadtxt('data.txt')
x_train = dataset[:,0:-1]
y_train = dataset[:, -1]
x0 = np.full(len(y_train),1)
x_train = np.vstack([x0,x_train.T]).T
x_train,x_test,y_train,y_test = train_test_split(x_train,y_train,test_size=0.3)
weights = weights(x_train,y_train)
y_pred=[]
for i in range(len(y_test)):
y_pred.append(predict(x_test[i],weights))
print(y_test==y_pred)
sklearn调用:
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import numpy as np
dataset = np.loadtxt("data.txt")
x_train,x_test,y_train,y_test = train_test_split(dataset[:,0:-1],dataset[:,-1],test_size=0.3)
model = LogisticRegression(penalty="l2")
model.fit(x_train,y_train)
print(y_test==model.predict(x_test))