线性回归(吴恩达课程作业——单变量城市人口和利润情况)

线性回归三种实现方式

1.梯度下降

梯度下降是一种迭代优化算法,用于寻找函数的最小值。其核心思想是沿着梯度的反方向(即函数值下降最快的方向)逐步更新模型参数,直到收敛到最小值。
线性回归的代价函数定义为
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_{\theta}(x^{(i)}) - y^{(i)})^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2
梯度下降需要选择学习速率 α \alpha α并进行多次迭代

2.sklearn 中的LinearRegression 类

LinearRegression 类默认使用正规方程来最小化代价函数。sklearn 的 LinearRegression 使用 numpy.linalg.lstsq 函数来求解线性最小二乘问题,这本质上是通过正规方程来计算最优解。

3.正规方程

正规方程是通过解析方法直接求解代价函数的最小值,即通过求导找到使代价函数最小的参数值。对于线性回归问题,正规方程的解可以通过矩阵运算直接得到。

正规方程的求解
θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ=(XTX)1XTy

正规方程公式用于直接求解线性回归模型的参数,而无需进行迭代优化。


一、ML-Exercise1_ex1data1_(1)BGD.py代码实现(自定义函数)

(1) 代价函数 computeCost(X, y, theta)

数学公式
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^m \left( h_\theta(x^{(i)}) - y^{(i)} \right)^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2
代码实现

def computeCost(X, y, theta):
    inner = np.power(((X * theta.T) - y), 2)
    return np.sum(inner) / (2 * len(X))
(2)批量梯度下降 gradientDescent(X, y, theta, alpha, iters)

数学公式
θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( h_\theta(x^{(i)}) - y^{(i)} \right) x_j^{(i)} θj:=θjαm1i=1m(hθ(x(i))y(i))xj(i)

代码实现

for j in range(parameters):
    term = np.multiply(error, X[:,j])  # (hθ(x) - y) * x_j
    temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))

代码实现

1. 导入库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

导入了三个常用的库:

  • numpy:用于数值计算。
  • pandas:用于数据处理。
  • matplotlib.pyplot:用于绘图。

2 定义代价函数

def computeCost(X, y, theta):
    inner = np.power(((X * theta.T) - y), 2)
    return np.sum(inner) / (2 * len(X))

代价函数用于衡量模型预测值和实际值之间的差异。公式如下:

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

  • X X X:特征矩阵。
  • y y y:目标变量向量。
  • θ \theta θ:模型参数。
  • m m m:样本数量。

3. 定义批量梯度下降函数

def gradientDescent(X, y, theta, alpha, iters):
    temp = np.matrix(np.zeros(theta.shape))  # 初始化临时参数矩阵
    parameters = int(theta.ravel().shape[1]) # 获取参数数量
    cost = np.zeros(iters) # 初始化成本存储数组
    
    for i in range(iters):
        error = (X * theta.T) - y     # 计算误差
        
        for j in range(parameters):
            term = np.multiply(error, X[:,j]) # 计算梯度项
            temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term)) # 更新参数
            
        theta = temp   # 更新参数
        cost[i] = computeCost(X, y, theta)  # 计算并存储当前成本
        
    return theta, cost

梯度下降算法用于最小化代价函数。其更新规则如下:

θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j - \alpha \frac{1}{m} \sum_{i=1}^{m} (h_{\theta}(x^{(i)}) - y^{(i)}) x_j^{(i)} θj:=θjαm1i=1m(hθ(x(i))y(i))xj(i)

  • α \alpha α:学习速率。
  • m m m:样本数量。
  • x j ( i ) x_j^{(i)} xj(i):第 i i i 个样本的第 j j j 个特征。

4. 数据准备

path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])

读取数据文件并存储为 pandasDataFrame 对象。

5. 数据可视化

data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
plt.show()

绘制散点图,展示人口与利润之间的关系。
在这里插入图片描述

6. 添加一列 1 的特征

data.insert(0, 'Ones', 1)

为了方便线性回归计算,在数据框的第一列插入全为 1 的列,用于线性回归中的截距项。
在这里插入图片描述

7. 初始化变量

cols = data.shape[1]
X = data.iloc[:,0:cols-1] # 特征矩阵
y = data.iloc[:,cols-1:cols] # 目标变量向量

初始化特征矩阵 X X X 和目标变量向量 y y y

8. 转换为 NumPy 矩阵

