人工智能机器学习:Python使用20行代码实现通用的线性回归算法,搞定一切线性回归问题(numpy、梯度下降、矩阵和向量)

1、核心算法代码

说明:算法是使用的梯度下降算法,成本函数是使用的最小二乘法:求残差的平方和的极小值

import numpy as np

# 定义假设函数:X是一个矩阵  W是一个列向量
def hyFunction(X, W):
    return X.dot(W)  # 一次计算所有的样本结果
    pass

# 梯度函数:X是样本矩阵,W是系数,y是实际结果
def gradientFunction(X, W, y):
    return (X.dot(W) - y).dot(X)/X.shape[0] # 一次计算所有的W的梯度值
    pass

# 成本函数:X是矩阵,W是向量,y也是向量
def costFunction(X, W, y):
    return 0.5*np.sum((X.dot(W) - y)**2)/X.shape[0] # 基于最小二乘法构造的成本函数:残差的平方和
    pass

# 定义梯度下降算法:X是样本,w是初始系数,costFunc成本函数,gFunc梯度函数,lamb步进系数,tolance收敛条件,times最大计算次数
def gradientDescent(X, w, y, costFunc, gFunc, lamb = 0.001 , tolance = 1.0e-12, times = 2000000):
    t = 0
    # 上一次结算结果
    result = costFunc(X, w, y)
    # 上一次的梯度
    g = gFunc(X, w, y)
    # 根据梯度和步进系数计算的新的点
    newW = w - lamb*g
    # 代入判别函数计算新的结果值
    newResult = costFunc(X, newW, y)

    # 如果两次的结算结果的差值没有达到收敛条件,继续迭代
    while np.abs(result - newResult) > tolance:
        # 把点移动到新的点
        w = newW
        result = newResult
        g = gFunc(X, w, y)
        newW = w - lamb * g
        newResult = costFunc(X, newW, y)
        t += 1
        # 避免无法收敛的情况
        if t > times:
            break
            pass
        pass
    return w
    pass

数据验证测试:

# 构造测试数据:验证算的有效性

'''
'''
'''

# f(x1, x2) = w0 + w1*x1 + w2*x2  # w1 = 2  w2 = 1  w0=3

# 样本:
'''
X = np.array([[3, 0],[4, 1], [5,2], [7,3]])
y = np.array([9, 12,15, 20])
row = X.shape[0]
one = np.ones(row)
one = one[:,np.newaxis]
X = np.hstack((X, one))

w = gradientDescent(X, np.array([2, 1, 4]), y, costFunction, gradientFunction)
print(w)


# 扩围降阶:对高阶函数拟合,下列x和y是使用函数:y=0.5*x*x*x+1.2*x*x-2.3*x+10 大致计算出来的
x = np.array([-3, -2.3, -1.6, -1, -0.3, 0.3, 1, 1.6, 2.3, 3])
y = np.array([14.2, 15.5, 14.8, 13., 10.8, 9.4, 9.4, 11.8, 17.5, 27.4])

def make_x_ext(X):
    x_ext = np.c_[X[:,np.newaxis], np.ones(len(X))]         # 追加全1列
    x_ext = np.insert(x_ext, 0, np.power(X, 2), axis=1)     # 插入x*x数据列
    x_ext = np.insert(x_ext, 0, np.power(X, 3), axis=1)     # 插入x*x*x数据列
    return x_ext

w_init = np.array([2.5, 3.0, 1.2, 0.7]) # 猜测这就是最优的系数
x_ext = make_x_ext(x)
w = gradientDescent(x_ext, w_init, y, costFunction, gradientFunction)
print(w)

低阶和高阶拟合效果:

第一组数据拟合的系数,符合:

[1.99858201 1.00181951 3.00403465]

第二组数据拟合的系数,符合:

[ 0.49012808  1.20100303 -2.19801389 10.07079948]

 

数学方法的推导过程:

