实验三 基于线性回归的波士顿房价预测

目录

引言

步骤:

数据预处理

异常值处理

数据集划分

特征工程

模型构建

模型训练

模型测试

模型预测

附完整代码


引言

在本次实验中,利用PyTorch框架和线性回归模型对波士顿房价进行预测。通过数据预处理、模型构建、训练、测试和预测,提升了房价预测的准确性,深入理解了PyTorch在深度学习中的应用。

步骤:

数据预处理

在机器学习和深度学习中,数据预处理是一个至关重要的步骤。良好的数据预处理能够显著提高模型的性能和预测能力。数据预处理的目标是清洗、规范化和准备数据,以便更好地用于模型训练和测试。

异常值处理

数据预处理的首要步骤是识别并处理异常值。使用箱线图来直观地展示数据的分布情况。通过观察箱线图,发现数据中存在多个异常值。

为了处理这些异常值,采用了四分位数法。首先计算每个特征的第一四分位数(Q1)和第三四分位数(Q3),然后计算四分位间距(IQR)。异常值定义为小于 Q1 - 1.5 * IQR 或大于 Q3 + 1.5 * IQR 的值。使用临界值来替代这些异常值,从而减少它们对模型性能的负面影响。

# 读取数据
data = pd.read_csv("boston_house_prices.csv")
columns = data.columns
num_columns = len(columns)


