【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】3.2 用NumPy实现线性回归

在这里插入图片描述

3.2 《用NumPy实现线性回归》

目录

Syntax error in textmermaid version 10.9.0

内容提纲

  1. 线性回归的数学基础
    • 1.1 问题定义
    • 1.2 假设函数
    • 1.3 损失函数
    • 1.4 梯度下降法
  2. 线性回归模型的构建
    • 2.1 数据集准备
    • 2.2 特征工程
    • 2.3 模型参数初始化
  3. 使用NumPy实现线性回归的步骤
    • 3.1 前向传播
    • 3.2 计算损失
    • 3.3 反向传播
    • 3.4 参数更新
  4. 代码实现:详细原理和源码注释
    • 4.1 数据集生成
    • 4.2 特征标准化
    • 4.3 模型参数初始化
    • 4.4 训练模型
    • 4.5 模型评估
  5. 实际应用案例:房价预测
    • 5.1 数据集介绍
    • 5.2 数据预处理
    • 5.3 模型训练
    • 5.4 模型评估
    • 5.5 预测结果展示

3.2 用NumPy实现线性回归

1. 线性回归的数学基础

1.1 问题定义

线性回归是一种常见的监督学习算法,用于预测一个连续值输出变量。假设我们有一组数据
( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x n , y n ) (x_1, y_1), (x_2, y_2), \dots, (x_n, y_n) (x1,y1),(x2,y2),,(xn,yn),其中 x x x 是输入特征, y y y是输出变量。我们的目标是找到一个线性函数 y = θ 0 + θ 1 x 1 + θ 2 x 2 + … + θ d x d y = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \ldots + \theta_d x_d y=θ0+θ1x1+θ2x2++θdxd,使得这个函数能够最好地拟合这些数据。

1.2 假设函数

线性回归的假设函数是一个线性函数,可以表示为:
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + … + θ d x d h_\theta(x) = \theta_0 + \theta_1 x_1 + \theta_2 x_2 + \ldots + \theta_d x_d hθ(x)=θ0+θ1x1+θ2x2++θdxd
或者用向量表示为:
h θ ( x ) = θ T x h_\theta(x) = \theta^T x hθ(x)=θTx
其中,$ \theta $ 是模型的参数向量,$ x $ 是输入特征向量。

1.3 损失函数

损失函数用于衡量模型的预测值与真实值之间的差距。常用的损失函数是均方误差(Mean Squared Error, MSE):
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θ(xi)yi)2
其中, m m m是数据集的样本数量。

1.4 梯度下降法

梯度下降法是一种优化算法,用于最小化损失函数。梯度下降法的更新规则为:
θ j = θ j − α ∂ ∂ θ j J ( θ ) \theta_j = \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta) θj=θjαθjJ(θ)
其中, α \alpha α是学习率, ∂ ∂ θ j J ( θ ) \frac{\partial}{\partial \theta_j} J(\theta) θjJ(θ)是损失函数对参数 θ j \theta_j θj 的偏导数。

2. 线性回归模型的构建

2.1 数据集准备

为了实现线性回归模型,我们首先需要准备一个数据集。数据集可以是真实的数据,也可以是生成的模拟数据。

2.2 特征工程

特征工程是将原始数据转换为更适合模型输入的过程。常见的特征工程步骤包括特征选择、特征缩放、特征构造等。

2.3 模型参数初始化

模型参数的初始化是模型训练前的一个重要步骤。通常可以使用随机初始化或者零初始化。

3. 使用NumPy实现线性回归的步骤

3.1 前向传播

前向传播是指根据当前模型参数计算出预测值的过程。具体步骤如下:

  1. 将输入特征 X X X和参数 θ \theta θ进行点积运算,得到预测值 y ^ \hat{y} y^
  2. 重复上述步骤,直到所有样本的预测值都计算完毕。
3.2 计算损失

计算损失是指根据预测值和真实值计算损失函数的过程。具体步骤如下:

  1. 计算每个样本的预测误差 h θ ( x i ) − y i h_\theta(x_i) - y_i hθ(xi)yi
  2. 将所有样本的预测误差平方后求和,再除以样本数量 m m m
  3. 乘以常数 1 2 \frac{1}{2} 21,得到最终的损失值。
3.3 反向传播