f(W,X) = [[w11, w12]  dot [[x11,x12,x13],
          [w12, W22]]     [x21,x22,x23],
          
          
cost function : 成本函数/目标函数
Σ(i(1,n))(h(x(i)) - y(i))^2 

最小二乘法是:线性回归问题的计算方法

有监督学习模型:
计算值 
实际值

残差:计算值 - 实际值

 

假设函数:自定义的方程式
h(x) = w0+ w1*x

成本函数是w0和w1系数的函数:
f(w0 , w1) =Σ(i(1,n))(h(x(i)) - y(i))^2 
           =Σ(i(1,n))(w0+w1*x(i) - y(i))^2
           = (w0 + w1*x1 - y1)^2 + (w0 + w1*x2 - y2)^2 + ... + (w0 + w1*xn - yn)^2
           
求极值f(w0 , w1),导数值,梯度下降:
f'(w0) = 2*(w0 + w1*x1 - y1) + 2*(w0 + w1*x2 - y2) + ... + 2*(w0 + w1*xn - yn) = 0
f'(w1) = 2*x1*(w0 + w1*x1 - y1) + 2*x2*(w0 + w1*x2 - y2) + ... + 2*xn*(w0 + w1*xn - yn) = 0

2*(w0 + w1*x1 - y1) + 2*(w0 + w1*x2 - y2) + ... + 2*(w0 + w1*xn - yn) = 0

n*w0 + (w1*x1 + w1*x2 + ... w1*xn) - (y1+y2+...+yn) = 0
n*w0 = (y1+y2+...+yn) - w1*(x1+x2+...+xn)
w0 = ((y1+y2+...+yn) - w1*(x1+x2+...+xn))/n
w0 = mean(y) - w1*mean(x)

2*x1*(w0 + w1*x1 - y1) + 2*x2*(w0 + w1*x2 - y2) + ... + 2*xn*(w0 + w1*xn - yn) = 0

w0*(x1+x2+...xn) + w1 * (x1^2+x2^2+...+xn^2) - (x1*y1 + x2*y2+ ... + xn*yn) = 0

残熵:
熵增 熵减

# pizza
x1:大小   3  4  5  7
x2: 距离   0  1  2  3 
.
.
.
xm

h(x1, x2) = w1*x1 + w2*x2 + w0 # w1 = 2  w2 = 1  w0=3

样本:
X = [[3, 0],[4, 1], [5,2], [7,3]]  

y = [9, 12,15, 20]

残差的平方和:
cost = Σ (h(x(i)1, x(i)2) - y(i))^2

 

h(x1, x2..., xm) = w0 + w1*x1 + w2*x2 + ... + wm*xm

扩展到m个维度:
cost = Σ (h(xi1,xi2...,xim) - y(i))^2


高阶:
f(x1, x2) = x1^2 + x2 + 2x2^2 + x1 + w0

扩围降阶:
x3 = x1^2
x4 = x2^2
f(x1, x2) = x1^2 + x2 + 2x2^2 + x1 + 10 
f(x1, x2) = x3 + x2 + 2x4 + x1 + 10

X = [[2,3],[4,6],[7,8]] 
y =  [10,20,40]

XE = [[2,3, 4, 9, 1],[4,6, 16, 36, 1],[7,8, 49,64, 1]] 

n个维度的线性回归问题,梯度下降算法的一般解法:
假设函数:
f(x1,x2,...,xn) = w0 + w1*x1 + ... wn*xn

X = [[x11,x12,...,x1n]
    [x21,x22,...,x2n]
    .
    .
    .
    [xm1,xm2,...,xmn]
]

y = [y1,y2,...,ym]

 

2、将线性回归函数扩展到任意个维度,构造的成本函数(基于最小二乘法,就是残差的平法和):


F(w0,w1,...,wn) = Σ(1,m)(f(x(i)1,x(i)2,...,x(i)n) - y(i))^2

F(w0,w1,...,wn) = Σ(1,m)(w0 + w1*x(i)1 + ... wn*x(i)n - y(i))^2

求解成本函数的极小值(梯度下降算法):

F'(w1) = 2 * Σ(1,m)((w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*xi1)
F'(w2) = 2 * Σ(1,m)((w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*xi2)
.
.
.
F'(wn) = 2 * Σ(1,m)((w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*xin)

F'(w0) = 2 * Σ(1,m)(w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*1


X.T.dot(X.dot(W)) #

X.dot(W).T.dot(X)

展开式:

F'(w1) = 2 * Σ(1,m)((w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*xi1)
       = 2* (( (w0 + w1*x11 + ... wn*x1n - y1)*x11 + (w0 + w1*x21 + ... +wn*x2n - y2) * x21+... +(w0 + w1*xm1 + ... +wn*xmn - ym) * xm1 ))
       = 2* X.dot(w).T.dot(X[0])
   
F'(w2) = 2 * Σ(1,m)((w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*xi2)
       = 2* X.dot(w).T.dot(X[1])
.
.
.
F'(wn) = 2 * Σ(1,m)((w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*xin)
        = 2* X.dot(w).T.dot(X[n-1])

F'(w0) = 2 * Σ(1,m)(w0 + w1*x(i)1 + ... wn*x(i)n - y(i))*1
       = 2* X.dot(w).T.dot(X[n])
       
F'(w) = 2* (X.dot(w) - y.T).T.dot(X)       
       

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
线性回归机器学习常用的一种模型,可以用于预测一个连续值。在Python,可以使用NumPy库来实现线性回归。 首先,我们需要准备数据集。假设我们有以下的数据集,其$X$代表输入特征,$Y$代表输出结果: ``` X = np.array([[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]) Y = np.array([2, 4, 6, 8, 10]) ``` 接下来,我们需要定义一个损失函数来衡量模型的预测值与真实值之间的差距。这里我们选择均方误差(MSE)作为损失函数: $$ MSE = \frac{1}{2n}\sum_{i=1}^{n}(y_i-\hat{y}_i)^2 $$ 其,$n$是样本数量,$y_i$是第$i$个样本的真实值,$\hat{y}_i$是第$i$个样本的预测值。 定义完损失函数后,我们可以使用梯度下降算法来最小化损失函数,从而得到最优的模型参数。具体地,我们需要迭代更新参数$\theta$,使得损失函数不断降低: $$ \theta_j = \theta_j - \alpha\frac{\partial MSE}{\partial \theta_j} $$ 其,$\alpha$是学习率,$\frac{\partial MSE}{\partial \theta_j}$是损失函数对参数$\theta_j$的偏导数。 根据线性回归的公式,我们可以将模型的预测值表示为: $$ \hat{y} = X\theta $$ 其,$X$是输入特征矩阵,$\theta$是模型参数矩阵,$\hat{y}$是模型的预测值矩阵。 根据梯度下降算法的公式,我们可以计算损失函数对参数$\theta$的偏导数: $$ \frac{\partial MSE}{\partial \theta} = \frac{1}{n}(X^T(X\theta - y)) $$ 将上述公式代入梯度下降算法的公式,得到参数更新的公式: $$ \theta = \theta - \alpha\frac{1}{n}(X^T(X\theta - y)) $$ 最后,我们可以使用以下代码实现线性回归: ``` import numpy as np class LinearRegression: def __init__(self, lr=0.01, n_iters=1000): self.lr = lr self.n_iters = n_iters self.theta = None def fit(self, X, y): n_samples, n_features = X.shape self.theta = np.zeros(n_features) for i in range(self.n_iters): y_pred = X.dot(self.theta) mse = np.mean((y - y_pred)**2) grad = (1/n_samples)*X.T.dot(y_pred - y) self.theta -= self.lr*grad if i % 100 == 0: print(f'Iteration {i}, MSE: {mse:.4f}') def predict(self, X): return X.dot(self.theta) ``` 在上述代码,我们定义了一个名为`LinearRegression`的类,它包含两个方法:`fit`和`predict`。 `fit`方法用于拟合模型,它接受输入特征矩阵$X$和输出结果向量$y$作为参数,使用梯度下降算法来最小化损失函数,从而得到最优的模型参数$\theta$。 `predict`方法用于预测新的输入样本,它接受输入特征矩阵$X$作为参数,根据模型参数$\theta$来预测输出结果。 我们可以使用以下代码来测试上述实现: ``` X = np.array([[1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]) Y = np.array([2, 4, 6, 8, 10]) regressor = LinearRegression(lr=0.01, n_iters=1000) regressor.fit(X, Y) y_pred = regressor.predict(X) print(y_pred) ``` 运上述代码可以得到以下输出结果: ``` Iteration 0, MSE: 28.0000 Iteration 100, MSE: 0.0000 Iteration 200, MSE: 0.0000 Iteration 300, MSE: 0.0000 Iteration 400, MSE: 0.0000 Iteration 500, MSE: 0.0000 Iteration 600, MSE: 0.0000 Iteration 700, MSE: 0.0000 Iteration 800, MSE: 0.0000 Iteration 900, MSE: 0.0000 [2. 4. 6. 8. 10.] ``` 从输出结果可以看出,我们的模型成功地预测了输入样本的输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值