# 画箱线图的函数
def boxplot(data):
    # 创建3行5列的子图布局
    fig, axs = plt.subplots(nrows=(num_columns // 3) + 1, ncols=3, figsize=(20, 15))
    # 绘制每一列的箱线图
    for i, col in enumerate(columns):
        row = i // 3
        col_num = i % 3
        axs[row, col_num].boxplot(data[col])
        axs[row, col_num].set_title(col)
        axs[row, col_num].set_ylabel('Values')
        axs[row, col_num].grid(True)

    # 调整布局,防止子图重叠
    plt.tight_layout()
    plt.show()


boxplot(data)

# 利用四分位数识别异常值
num_features = data.select_dtypes(exclude=['object', 'bool']).columns.tolist()
for feature in num_features:
    if feature == 'CHAS':
        continue

    Q1 = data[feature].quantile(q=0.25)
    Q3 = data[feature].quantile(q=0.75)
    # 利用临界值替代异常值
    IQR = Q3 - Q1
    top = Q3 + 1.5 * IQR
    bot = Q1 - 1.5 * IQR
    values = data[feature].values
    values[values > top] = top
    values[values < bot] = bot
    data[feature] = values.astype(data[feature].dtype)

boxplot(data)
数据集划分

数据集被划分为训练集和测试集,比例为80%和20%。这一步骤通过train_test_split函数实现,确保了模型能够在未见过的数据上进行有效的泛化。

# 划分数据集
X = data.drop('MEDV', axis=1)  # 特征
y = data['MEDV']  # 目标变量
# 划分训练集和测试集,比例为80%和20%
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练集构建
train_dataset = (X_train, y_train)
# 测试集构建
test_dataset = (X_test, y_test)
特征工程

为了消除不同特征之间的量纲影响,对特征进行了归一化处理。使用MinMaxScaler将数据缩放到[0, 1]区间内,使得不同特征之间具有可比性。这一步骤对于提高模型的收敛速度和预测准确性至关重要。

# 特征归一化
# 创建 MinMaxScaler 对象
scaler = MinMaxScaler()
# 对特征进行归一化
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

模型构建

# 定义线性回归模型
class LinearRegressionModel(nn.Module):
    def __init__(self, input_size):
        super(LinearRegressionModel, self).__init__()
        # 线性层,输入特征数量为输入的特征数,输出为1
        self.linear = nn.Linear(input_size, 1)

    def forward(self, x):
        return self.linear(x)


# 将数据转化为 PyTorch 的 Tensor
X_train_tensor = torch.tensor(X_train_scaled, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)

# 定义模型
input_size = X_train_tensor.shape[1]
model = LinearRegressionModel(input_size)

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

模型训练

# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):
    model.train()

    # 前向传播
    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}')


# 打印训练得到的权重和偏置
print("权重 (w):", model.linear.weight.data)
print("偏置 (b):", model.linear.bias.data)

模型测试

# 转换测试集数据为 Tensor
X_test_tensor = torch.tensor(X_test_scaled, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1)

# 测试模型
model.eval()  # 将模型设置为评估模式
with torch.no_grad():
    y_pred = model(X_test_tensor)
    test_loss = criterion(y_pred, y_test_tensor)
    predictions = model(X_test_tensor).numpy()  # 转换为 numpy 数组
    y_test_numpy = y_test_tensor.numpy()

    mse = mean_squared_error(y_test_numpy, predictions)
    print(f'测试集上均方误差: {mse:.4f}')

print(f'损失: {test_loss.item():.4f}')

模型预测

# 使用训练好的模型进行预测
with torch.no_grad():
    predictions = model(X_test_tensor)
    predictions = predictions.numpy()

# 打印前10个预测结果
print(f"预测结果: {predictions[:10].flatten()}")
print(f"真实值: {y_test.values[:10]}")

完整运行结果:

附完整代码:
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import torch
import torch.nn as nn
import torch.optim as optim

# 读取数据
data = pd.read_csv("boston_house_prices.csv")
columns = data.columns
num_columns = len(columns)


# 画箱线图的函数
def boxplot(data):
    # 创建3行5列的子图布局
    fig, axs = plt.subplots(nrows=(num_columns // 3) + 1, ncols=3, figsize=(20, 15))
    # 绘制每一列的箱线图
    for i, col in enumerate(columns):
        row = i // 3
        col_num = i % 3
        axs[row, col_num].boxplot(data[col])
        axs[row, col_num].set_title(col)
        axs[row, col_num].set_ylabel('Values')
        axs[row, col_num].grid(True)

    # 调整布局,防止子图重叠
    plt.tight_layout()
    plt.show()


boxplot(data)

# 利用四分位数识别异常值
num_features = data.select_dtypes(exclude=['object', 'bool']).columns.tolist()
for feature in num_features:
    if feature == 'CHAS':
        continue

    Q1 = data[feature].quantile(q=0.25)
    Q3 = data[feature].quantile(q=0.75)
    # 利用临界值替代异常值
    IQR = Q3 - Q1
    top = Q3 + 1.5 * IQR
    bot = Q1 - 1.5 * IQR
    values = data[feature].values
    values[values > top] = top
    values[values < bot] = bot
    data[feature] = values.astype(data[feature].dtype)

boxplot(data)

# 划分数据集
X = data.drop('MEDV', axis=1)  # 特征
y = data['MEDV']  # 目标变量
# 划分训练集和测试集,比例为80%和20%
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练集构建
train_dataset = (X_train, y_train)
# 测试集构建
test_dataset = (X_test, y_test)

# 特征归一化
# 创建 MinMaxScaler 对象
scaler = MinMaxScaler()
# 对特征进行归一化
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)


# 定义线性回归模型
class LinearRegressionModel(nn.Module):
    def __init__(self, input_size):
        super(LinearRegressionModel, self).__init__()
        # 线性层,输入特征数量为输入的特征数,输出为1
        self.linear = nn.Linear(input_size, 1)

    def forward(self, x):
        return self.linear(x)


# 将数据转化为 PyTorch 的 Tensor
X_train_tensor = torch.tensor(X_train_scaled, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)

# 定义模型
input_size = X_train_tensor.shape[1]
model = LinearRegressionModel(input_size)

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):
    model.train()

    # 前向传播
    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}')


# 打印训练得到的权重和偏置
print("权重 (w):", model.linear.weight.data)
print("偏置 (b):", model.linear.bias.data)


# 转换测试集数据为 Tensor
X_test_tensor = torch.tensor(X_test_scaled, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1)

# 测试模型
model.eval()  # 将模型设置为评估模式
with torch.no_grad():
    y_pred = model(X_test_tensor)
    test_loss = criterion(y_pred, y_test_tensor)
    predictions = model(X_test_tensor).numpy()  # 转换为 numpy 数组
    y_test_numpy = y_test_tensor.numpy()

    mse = mean_squared_error(y_test_numpy, predictions)
    print(f'测试集上均方误差: {mse:.4f}')

print(f'损失: {test_loss.item():.4f}')


# 使用训练好的模型进行预测
with torch.no_grad():
    predictions = model(X_test_tensor)
    predictions = predictions.numpy()

# 打印前10个预测结果
print(f"预测结果: {predictions[:10].flatten()}")
print(f"真实值: {y_test.values[:10]}")

第一次写博客感觉写的不是很好,希望uu们可以提一些建议(˃ ⌑ ˂ഃ )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值