一、logistic回归原理
1.1 从线性回归到logistic回归角度理解模型
logistic回归名字里有回归两个字,但本质上是一个分类问题,对于给定的特征输入X,判断该特征代表的样例是正类还是负类。借鉴以前我们学习线性回归的知识,我们希望建立一个线性模型Wx+b,让模型能告诉我们如果是正类输出1,是负类输出0,但是我们都知道wx+b的结果是负无穷到正无穷上的所有数,所以没办法满足我们的要求。想找到一个函数,使得wx+b输出的结果越大,是正类的概率越大。输出结果越小,是负类的概率越大,而sigmoid函数正好满足这个条件:
sigmoid函数表达式如下:
sigmoid函数图像如下所示:可以看到当x为0的时候,y值为0.5,当x趋近于正无穷的时候,y趋近于1。当x趋近于负无穷的时候,y趋近于0
1. 2 从对数几率的角度理解模型
给定输入变量x,输出变量为y属于{0,1},将y=1的概率计为Π(x)= P(y=1|x),而已知logistic模型为线性模型可以用wx表示,wx的取值范围为负无穷到正无穷。而Π(x)的取值范围为0到1.如何将这两个联系起来,就需要用到logit函数
一个事件发生的概率是p,不发生的概率是1-p,那么该事件的对数几率函数是:
函数图像如下:
1.3 模型参数求解
logistic回归本质上是一个二分类问题,运用极大似然函数来估计参数值。设X为数据的特征,W,b为要求的参数,f(x)为估计为正类的概率,1-f(x)为估计成负类的概率。则logistic转为二分类,可利用极大似然函数求解,参见上面讲解极大似然函数的例子。
实际计算过程中一般取InL的负数,转化为求最小值
注:上面的推导少加了一个负号,极大似然估计要求最大化函数,添加负号之后变成求最小函数,利用梯度下降求解。
还可以从另一个角度来理解这损失函数:
二、logistic回归代码实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def create_data():
iris = load_iris()
df = pd.DataFrame(iris.data,columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
df.insert(0,"ones",1)
data = np.array(df.iloc[:100,[0, 1, 2, -1]])
return data[:,:3],data[:,-1]
X,y = create_data()
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)
def sigmoid(z):
return 1 / (1 + np.exp(-z))
#计算损失函数
def cost(theta,X,y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y.T,np.log(sigmoid(X*theta.T)))
second = np.multiply((1-y).T,np.log(sigmoid(1-sigmoid(X*theta.T))))
return np.sum(first-second)/(len(X))
#计算梯度
def gradient(theta,X,y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
error = sigmoid(np.dot(X,theta.T)) - y.T
grad = np.dot(error.T,X)
return grad
#进行迭代,求解最优值
theta = np.zeros(3)
for i in range(400):
c = cost(theta,X_train,y_train)
g = gradient(theta,X_train,y_train)
theta = theta-g*0.005
print(theta)
#进行预测
def predict(theta,X):
prbability = sigmoid(np.dot(X,theta.T))
return [1 if x>=0.5 else 0 for x in prbability]
theta_min = np.matrix(theta)
predictions = predict(theta_min, X_test)
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y_test)]
accuracy = sum(correct)/len(correct)
print ('accuracy = {}'.format(accuracy))
三、相关知识补充
3.1 最大似然估计函数
对未知参数Θ进行估计的时候,在该参数可能的取值范围内选取,使样本获此观测值X1,X2,...Xn的概率最大值的参数值作为参数Θ的估计,这就是极大似然估计。下面是极大似然函数的定义。
求解极大似然函数的步骤
以二项分布为例,讲解极大似然估计
3.2 sigmoid的导数
下面是sigmoid函数的导数求导公式
下面是sigmoid导数的函数图像,可以看到sigmoid在中间导数值大,进行梯度下降的时候,运行的快。sigmoid在两侧导数小,进行梯度下降的时候,运行的慢。