线性回归要解决的问题是给一堆样本点X(m, n)和每个点对应的函数值Y(m,1)要求找到一个线性函数 y=w1∗x1+w2∗x2+...+wn∗xn+b y = w 1 ∗ x 1 + w 2 ∗ x 2 + . . . + w n ∗ x n + b 使得其对原样本点的拟合度最好。拟合度最好就是每个样本点到这条直线的距离和最小,转化成数学语言就是使得误差函数 J(y^,y)=1/2∗(y^−y)2=1/2∗(wTx+b−y)2 J ( y ^ , y ) = 1 / 2 ∗ ( y ^ − y ) 2 = 1 / 2 ∗ ( w T x + b − y ) 2 最小,选平方函数消除误差的正负情况。
令误差函数对两参数的倒数分别为0,即可得出其表达式。但最后 θ(w,b)=(XTX)−1XTY θ ( w , b ) = ( X T X ) − 1 X T Y 高维矩阵的逆不易算,而且存在矩阵不可逆的情况。实现上往往采用梯度下降法: θ=θ−α∂J(w,b)∂θ θ = θ − α ∂ J ( w , b ) ∂ θ ,下面做个简单的示例。首先统一样本及标签矩阵的格式如下:
样本特征矩阵是 n×m 的,其中 n 是每个样本的特征数,m是样本个数。标签y为 1×m 的行向量。按此格式生成100个样本点:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def generate_data():
x = np.linspace(-2, 2, 100).reshape(100, 1)
y = -3 * x + 7 + (np.random.rand(100, 1) - 0.5)
return x, y
x, y = generate_data()
x = x.T
y = y.T
print(x.shape,)
print(y.shape,)
((1, 100),)
((1, 100),)
拟合函数为 y=−3∗x+7 y = − 3 ∗ x + 7 ,每个样本点加一个噪声。作图如下:
plt.figure(figsize=(12, 8))
plt.scatter(x.T, y.T, c= 'y')
plt.plot(x.T, (-3 * x + 7).T, c='b', linewidth=2)
plt.show()
接下来就用梯度下降法得到使得误差函数最小的 w,b w , b 。参数更新公式推导: J(y^,y)=1/2∗(y^−y)2 J ( y ^ , y ) = 1 / 2 ∗ ( y ^ − y ) 2
def GDparalearning (x, y,m, iterations = 1000):
#初始化学习率a和系数w,b
a = 0.05
w = 1
b = 1
for i in range(iterations):
#计算预测值
z = w * x + b
dz = z - y
#计算误差
loss = dz.dot(dz.T).sum()/2.0
#更新参数
w = w - a * 1.0/m * x.dot(dz.T) #x为向量不能用.mean(),否则变为一个数
b = b - a * dz.mean()
return w, b
测试与作图:
w, b = GDparalearning(x, y,100)
print (w, b)
predict = w.T.dot(x) + b
#计算真实值与预测值的相关系数
print (np.corrcoef(y, predict))
plt.figure(figsize=(12, 8))
plt.scatter(x, y, c= 'y')
plt.plot(x.T, (-3 * x + 7).T, c='b', linewidth=2)
plt.plot(x.T, predict.T, c='r', linewidth=2)
plt.show()
(array([[-3.00567058]]), 6.980861739959656)
[[1. , 0.99666187]
[0.99666187 , 1. ]]
两条线基本吻合。
逻辑回归主要用来处理二分类问题,给样本点x,输出其标签为正或负的概率。
本来分类的是线性函数,但概率的取值范围是[0, 1]故套一层sigmod函数
同样要得到参数w,b就需要定义损失函数,此处不再用平方函数,因为这会使损失函数非凸从而存在很多局部最小值。单个样本的损失函数为: J(w,b)=−(y∗logy^+(1−y)∗log(1−y^)) J ( w , b ) = − ( y ∗ l o g y ^ + ( 1 − y ) ∗ l o g ( 1 − y ^ ) ) 总的代价函数即为每个样本的损失函数的和取平均。
这个损失函数也不是凭空编出来的,其背后的原理在概率论中。将概率函数p(y|x)的分段表达统一起来就是 p(y|x)=y^y∗(1−y^)(1−y) p ( y | x ) = y ^ y ∗ ( 1 − y ^ ) ( 1 − y ) 意义是:给定样本点x的条件下,其标签为y的概率是用sigmod函数计算出来的值。
假定这些样本独立同分布,则所有样本的联合概率就是每个样本概率的乘积。然后对它做最大似然估计,即找到一组参数使得给定样本的观测值最大。
为了去掉连乘对其取对数,算极大似然就是算代价函数最小,故定义总的代价函数时去掉前面的负号,最后对代价函数缩放加因子1/m。
样本采用同线性回归一样的格式:n为特征数,m为样本数
用上面推出的代价函数 J(w,b)=−(y∗logy^+(1−y)∗log(1−y^)) J ( w , b ) = − ( y ∗ l o g y ^ + ( 1 − y ) ∗ l o g ( 1 − y ^ ) ) 分别对两参数求导。首先
z=wTx+b z = w T x + b
y^=σ(wTx+b)=σ(z) y ^ = σ ( w T x + b ) = σ ( z )
σ(z)=11+e−z σ ( z ) = 1 1 + e − z
J(w,b)=−(Y∗logY^+(1−Y)∗log(1−Y^)) J ( w , b ) = − ( Y ∗ l o g Y ^ + ( 1 − Y ) ∗ l o g ( 1 − Y ^ ) )
分别求导:
from numpy import *
import matplotlib.pyplot as plt
import time
def loadData():
train_x = []
train_y = []
fileIn = open('testSet.txt')
for line in fileIn.readlines():
lineArr = line.strip().split()
train_x.append([float(lineArr[0]), float(lineArr[1])])
train_y.append(float(lineArr[2]))
return np.array(train_x).T , np.array(train_y)
x, y = loadData()
print x.shape, y.shape
(2, 100) (100,)
然后是sigmoid函数和梯度下降算法模型
import numpy as np
import matplotlib.pyplot as plt
import time
def sigmoid(x):
return 1.0 / (1 + exp(-x))
def GDlogistic(x, y, m, iterations = 50000):
w = np.ones(2).reshape(2, 1)
b = 1
a = 0.05
for i in range(iterations):
z = sigmoid(w.T.dot(x) + b)
dz = z - y
w = w - a * 1.0/m * x.dot(dz.T)
b = b - a * 1.0/m * np.sum(dz)
return w, b
测试
w, b = GDlogistic(x, y, 100)
print w, b
predict = sigmoid(w.T.dot(x) + b)
print (np.corrcoef(y, predict))
[[ 1.16239039]
[-1.82522712]] 13.4202362998
[[ 1. , 0.93775995]
精度达到93%,可视化
plt.figure(figsize=(12, 8))
#print y.shape
for i in xrange(100):
if int(y[i]) == 0:
plt.plot(x.T[i, 0], x.T[i, 1], 'or')
elif int(y[i]) == 1:
plt.plot(x.T[i, 0], x.T[i, 1], 'ob')
min_x = min(x.T[:, 0])
max_x = max(x.T[:, 0])
y_min_x = float(-b - w[0] * min_x) / w[1]
y_max_x = float(-b - w[0] * max_x) / w[1]
plt.plot([min_x, max_x], [y_min_x, y_max_x], '-g')
plt.xlabel('X1'); plt.ylabel('X2')
plt.show()
以上是分别对线性回归与逻辑回归的数学分析和实现,两者一个用于回归一个用于分类,应属于完全不同的算法,但本质上又存在联系。实际上,逻辑回归是对样本正负概率比值的预测,也就是说它预测的是正负样本的分类面。
p=11+e−wTx p = 1 1 + e − w T x
lnp1−p=wTx l n p 1 − p = w T x
这两个式子可以清晰地看出两者的联系: