PaddlePaddle实现线性回归
在本次实验中我们将使用PaddlePaddle来搭建一个简单的线性回归模型,并利用这一模型实现已知某地给定有机质含量对土壤的含氮量进行预测。并且在学习模型搭建的过程中,了解到机器学习的若干重要概念,掌握一个机器学习预测的基本流程。
** 线性回归的基本概念 **
线性回归是机器学习中最简单也是最重要的模型之一,其模型建立遵循此流程:获取数据、数据预处理、训练模型、应用模型。
回归模型可以理解为:存在一个点集,用一条曲线去拟合它分布的过程。如果拟合曲线是一条直线,则称为线性回归。如果是一条二次曲线,则被称为二次回归。线性回归是回归模型中最简单的一种。
在线性回归中有几个基本的概念需要掌握:
- 假设函数(Hypothesis Function)
- 损失函数(Loss Function)
- 优化算法(Optimization Algorithm)
假设函数:
假设函数是指,用数学的方法描述自变量和因变量之间的关系,它们之间可以是一个线性函数或非线性函数。 在本次线性回顾模型中,我们的假设函数为 $ \hat{Y}= aX_1+b $ ,其中,Y^\hat{Y}Y^表示模型的预测结果(预测房价),用来和真实的Y区分。模型要学习的参数即:a,b。
损失函数:
损失函数是指,用数学的方法衡量假设函数预测结果与真实值之间的误差。这个差距越小预测越准确,而算法的任务就是使这个差距越来越小。
建立模型后,我们需要给模型一个优化目标,使得学到的参数能够让预测值Y^\hat{Y}Y^尽可能地接近真实值Y。输入任意一个数据样本的目标值yiy_iyi和模型给出的预测值Yi^\hat{Y_i}Yi^,损失函数输出一个非负的实值。这个实值通常用来反映模型误差的大小。
对于线性模型来讲,最常用的损失函数就是均方误差(Mean Squared Error, MSE)。
MSE=1n∑i=1n(Yi^−Yi)2MSE=\frac{1}{n}\sum_{i=1}^{n}(\hat{Y_i}-Y_i)^2MSE=n1i=1∑n(Yi^−Yi)2
即对于一个大小为n的测试集,MSE是n个数据预测结果误差平方的均值。
优化算法:
在模型训练中优化算法也是至关重要的,它决定了一个模型的精度和运算速度。本章的线性回归实例中主要使用了梯度下降法进行优化。
现在,让我们正式进入实验吧!
1 - 引用库
首先载入需要用到的库,它们分别是:
- numpy:一个python的基本库,用于科学计算
- matplotlib.pyplot:用于生成图,在验证模型准确率和展示成本变化趋势时会使用到
- paddle.fluid:PaddlePaddle其中一种深度学习框架
- pandas:一种基于NumPy的工具,高效处理数据
第一步,先运行!ls /home/aistudio/data/代码看自己的数据集在哪,如我的为data2054,在data2054里面有data_soil.txt
In[2]
!ls /home/aistudio/data/
data2054
In[3]
!ls /home/aistudio/data/data2054
data_soil.txt
安装pandas(一般情况已经存在)
In[4]
!pip install pandas
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Looking in indexes: https://pypi.mirrors.ustc.edu.cn/simple/
Requirement already satisfied: pandas in /opt/conda/envs/python27-paddle120-env/lib/python2.7/site-packages (0.24.2)
Requirement already satisfied: pytz>=2011k in /opt/conda/envs/python27-paddle120-env/lib/python2.7/site-packages (from pandas) (2018.9)
Requirement already satisfied: numpy>=1.12.0 in /opt/conda/envs/python27-paddle120-env/lib/python2.7/site-packages (from pandas) (1.16.2)
Requirement already satisfied: python-dateutil>=2.5.0 in /opt/conda/envs/python27-paddle120-env/lib/python2.7/site-packages (from pandas) (2.8.0)
Requirement already satisfied: six>=1.5 in /opt/conda/envs/python27-paddle120-env/lib/python2.7/site-packages (from python-dateutil>=2.5.0->pandas) (1.12.0)
添加需要的库
In[5]
import sys
import paddle
import paddle.fluid as fluid
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from paddle.utils.plot import Ploter
from __future__ import print_function
from paddle.fluid.contrib.trainer import *
from paddle.fluid.contrib.inferencer import *
查看当前环境中的Python版本和Paddle版本
In[6]
print(sys.version)
print(paddle.__version__)
2.7.15 | packaged by conda-forge | (default, Feb 28 2019, 04:00:11)
[GCC 7.3.0]
1.5.0
2 - 数据预处理 本次数据集使用的是某地区的土壤有机质含量和氮含量的数据。氮含量和有机质含量近似成线性关系,数据集只有两列,以TXT的形式储存。本次预测要得到的他们之间的线性关系。 当真实数据被收集到后,它们往往不能直接使用,需要进行预处理。我们首先以表格的形式输出数据的前五行看一下
In[7]
colnames = ['有机质含量']+['氮含量']
print_data = pd.read_csv('/home/aistudio/data/data2054/data_soil.txt',names = colnames)
print_data.head()
有机质含量 | 氮含量 | |
---|---|---|
0 | 3.75 | 0.40 |
1 | 7.95 | 0.41 |
2 | 5.44 | 0.42 |
3 | 7.57 | 0.43 |
4 | 9.83 | 0.44 |
小技巧
如果不确定某个组件下有哪些方法或者属性, 可以尝试使用.之后按下tab键. 这个tab键也可以提示方法或函数需要的参数
归一化 观察一下数据的分布特征,一般而言,如果样本有多个属性,那么各维属性的取值范围差异会很大,这就要用到一个常见的操作-归一化(normalization)了。归一化的目标是把各维属性的取值范围放缩到差不多的区间,例如[-0.5, 0.5]。这里我们使用一种很常见的操作方法:减掉均值,然后除以原取值范围。
In[8]
# coding = utf-8 #
global x_raw,train_data,test_data
#下载原始数据赋值给data,将data分为train_data与test_data
data = np.loadtxt('/home/aistudio/data/data2054/data_soil.txt',delimiter = ',')
x_raw = data.T[0].copy()
maximums, minimums, avgs = data.max(axis=0), data.min(axis=0), data.sum(axis=0)/data.shape[0]
print("the raw area :",data[:,0].max(axis = 0))
#进行归一化操作
feature_num = 2
for i in range(feature_num-1):
#输入归一化的代码
#需要自行编程实现
data[:,i]=(data[:,i]-avgs[i])/(maximums[i] - minimums[i])
print('normalization:',data[:,0].max(axis = 0))
the raw area : 85.67
normalization: 0.5386874418397725
数据集分割 将原始数据处理为可用数据后,为了评估模型的好坏,我们将数据分成两份:训练集和测试集。 训练集数据用于调整模型的参数,即进行模型的训练,模型在这份数据集上的误差被称为训练误差; 测试集数据被用来测试,模型在这份数据集上的误差被称为测试误差。 我们训练模型的目的是为了通过从训练数据中找到规律来预测未知的新数据,所以测试误差是更能反映模型表现的指标。分割数据的比例要考虑到两个因素:更多的训练数据会降低参数估计的方差,从而得到更可信的模型;而更多的测试数据会降低测试误差的方差,从而得到更可信的测试误差。我们这个例子中设置的分割比例为8:2。 定义reader 构造read_data()函数,来读取训练数据集train_set或者测试数据集test_set。它的具体实现是在read_data()函数内部构造一个reader(),使用yield关键字来让reader()成为一个Generator(生成器),注意,yield关键字的作用和使用方法类似return关键字,不同之处在于yield关键字可以构造生成器(Generator)。虽然我们可以直接创建一个包含所有数据的列表,但是由于内存限制&