您现在的位置是:首页 >其他 >线性回归梯度下降法python实现网站首页其他

线性回归梯度下降法python实现

coderzjy 2025-04-18 00:01:02
简介线性回归梯度下降法python实现


线性回归的公式
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + ⋯ + θ n x n h_ heta(x) = heta_0 + heta_1 x_1 + heta_2 x_2 + dots + heta_n x_n hθ(x)=θ0+θ1x1+θ2x2++θnxn
其中, h θ ( x ) h_ heta(x) hθ(x) 是预测值, θ heta θ 是模型参数, x 1 , x 2 , … , x n x_1, x_2, dots, x_n x1,x2,,xn 是输入特征。

梯度下降的更新公式
θ j = θ j − α ⋅ 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) heta_j = heta_j - alpha cdot frac{1}{m} sum_{i=1}^m left(h_ heta(x^{(i)}) - y^{(i)} ight) x_j^{(i)} θj=θjαm1i=1m(hθ(x(i))y(i))xj(i)
其中, θ j heta_j θj 是第 j j j 个参数, α alpha α 是学习率, m m m 是样本的数量, h θ ( x ( i ) ) h_ heta(x^{(i)}) hθ(x(i)) 是预测值, y ( i ) y^{(i)} y(i) 是实际值, x j ( i ) x_j^{(i)} xj(i) 是样本的第 j j j 个特征。
线性回归的损失函数(均方误差)

J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J( heta) = frac{1}{2m} sum_{i=1}^{m} left( h_ heta(x^{(i)}) - y^{(i)} ight)^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2

其中:

  • J ( θ ) J( heta) J(θ) 是损失函数(成本函数),
  • m m m 是样本的数量,
  • h θ ( x ( i ) ) h_ heta(x^{(i)}) hθ(x(i)) 是模型对第 i i i 个样本的预测值,
  • y ( i ) y^{(i)} y(i) 是第 i i i 个样本的实际值。

通常,在梯度下降中,我们通过最小化损失函数来优化模型参数 θ heta θ

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
def computeCost(X,y,theta):
    m = X.shape[0]
    part = np.power(((X@theta.T)-y),2)
    return np.sum(part)/(m*2)
def gradientDescent(X,y,theta,alpha,iterations):
    #副本
    temp = theta
    #样本数量
    m = X.shape[0]
    #特征数
    params = theta.shape[1]
    #记录每一次的成本变化
    costs = np.zeros(iterations)
    #迭代iterations次
    for i in range(iterations):
        error = X@theta.T-y
        for j in range(params):
            temp[0,j] = temp[0,j] - (alpha/m)*np.sum(np.multiply(error,X[:,j:j+1]))
        theta = temp
        costs[i] = computeCost(X,y,theta)
    return theta, costs
# 读取数据,dataframe
data = pd.read_csv('ex1data1.txt', header=None,names = ["population","profits"])
#插入一行1,作为线性回归函数的常数项
data.insert(0,"Ones",1)
print(data.head())
cols = data.shape[1]
#切片第二项也要用:,保持是dataframe
X = data.iloc[:,0:cols-1]
y = data.iloc[:,cols-1:cols]
#theta都初始化为0,np.array默认是行向量
theta = np.zeros((1,cols-1))
#将dataframe转化为np.array
X = X.to_numpy()
y = y.to_numpy()
print(X.shape)
print(y.shape)
print(theta.shape)
alpha = 0.01
iterations = 1000
theta, costs =gradientDescent(X,y,theta,alpha,iterations)
print(costs[iterations-1])
x = np.linspace(data.population.min(), data.population.max(),100)
f = theta[0,0] + theta[0,1] * x
fig = plt.figure()
#fig 为整个画图区域,ax为子图的集合
#当nrows=1或ncols=1时为一维数组,此时下标索引只有一个维度,否则是两个维度
fig,ax = plt.subplots(figsize=(12,8),nrows=1,ncols=2)
ax[0].plot(x, f, 'r', label='Prediction')
ax[0].set_title('Predicted Profit vs. Population Size')
ax[0].set_xlabel('population')
ax[0].set_ylabel('profit')
ax[0].scatter(data.population, data.profits, label='Traning Data')
ax[0].legend()
#np.arange(iterations) 的意思是 生成从 0 到 iterations-1 的整数数组。
#np.arange(start, stop, step, dtype) 用于生成等间隔的数组
ax[1].plot(np.arange(iterations),costs,label='Cost Function')
ax[1].set_title('Error vs. Training Epoch')
ax[1].set_xlabel('iterations')
ax[1].set_ylabel('cost')
ax[1].legend()
plt.show()

在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。