【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】3.2 用NumPy实现线性回归
3.2 《用NumPy实现线性回归》
目录
内容提纲
- 线性回归的数学基础
- 1.1 问题定义
- 1.2 假设函数
- 1.3 损失函数
- 1.4 梯度下降法
- 线性回归模型的构建
- 2.1 数据集准备
- 2.2 特征工程
- 2.3 模型参数初始化
- 使用NumPy实现线性回归的步骤
- 3.1 前向传播
- 3.2 计算损失
- 3.3 反向传播
- 3.4 参数更新
- 代码实现:详细原理和源码注释
- 4.1 数据集生成
- 4.2 特征标准化
- 4.3 模型参数初始化
- 4.4 训练模型
- 4.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(θ)=2m1∑i=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−α∂θj∂J(θ)
其中,
α
\alpha
α是学习率,
∂
∂
θ
j
J
(
θ
)
\frac{\partial}{\partial \theta_j} J(\theta)
∂θj∂J(θ)是损失函数对参数
θ
j
\theta_j
θj 的偏导数。
2. 线性回归模型的构建
2.1 数据集准备
为了实现线性回归模型,我们首先需要准备一个数据集。数据集可以是真实的数据,也可以是生成的模拟数据。
2.2 特征工程
特征工程是将原始数据转换为更适合模型输入的过程。常见的特征工程步骤包括特征选择、特征缩放、特征构造等。
2.3 模型参数初始化
模型参数的初始化是模型训练前的一个重要步骤。通常可以使用随机初始化或者零初始化。
3. 使用NumPy实现线性回归的步骤
3.1 前向传播
前向传播是指根据当前模型参数计算出预测值的过程。具体步骤如下:
- 将输入特征 X X X和参数 θ \theta θ进行点积运算,得到预测值 y ^ \hat{y} y^。
- 重复上述步骤,直到所有样本的预测值都计算完毕。
3.2 计算损失
计算损失是指根据预测值和真实值计算损失函数的过程。具体步骤如下:
- 计算每个样本的预测误差 h θ ( x i ) − y i h_\theta(x_i) - y_i hθ(xi)−yi。
- 将所有样本的预测误差平方后求和,再除以样本数量 m m m。
- 乘以常数 1 2 \frac{1}{2} 21,得到最终的损失值。
3.3 反向传播
反向传播是指根据损失函数计算参数梯度的过程。具体步骤如下:
- 计算损失函数对每个参数 θ j \theta_j θj 的偏导数。
- 重复上述步骤,直到所有参数的梯度都计算完毕。
3.4 参数更新
参数更新是指根据梯度下降法更新模型参数的过程。具体步骤如下:
- 将每个参数的梯度乘以学习率 α \alpha α。
- 从当前参数值中减去上述结果,得到新的参数值。
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/ |
希望这篇文章能帮助你更好地理解和实现线性回归模型。这篇文章包含了详细的原理介绍、代码示例、源码注释以及案例等。希望这对您有帮助。如果有任何问题请随私信或评论告诉我。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)