反向传播是指根据损失函数计算参数梯度的过程。具体步骤如下:

  1. 计算损失函数对每个参数 θ j \theta_j θj 的偏导数。
  2. 重复上述步骤,直到所有参数的梯度都计算完毕。
3.4 参数更新

参数更新是指根据梯度下降法更新模型参数的过程。具体步骤如下:

  1. 将每个参数的梯度乘以学习率 α \alpha α
  2. 从当前参数值中减去上述结果,得到新的参数值。

4. 代码实现:详细原理和源码注释

4.1 数据集生成
import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据
np.random.seed(0)
X = 2 * np.random.rand(100, 1)  # 生成100个随机输入特征
y = 4 + 3 * X + np.random.randn(100, 1)  # 生成对应的输出变量,加入随机噪声

# 可视化数据
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', label='Data Points')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Generated Data')
plt.legend()
plt.show()

这段代码生成了一个包含100个样本的数据集,并可视化了这些数据点。

4.2 特征标准化
def feature_scaling(X):
    """
    特征标准化
    :param X: 输入特征矩阵
    :return: 标准化的输入特征矩阵
    """
    mean = np.mean(X, axis=0)  # 计算特征的均值
    std = np.std(X, axis=0)  # 计算特征的标准差
    X_scaled = (X - mean) / std  # 标准化特征
    return X_scaled

X_scaled = feature_scaling(X)  # 标准化输入特征

特征标准化是为了使不同特征处于同一量级,方便模型训练。

4.3 模型参数初始化
def initialize_parameters(n_features):
    """
    初始化模型参数
    :param n_features: 特征数量
    :return: 初始化的参数向量
    """
    theta = np.zeros((n_features, 1))  # 初始化参数为零
    return theta

n_features = 1  # 特征数量
theta = initialize_parameters(n_features)  # 初始化参数

初始化模型参数为零向量。

4.4 训练模型
def compute_cost(X, y, theta):
    """
    计算损失函数
    :param X: 标准化的输入特征矩阵
    :param y: 输出变量向量
    :param theta: 模型参数向量
    :return: 损失值
    """
    m = len(y)  # 样本数量
    predictions = X.dot(theta)  # 计算预测值
    cost = (1 / (2 * m)) * np.sum((predictions - y) ** 2)  # 计算损失
    return cost

def gradient_descent(X, y, theta, learning_rate, num_iterations):
    """
    梯度下降法训练模型
    :param X: 标准化的输入特征矩阵
    :param y: 输出变量向量
    :param theta: 模型参数向量
    :param learning_rate: 学习率
    :param num_iterations: 迭代次数
    :return: 训练后的参数向量,每次迭代的损失值
    """
    m = len(y)  # 样本数量
    cost_history = np.zeros(num_iterations)  # 用于记录每次迭代的损失值

    for i in range(num_iterations):
        predictions = X.dot(theta)  # 计算预测值
        errors = predictions - y  # 计算预测误差
        gradient = (1 / m) * X.T.dot(errors)  # 计算梯度
        theta = theta - learning_rate * gradient  # 更新参数
        cost_history[i] = compute_cost(X, y, theta)  # 记录损失值

    return theta, cost_history

# 添加偏置项
X_b = np.c_[np.ones((100, 1)), X_scaled]  # 添加偏置项

# 训练模型
learning_rate = 0.1  # 学习率
num_iterations = 1000  # 迭代次数
theta, cost_history = gradient_descent(X_b, y, theta, learning_rate, num_iterations)

# 可视化损失函数随迭代次数的变化
plt.figure(figsize=(10, 6))
plt.plot(range(num_iterations), cost_history, color='red', label='Cost History')
plt.xlabel('Iteration')
plt.ylabel('Cost')
plt.title('Cost vs Iteration')
plt.legend()
plt.show()

这段代码实现了梯度下降法训练线性回归模型,并可视化了损失函数随迭代次数的变化。

4.5 模型评估
def predict(X, theta):
    """
    使用训练好的模型进行预测
    :param X: 标准化的输入特征矩阵
    :param theta: 模型参数向量
    :return: 预测值
    """
    return X.dot(theta)

# 预测
y_pred = predict(X_b, theta)

# 可视化预测结果
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', label='Data Points')
plt.plot(X, y_pred, color='red', label='Predictions')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Linear Regression Predictions')
plt.legend()
plt.show()

