前言
文章概述《深度学习详解》- 1.1
书中介绍了机器学习的基本概念及其应用,包括回归、分类和结构化学习。通过对视频点击次数预测案例的学习,阐述了机器学习的三个步骤:构建模型、定义损失函数以及使用梯度下降法寻找最优参数。作者详细解释了如何通过未知参数来预测特定变量的值,并通过计算损失函数来评估模型的准确性。此外,讨论了梯度下降算法的工作原理及潜在问题,如局部最小值的存在。最后,文中展示了如何使用线性模型并结合梯度下降法来优化模型参数,从而提高预测精度。通过这个实例,读者能够理解机器学习的核心理念和实践方法。
个人学习笔记以及概念梳理,望对大家有所帮助。
思维导图1.1
机器学习的主要任务类型(补充)
涉及的一些术语
术语 | 定义与说明 |
回归 (Regression) | 预测连续值输出的任务类型。例如预测未来的PM2.5数值。 |
分类 (Classification) | 预测离散值输出的任务类型,通常涉及从预定义类别中选择一项。例如判断一封邮件是否为垃圾邮件。 |
结构化学习 (Structured Learning) | 预测具有特定结构的输出的任务类型,如生成图像或文章。 |
特征 (Feature) | 用于预测的数据点,如昨天的观看次数。 |
模型 (Model) | 包含未知参数的函数,用于预测输出。 |
参数 (Parameter) | 模型中的未知变量,需要通过数据估计。 |
权重 (Weight) | 参数的一种,通常表示特征的重要性。 |
偏置 (Bias) | 参数的一种,通常用于调整模型的基础预测值。 |
损失函数 (Loss Function) | 评估模型预测与实际值差异的函数。 |
平均绝对误差 (Mean Absolute Error, MAE) | 损失函数的一种,计算预测值与实际值之间的平均绝对差值。 |
均方误差 (Mean Squared Error, MSE) | 损失函数的一种,计算预测值与实际值之间差值的平方的平均值。 |
交叉熵 (Cross Entropy) | 当预测值为概率分布时使用的损失函数。 |
超参数 (Hyperparameter) | 在模型训练过程中人为设定的参数,如学习率。 |
学习率 (Learning Rate, η) | 控制模型参数更新速度的超参数。 |
全局最小值 (Global Minima) | 损失函数达到全局最低点的参数值。 |
局部最小值 (Local Minima) | 损失函数达到局部最低点但非全局最低点的参数值。 |
梯度下降 (Gradient Descent) | 寻找使损失函数最小化的参数值的优化算法。 |
涉及到的一些公式
![](https://i-blog.csdnimg.cn/direct/90d8b3d335214b0ca5253ceeaeb148d7.png)
![](https://i-blog.csdnimg.cn/direct/ccaaafc662914a8db58cf849ebffa8f6.png)
学习过程遇到的一些问题的理解:
1机器学习找函数的过程可以总结为以下三个步骤
1)定义模型:选择一个包含未知参数的函数(模型),该函数能够预测输出。例如,在预测视频点击次数的例子中,模型被定义为 y=b+wx ,其中 y 是预测的观看次数,x 是前一天的观看次数,而 b 和 w 是未知参数。
2)定义损失函数:确定一个衡量标准(损失函数),用来评价模型预测的准确性。损失函数的目的是量化预测值与实际值之间的差距。例如,在预测视频点击次数的例子中,损失函数可以是均方误差(MSE),即预测值与实际值之差的平方的平均值。
3)优化模型参数:找到使损失函数最小化的模型参数。这通常是通过优化算法实现的,例如梯度下降法,它逐步调整参数值以减少损失函数的值。
2几种常见的梯度下降小结
批量梯度下降 适合小型数据集,计算准确但效率较低。
随机梯度下降 适合大型数据集,计算效率高但路径不稳定。
小批量梯度下降 是最常见的选择,结合了两者的优势。
带有动量的梯度下降 和 自适应学习率方法 可以进一步提高收敛速度和稳定性,适用于大多数场景。这里不详细展开,更多细节,可见https://www.cnblogs.com/suanfajin/p/18257713
代码运行
运用python 对波士顿房价数据集进行处理
常见回归类型效果的验证,此处运用了sklearn
import numpy as np
import pandas as pd
from sklearn import linear_model
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
#print(sklearn.__version__)
def TrianLinerRegression(X,y):
model = linear_model.LinearRegression()
model.fit(X, y)
print('LinerRegression E(|y-wTx|^2):' + str(np.mean((model.predict(X) - y) ** 2)))
return model
def TrainRidegeRegression(X, y, coeff):
model = linear_model.Ridge(alpha=coeff)
model.fit(X, y)
print('RidegeRegression E(|y-wTx|^2):' + str(np.mean((model.predict(X) - y) ** 2)))
return model
def TrainLassoRegression(X, y ,coeff):
model = linear_model.Lasso(alpha=coeff)
model.fit(X, y)
print('LassoRegression E(|y-wTx|^2):' + str(np.mean((model.predict(X) - y) ** 2)))
return model
def TestModel(X_test, y_test,model):
score = model.score(X_test, y_test)
y_pred = model.predict(X_test)
print('model test score is ' + str(score))
return y_pred, score
回归类型分别为
线性回归(Linear Regression)
岭回归(Ridge Regression)
Lassso回归
主函数:
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
label = raw_df.values[1::2, 2]
print('模型数据以及特征 ', data.shape, label.shape)
X_train, X_test, y_train, y_test = train_test_split(data, label, test_size=0.2)
print("训练集 ", X_train.shape, y_train.shape, X_test.shape, y_test.shape)
LinerModel = TrianLinerRegression(X_train, y_train)
RidgeModel = TrainRidegeRegression(X_train, y_train, 0.5)
LassoModel = TrainLassoRegression(X_train, y_train, 0.01)
print()
y_pred_linear, score_linear = TestModel(X_test, y_test, LinerModel)
y_pred_ridge, score_ridge = TestModel(X_test, y_test, RidgeModel)
y_pred_lasso, score_lasso = TestModel(X_test, y_test, LassoModel)
plt.figure()
plt.plot(range(30), y_pred_linear[:30], 'bo-', y_test[:30], 'y.--')
plt.title('Linear model prediction', fontsize='large')
plt.figure()
plt.plot(range(30), y_pred_ridge[:30], 'r>-', y_test[:30], 'y.--')
plt.title('Ridge model prediction', fontsize='large')
plt.figure()
plt.plot(range(30), y_pred_lasso[:30], 'ks-', y_test[:30], 'y.--')
plt.title('Lasso model prediction', fontsize='large')
plt.show()
运行结果:
![]() | ![]() |
![]() | ![]() |
得出:在训练集上,线性拟合最好,而岭回归和Lassso回归的误差反而较大,这是因为正则化项,在一定程度上牺牲了在训练集上的精度,但在新的测试样本中提高了性能。
小建议:在选择模型时,可以考虑奥卡姆剃刀原则和交叉验证,以确保模型的准确性和稳定性。
修改代码,运用torch来实现线性回归部分,代码如下:
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
#数据
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
label = raw_df.values[1::2, 2]
#转换
data_tensor = torch.tensor(data, dtype=torch.float32)
label_tensor = torch.tensor(label, dtype=torch.float32).view(-1, 1)
#训练 和 测试集
X_train, X_test, y_train, y_test = train_test_split(data_tensor, label_tensor, test_size=0.2, random_state=42)
# 定义线性回归模型
class LinearRegression(nn.Module):
def __init__(self, input_dim):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(input_dim, 1)
def forward(self, x):
return self.linear(x)
# 数据预处理
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 将数据转换为 PyTorch 张量
X_train_tensor = torch.from_numpy(X_train_scaled).float()
X_test_tensor = torch.from_numpy(X_test_scaled).float()
y_train_tensor = y_train.float().view(-1, 1) # 修改这一行
y_test_tensor = y_test.float().view(-1, 1)
# 初始化模型、损失函数和优化器
input_dim = X_train.shape[1]
model = LinearRegression(input_dim)
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):
# 前向传播
outputs = model(X_train_tensor)
loss = criterion(outputs, y_train_tensor)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
# 评估模型
model.eval()
with torch.no_grad():
y_pred = model(X_test_tensor)
mse = criterion(y_pred, y_test_tensor).item()
r2_score = 1 - (torch.sum((y_test_tensor - y_pred) ** 2) / torch.sum((y_test_tensor - torch.mean(y_test_tensor)) ** 2)).item()
# 打印评估指标
print(f'Test MSE: {mse:.4f}')
print(f'R2 Score: {r2_score:.4f}')
# 可视化预测结果
plt.figure(figsize=(10, 6))
plt.plot(range(len(y_test_tensor[:30])), y_test_tensor[:30].numpy(), 'yo--', label='Actual')
plt.plot(range(len(y_pred[:30])), y_pred[:30].detach().numpy(), 'bo-', label='Predicted')
plt.title('Linear Model Prediction')
plt.legend()
plt.show()
结果:
![]() | ![]() |
小结
机器学习概念
- 主要任务类型:回归、分类、结构化学习。
- 流程:定义模型、定义损失函数、优化参数。
梯度下降法
- 批量梯度下降:精确但慢。
- 随机梯度下降:快但路径不稳定。
- 小批量梯度下降:折中方案。
波士顿房价预测
- 比较了线性回归、岭回归和Lasso回归的效果。
- 训练集上,线性回归拟合最好;但正则化模型在测试集上表现更好。
建议
- 选择模型时考虑简单性原则和交叉验证。