3 线性回归应用-波士顿房价预测

数据可以直接在代码里下载

import torch
from torch import nn
from torch.utils.data import DataLoader
from chapter1 import data_download_and_load as ddal  # 数据下载
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler  # 数据预处理模块
import pandas as pd  # 数据处理模块


def draw_lines(ds, names):

    """
    :param ds: [数据列表1,数据列表2]
    :param names:[name1,name2]
    :return:
    """

    plt.figure()  # 创建一个图框
    x = range(len(ds[0]))
    for d, name in zip(ds, names):
        plt.plot(x, d, label=name)
        plt.xlabel('X', fontsize=14)
        plt.ylabel('Y', fontsize=14)
        plt.legend(fontsize=16, loc='upper left')
        plt.grid(c='gray')
    plt.show()


class LinearReg(nn.Module):

    # 初始化子类
    def __init__(self, n_features):

        # 继承父类属性
        super(LinearReg, self).__init__()  # 第一种继承方法 python2 python3通用
        # 初始化权值
        self.linear = nn.Linear(n_features, 1, bias=True)  # 第一种方法 初始化Linear类 变量分别是权重项w个数 偏置项b个数 以及是否打乱

    # 前向传播
    def forward(self, x):
        y = self.linear(x)
        y = torch.squeeze(y)  # 对一维的矩阵进行压缩
        return y


@torch.no_grad()  # 关掉梯度计算 节省计算时间
def eva(dates, net, y_min, y_max):

    net.eval()  # 测试模式
    x = torch.Tensor(dates[:, :-1])  # 将测试集数据转化为tensor格式
    y = dates[:, -1]
    y_pr = net(x)

    # 归一化的值还原 更贴切实际
    y_pr = anti_min_max_scaler(y_pr, y_min, y_max)
    y = anti_min_max_scaler(y, y_min, y_max)

    criterion = nn.MSELoss()  # 平方差损失函数
    loss = criterion(y_pr, torch.Tensor(y))
    print(loss**0.5)

    draw_lines([y, y_pr], ['true', 'pr'])


# 数据预处理 数据归一化
def preprocess(df):
    ss = MinMaxScaler()  # 初始化MinMaxScaler() 归一化的方法之一
    df = ss.fit_transform(df)  # 做(x-min)/(max-min)计算 归一化
    df = pd.DataFrame(df)  # 将计算后的值转化为DataFrame格式
    return df, ss.data_min_[-1], ss.data_max_[-1]  # 返回归一化后的数据以及标签值的最大最小值


# 归一化还原
def anti_min_max_scaler(d, y_min, y_max):
    return d*(y_max-y_min)+y_min


def train(epochs=2000, batch_size=16, lr=0.01):

    # 数据处理
    df, y_min, y_max = preprocess(ddal.load_boston())  # 数据预处理
    train_df, test_df = ddal.split_train_test_from_df(df, test_ratio=0.2)  # 将数据集划分为训练集和测试集

    # 初始化模型、损失函数、梯度下降函数三大类
    net = LinearReg(train_df.shape[1]-1)  # 初始化线性回归模型 同时初始化权值
    criterion = nn.MSELoss()  # 初始化平方差损失函数
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)  # 初始化随机梯度下降函数

    net.train()  # 训练模式
    for e in range(epochs):
        for datas in DataLoader(train_df.values, batch_size=batch_size, shuffle=True):
            optimizer.zero_grad()  # 梯度归0
            x = datas[:, :-1]  # 获取X 训练值
            y = datas[:, -1]  # 获取y 标签值
            y_pr = net(x)  # 得到预测值y
            loss = criterion(y_pr, y)  # 将预测的y与真实的y带入损失函数计算损失值
            loss.backward()  # 反馈
            optimizer.step()  # 沿梯度下降方向更新所有参数
        print('epoch{},loss={:.4f}'.format(e, loss))

    # 测试训练结果
    eva(test_df.values, net, y_min, y_max)


if __name__ == '__main__':
    train()


from chapter1 import data_download_and_load as ddal  # 数据下载

这个模块代码如下:

import pandas as pd  # 科学计算库 数据基本结构为DataFrame
from sklearn import datasets  # 机器学习库
from data_set import filepaths as fp
from os import path as osp
import numpy as np
from utils import osUtils as oU
import random


BOSTON_CSV = osp.join(fp.BOSTON_DIR, 'boston.csv')
IRIS_CSV = osp.join(fp.IRIS_DIR, 'iris.csv')
ML100K_TSV = osp.join(fp.ML100K_DIR, 'rating_index.tsv')


# 将下载的数据转化为DataFrame格式(pandas所用的格式)
def sklearn_to_df(sklearn_dataset):
    df = pd.DataFrame(sklearn_dataset.data, columns=sklearn_dataset.feature_names)
    df['target'] = pd.Series(sklearn_dataset.target)
    return df


# 下载波士顿房价数据及格式转换
def download_boston():
    boston = datasets.load_boston()  # 从datasets数据库里下载波士顿房价数据
    df = sklearn_to_df(boston)  # 将下载的数据转化为DataFrame格式(pandas所用的格式)
    print(df)
    df.to_csv(BOSTON_CSV)  # 将DataFrame格式转化为excel可读的csv格式


# 读取csv文件并转化为pandas所用的DataFrame格式
def load_boston():
    return pd.read_csv(BOSTON_CSV, index_col=0, dtype=np.float32)


def download_iris():
    iris = datasets.load_iris()
    df = sklearn_to_df(iris)
    df.to_csv(IRIS_CSV)


def load_iris():
    return pd.read_csv(IRIS_CSV, index_col=0, dtype=np.float32)


# 将数据划为为训练集和测试集
def split_train_test_from_df(df, test_ratio=0.2):  # 指定测试集的百分比
    test_df = df.sample(frac=test_ratio)  # 在数据集里面采样20%作为测试集
    train_df = df[~df.index.isin(test_df.index)]  # 其余的为训练集
    return train_df, test_df


def read_rec_data(path=ML100K_TSV, test_ratio=0.2):
    user_set, item_set = set(), set()
    triples = []
    for u, i, r in oU.readTriple(path):
        user_set.add(int(u))
        item_set.add(int(i))
        triples.append((int(u), int(i), int(r)))

    test_set = random.sample(triples, int(len(triples)*test_ratio))
    train_set = list(set(triples)-set(test_set))

    # 返回用户集合列表,物品集合列表,与用户,物品,评分三元组列表
    return list(user_set), list(item_set), train_set, test_set


if __name__ == '__main__':
    download_boston()

    # downloadIris()
    # df = loadBoston()

数据集一共500条数据,划分训练集与测试集为8:2
训练了2000个epoch
batch_size选取为16,学习率为0.01
以下是训练的结果
真实值与预测值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值