数据可以直接在代码里下载
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
以下是训练的结果