Python编写线性回归算法
前言
线性回归(Linear Regression)是机器学习的基础,作为机器学习算法的基石,后人在此基础之上演化了各种更为精确、有效的算法。
1 线性回归的基本原理
线性回归是要用一组特征的线性组合,来拟合目标值。假设函数(hypothesis function)表达如下所示:
x为m×n的特征矩阵,θ为特征参数矩阵,线性回归学习的目标是得到一组拟合的θ向量值。
以下采用比较基础的最小二乘法、梯度下降法求取θ向量值。数据量较小的时候使用最小二乘法
a.最小二乘法
为了求上式的最优解,线性回归需要建立观测结果y与预测结果y’的差别为目标函数J(θ):
令J(θ)等于某个最小值δ,则
对参数θ求导,得:
b. 梯度下降法
定义一个简单的代价函数:
表示第i个数据的因变量(特征),表示第i个数据的自变量(观察结果)。
更新参数θ:
由于θ每次更新都会用到全部数据,因此这种方法叫做(批量)梯度下降法。相比较随机梯度下降法(SGD),这种方法更容易局部最优。另外,在使用梯度下降法时要注意对自变量(特征)进行归一化。例如年龄和身高显然不在同一尺度上,若没有归一化采用同一学习率,效果会很差。
2 代码实现
代码地址:https://github.com/HZNU1/Writing-machine-learning-algorithms-in-python
仅将算法部分展示:
a. 最小二乘法
import numpy as np
class LinearRegression_1:
def __init__(self,x,y):
self.x = np.mat(x)
self.y = np.mat(y)
def regression(self):
#添加系数θ0,并且赋予它的参数为1
theta0 = np.ones((len(data), 1))
self.x = np.hstack((self.x, theta0))
x_T =self.x.T #计算X矩阵的转置矩阵
self.theta = (x_T * self.x).I * x_T * self.y.T #由最小二乘法计算得出的参数向量
def predict(self, vec):
vec =np.mat(vec)
vec0= np.ones((len(vec), 1))
vec = np.hstack((vec, vec0))
estimate = np.matmul(vec, self.theta) #点乘
return estimate
b. 梯度下降法
import numpy as np
class LinearRegression_2:
def __init__(self):
self._theta = None
#自变量x,因变量y,学习率learning_rate(默认0.0001),迭代次数(默认10000次)
def fit_gd(self, x, y, learning_rate=0.0001,n_iters=1e4):
#代价函数
def J(theta, X, y):
try:
return np.sum((y -X.dot(theta)) ** 2) / (2*len(y))
except:
return float('inf')
#代价函数的偏导数
def dJ(theta, X, y):
return X.T.dot(X.dot(theta) -y) / len(y)
#梯度下降
def gradient_descent(X, y, initial_theta,learning_rate, n_iters=1e4, epsilon=1e-8):
theta = initial_theta
cur_iter = 0
#遍历
while cur_iter < n_iters:
gradient = dJ(theta, X, y)
last_theta = theta
theta = theta -learning_rate * gradient
#收敛条件 本次迭代与上一次迭代之差小于epsilon=1e-8
if (abs(J(theta, X, y) -J(last_theta, X, y)) < epsilon):
break
cur_iter += 1
return theta
#添加系数θ0,并且赋予它的参数为1
X = np.hstack([np.ones((len(x), 1)),x])
#初始theta值为全为0的1×n数组
initial_theta = np.zeros(X.shape[1])
self._theta = gradient_descent(X,y, initial_theta, learning_rate, n_iters)
return self
def predict(self, X_predict):
X = np.hstack([np.ones((len(X_predict),1)), X_predict])
return X.dot(self._theta)
参考资料:
1. https://zhuanlan.zhihu.com/p/22474562
2. 周志华《机器学习》
网友评论