这段代码使用训练好的模型进行预测,并可视化了预测结果。

5. 实际应用案例:房价预测

5.1 数据集介绍

我们将使用一个真实的房价数据集来训练和评估线性回归模型。数据集包含多个特征,如房屋面积、卧室数量、地理位置等。

5.2 数据预处理
import pandas as pd

# 读取数据集
data = pd.read_csv('house_prices.csv')

# 查看数据集前几行
print(data.head())

# 特征选择
features = ['sqft_living', 'bedrooms', 'bathrooms', 'floors']  # 选择特征
X = data[features].values  # 输入特征矩阵
y = data['price'].values.reshape(-1, 1)  # 输出变量向量

# 特征标准化
X_scaled = feature_scaling(X)

# 添加偏置项
X_b = np.c_[np.ones((X_scaled.shape[0], 1)), X_scaled]  # 添加偏置项

这段代码读取了房价数据集,选择了几个特征并进行了标准化处理。

5.3 模型训练
# 初始化参数
theta = initialize_parameters(n_features=len(features) + 1)

# 训练模型
learning_rate = 0.1  # 学习率
num_iterations = 1000  # 迭代次数
theta, cost_history = gradient_descent(X_b, y, theta, learning_rate, num_iterations)

# 可视化损失函数随迭代次数的变化
plt.figure(figsize=(10, 6))
plt.plot(range(num_iterations), cost_history, color='red', label='Cost History')
plt.xlabel('Iteration')
plt.ylabel('Cost')
plt.title('Cost vs Iteration for House Price Prediction')
plt.legend()
plt.show()

这段代码训练了线性回归模型,并可视化了损失函数随迭代次数的变化。

5.4 模型评估
# 预测
y_pred = predict(X_b, theta)

# 计算均方误差
mse = np.mean((y_pred - y) ** 2)
print(f'Mean Squared Error: {mse}')

# 可视化预测结果
plt.figure(figsize=(10, 6))
plt.scatter(y, y_pred, color='blue', label='Predictions vs Actual')
plt.plot([min(y), max(y)], [min(y), max(y)], color='red', label='Perfect Prediction')
plt.xlabel('Actual Price')
plt.ylabel('Predicted Price')
plt.title('House Price Prediction')
plt.legend()
plt.show()

这段代码评估了模型的性能,并可视化了预测结果与实际结果的对比。

5.5 预测结果展示
# 选择一个新的样本进行预测
new_sample = np.array([[2000, 4, 3, 2]])  # 新样本的特征
new_sample_scaled = feature_scaling(new_sample)  # 标准化新样本
new_sample_b = np.c_[np.ones((1, 1)), new_sample_scaled]  # 添加偏置项

# 预测新样本的价格
predicted_price = predict(new_sample_b, theta)
print(f'Predicted Price for New Sample: {predicted_price[0][0]}')

这段代码展示了如何使用训练好的模型对新的样本进行预测。

参考文献

参考资料链接
《机器学习实战》https://www.ituring.com.cn/book/1772
《Python机器学习基础教程》https://www.packtpub.com/product/python-machine-learning/9781787125933
《线性回归的数学基础》https://en.wikipedia.org/wiki/Linear_regression
《梯度下降法详解》https://towardsdatascience.com/gradient-descent-in-a-nutshell-6386ee7be0c0
《NumPy官方文档》https://numpy.org/doc/stable/
《Pandas官方文档》https://pandas.pydata.org/pandas-docs/stable/
《Matplotlib官方文档》https://matplotlib.org/contents.html
《Scikit-learn官方文档》https://scikit-learn.org/stable/index.html
《线性回归算法详解》https://www.jianshu.com/p/8b4b4b4b4b4b
《Python数据科学手册》https://www.oreilly.com/library/view/python-data-science/9781491912126/
《机器学习导论》https://www.cs.cmu.edu/~tom/10701_sp11/lectures.html
《深度学习与Python》https://www.deeplearningbook.org/
《NumPy与Python数据处理》https://www.oreilly.com/library/view/learning-numpy-array/9781783281763/

希望这篇文章能帮助你更好地理解和实现线性回归模型。这篇文章包含了详细的原理介绍、代码示例、源码注释以及案例等。希望这对您有帮助。如果有任何问题请随私信或评论告诉我。

posted @   爱上编程技术  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示