X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0]))

pandasDataFrame 对象转换为 NumPy 矩阵,初始化参数 θ \theta θ

9. 检查维度

print(X.shape, theta.shape, y.shape)
# 输出:(97, 2) (1, 2) (97, 1)

输出各矩阵的形状,确保维度正确。

10. 计算初始代价函数值

computeCost(X, y, theta)

计算初始参数 θ \theta θ 下的代价函数值。

11. 设置超参数

alpha = 0.01
iters = 10000

设置学习速率 α \alpha α 和迭代次数 i t e r s iters iters

12. 运行梯度下降算法

bestTheta, cost = gradientDescent(X, y, theta, alpha, iters)

运行梯度下降算法,找到最佳参数 θ \theta θ 和每次迭代的成本值。

13. 输出最佳参数

print('梯度下降算法的预测 theta = ', bestTheta)

打印最佳参数 θ \theta θ

14. 计算最终的代价函数值

computeCost(X, y, bestTheta)

计算最终最佳参数 θ \theta θ 下的代价函数值。

15. 绘制线性回归模型

x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = bestTheta[0, 0] + (bestTheta[0, 1] * x)

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()

绘制回归直线和原始数据的散点图。
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1ea2030f7788412a883a2a303917e8b8.png#pic_center

16. 绘制代价函数随迭代次数的变化

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

在这里插入图片描述

绘制代价函数值随迭代次数的变化曲线。
在这里插入图片描述

17. 预测

predict1 = bestTheta[0, 0] + (bestTheta[0, 1] * 3.5)
predict2 = bestTheta[0, 0] + (bestTheta[0, 1] * 7)
print(predict1, predict2)

对人口分别为 3.5 和 7 的地区进行利润预测。


二、ML-Exercise1_ex1data1_(2)sklearn .py代码实现(sklearn 线性回归)

使用 sklearn 库中的线性回归模型,对单变量线性回归问题进行建模和预测。
通过使用 sklearn,可以更简洁地实现线性回归,而无需从头开始实现梯度下降算法。

代码实现

1. 导入库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

导入必要的库:numpy(数值计算)、pandas(数据处理)和 matplotlib.pyplot(绘图)。

2. 数据准备

path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])

读取数据文件并存储为 pandas 的 DataFrame 对象。header=None 表示文件没有标题行,names 参数用于指定列名。

3. 数据可视化

data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
plt.show()

绘制散点图,展示人口与利润之间的关系。
在这里插入图片描述

4. 变量初始化

cols = data.shape[1]
X = data.iloc[:,0:cols-1] # 特征矩阵
y = data.iloc[:,cols-1:cols] # 目标变量向量

初始化特征矩阵 X 和目标变量向量 y

5. 数据类型转换

X = np.matrix(X.values)
y = np.matrix(y.values)

将 pandas 的 DataFrame 对象转换为 NumPy 矩阵。

X_array = np.asarray(X)
y_array = np.asarray(y)

将 NumPy 矩阵转换为 NumPy 数组,以满足 scikit-learn 的输入要求

6. 模型训练

from sklearn import linear_model

model = linear_model.LinearRegression()
model.fit(X_array, y_array)

导入 sklearn 的线性回归模块,创建线性回归模型并进行训练。

7. 模型评估

print('scikit-learn model的预测')
print('截距项:', model.intercept_)
print('系数:', model.coef_)

输出模型的截距项和系数。

8. 模型预测表现

x = np.array(X_array[:,0])
f = model.predict(X_array).flatten()

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()

生成预测值并绘制回归直线和原始数据的散点图。
在这里插入图片描述

三、ML-Exercise1_ex1data1_(3)Regulation.py(正规方程)

原理

正规方程通过求解下面的方程来找到使得代价函数最小的参数:
θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ=(XTX)1XTy
其中:

  • ( X ) 是特征矩阵。
  • ( y ) 是目标变量向量。
  • ( θ \theta θ)是模型参数向量。

代码实现

# 正规方程
def normalEqn(X, y):
    theta = np.linalg.inv(X.T @ X) @ X.T @ y  # X.T @ X 等价于 X.T.dot(X)
    return theta

final_theta2 = normalEqn(X, y)
print('正规方程方法:final_theta2 =', final_theta2)

正规方程函数:定义 normalEqn 函数,计算最佳参数 theta
计算并输出结果:调用 normalEqn 函数,计算并打印最佳参数 theta

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值