转:https://blog.csdn.net/weixin_40014576/article/details/79918819
Python实现多元线性回归
线性回归介绍
线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。其表达形式为y = w'x+e,e为误差服从均值为0的正态分布。回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。
线性回归属于回归问题。对于回归问题,解决流程为:
给定数据集中每个样本及其正确答案,选择一个模型函数h(hypothesis,假设),并为h找到适应数据的(未必是全局)最优解,即找出最优解下的h的参数。这里给定的数据集取名叫训练集(Training Set)。不能所有数据都拿来训练,要留一部分验证模型好不好使,这点以后说。先列举几个几个典型的模型:
● 最基本的单变量线性回归:
形如h(x)=theta0+theta1*x1
● 多变量线性回归:
形如h(x)=theta0+theta1*x1+theta2*x2+theta3*x3
● 多项式回归(Polynomial Regression):
形如h(x)=theta0+theta1*x1+theta2*(x2^2)+theta3*(x3^3)
或者h(x)=ttheta0+theta1*x1+theta2*sqr(x2)
但是可以令x2=x2^2,x3=x3^3,于是又将其转化为了线性回归模型。虽然不能说多项式回归问题属于线性回归问题,但是一般我们就是这么做的。
● 所以最终通用表达式就是:
这里写图片描述
数据导入与清洗
对于数据导入来说,可以利用pandas内的read_csv的函数来对数据进行导入操作,在进行多元线性回归之间通过简单线性回归来展现线性回归的特性和结果之后再延伸至多元线性回归。
在进行数据导入之间需要导入进行线性回归的包:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import DataFrame,Series
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression
我们利用pandas和numpy对数据进行操作,使用matplotlib进行图像化,使用sklearn进行数据集训练与模型导入。
简单线性回归
对于学生来说,所学习的时间和考试的成绩挂钩,所学习的时间与考试的成绩也是呈线性相关。创建一个数据集来描述学生学习时间与成绩的关系并且做简单的线性回归。
in:
#创建数据集
examDict = {'学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,
2.00,2.25,2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
'分数':[10,22,13,43,20,22,33,50,62,
48,55,75,62,73,81,76,64,82,90,93]}
#转换为DataFrame的数据格式
examDf = DataFrame(examDict)
通过DataFrame的函数将字典转化为所需要的数据集,也就是学生成绩与考试成绩的数据集。且关于pandas的数据内容Series与DataFrame可以查看关于pandas的博客了解点击打开链接
out:
分数 学习时间
0 10 0.50
1 22 0.75
2 13 1.00
3 43 1.25
4 20 1.50
5 22 1.75
6 33 1.75
7 50 2.00
8 62 2.25
9 48 2.50
10 55 2.75
11 75 3.00
12 62 3.25
13 73 3.50
14 81 4.00
15 76 4.25
16 64 4.50
17 82 4.75
18 90 5.00
19 93 5.50
从上面的数据可以看到数据的特征值与其标签,学生所学习的时间就是所需要的特征值,而成绩就是通过特征值所反应的标签。在这个案例中要对数据进行观测来反应学习时间与成绩的情况,将利用散点图来实现简单的观测。
in:
#绘制散点图
plt.scatter(examDf.分数,examDf.学习时间,color = 'b',label = "Exam Data")
#添加图的标签(x轴,y轴)
plt.xlabel("Hours")
plt.ylabel("Score")
#显示图像
plt.show()
out:
从上图可以看到对于分数和时间来说存在相应的线性关系,且俩数据间相关性较强。
在此可以通过相关性来衡量两个变量因素的相关密切程度。
相关系数是用以反映变量之间相关关系密切程度的统计指标。
r(相关系数) = x和y的协方差/(x的标准差*y的标准差) == cov(x,y)/σx*σy(即person系数)
对于相关性强度来说的化有以下的关系:
0~0.3 弱相关
0.3~0.6 中等程度相关
0.6~1 强相关
in:
rDf = examDf.corr()
print(rDf)
out:
分数 学习时间
分数 1.000000 0.923985
学习时间 0.923985 1.000000
pandas中的数学统计函数D.corr()可以反应数据间的相关性关系,可从表值中反应出学习时间与分数之间的相关性为强相关(0.6~1)。对于简单线性回归来来说,简单回归方程为: y = a + b*x (模型建立最佳拟合线)最佳拟合线也是需要通过最小二乘法来实现其作用。对于OLS即最小二乘法我们需要知道的一个关系为点误差,点误差 = 实际值 - 预测值,而误差平方和(Sum of square error) SSE = Σ(实际值-预测值)^2,最小二乘法就是基于SSE实现,最小二乘法 : 使得误差平方和最小(最佳拟合)。解释完简单线性回归后进行对训练集和测试集的创建,将会使用train_test_split函数来创建(train_test_split是存在与sklearn中的函数)
in:
#将原数据集拆分训练集和测试集
X_train,X_test,Y_train,Y_test = train_test_split(exam_X,exam_Y,train_size=.8)
#X_train为训练数据标签,X_test为测试数据标签,exam_X为样本特征,exam_y为样本标签,train_size 训练数据占比
print("原始数据特征:",exam_X.shape,
",训练数据特征:",X_train.shape,
",测试数据特征:",X_test.shape)
print("原始数据标签:",exam_Y.shape,
",训练数据标签:",Y_train.shape,
",测试数据标签:",Y_test.shape)
#散点图
plt.scatter(X_train, Y_train, color="blue", label="train data")
plt.scatter(X_test, Y_test, color="red", label="test data")
#添加图标标签
plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Pass")
#显示图像
plt.savefig("tests.jpg")
plt.show()
out:
原始数据特征: (20,) ,训练数据特征: (16,) ,测试数据特征: (4,)
原始数据标签: (20,) ,训练数据标签: (16,) ,测试数据标签: (4,)
tips:由于训练集随机分配的原因每一次运行的结果(点的分布情况,训练集内的情况,测试集内的情况)不都相同在创建数据集之后我们需要将训练集放入skleran中的线性回归模型(LinearRegression())进行训练,使用函数种的.fit函数进行模型的训练操作。
in:
model = LinearRegression()
#对于模型错误我们需要把我们的训练集进行reshape操作来达到函数所需要的要求
# model.fit(X_train,Y_train)
#reshape如果行数=-1的话可以使我们的数组所改的列数自动按照数组的大小形成新的数组
#因为model需要二维的数组来进行拟合但是这里只有一个特征所以需要reshape来转换为二维数组
X_train = X_train.values.reshape(-1,1)
X_test = X_test.values.reshape(-1,1)
model.fit(X_train,Y_train)
在模型训练完成之后会得到所对应的方程式(线性回归方程式)需要利用函数中的intercept_与coef_来得到
a = model.intercept_#截距
b = model.coef_#回归系数
print("最佳拟合线:截距",a,",回归系数:",b)
out:
最佳拟合线:截距 7.5580754557 ,回归系数: [ 16.28401865]
由上述的最佳拟合线的截距和回归系数可以算出其线性回归线方程:y = 7.56 + 16.28*x
接下来需要对模型进行预测和对模型进行评价,在进行评价之间将会引入一个决定系数r平方的概念。
对于决定系数R平方常用于评估模型的精确度。
下列为R平方的计算公式:
● y误差平方和 = Σ(y实际值 - y预测值)^2
● y的总波动 = Σ(y实际值 - y平均值)^2
● 有多少百分比的y波动没有被回归拟合线所描述 = SSE/总波动
● 有多少百分比的y波动被回归线描述 = 1 - SSE/总波动 = 决定系数R平方
对于决定系数R平方来说
(1) 回归线拟合程度:有多少百分比的y波动刻印有回归线来描述(x的波动变化)
(2)值大小:R平方越高,回归模型越精确(取值范围0~1),1无误差,0无法完成拟合对于预测来说我们需要运用函数中的model.predict()来得到预测值
in:
#训练数据的预测值
y_train_pred = model.predict(X_train)
#绘制最佳拟合线:标签用的是训练数据的预测值y_train_pred
plt.plot(X_train, y_train_pred, color='black', linewidth=3, label="best line")
#测试数据散点图
plt.scatter(X_test, Y_test, color='red', label="test data")
#添加图标标签
plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Score")
#显示图像
plt.savefig("lines.jpg")
plt.show()
score = model.score(X_test,Y_test)
print(score)
out:
score : 0.834706696876
多元线性回归
在间单线性回归的例子中可以得到与线性回归相关的分析流程,接下来对多元线性回归进行分析对于多元线性回归前面已经提到,形如h(x)=theta0+theta1*x1+theta2*x2+theta3*x3从http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv来下载数据集 Advertising.csv,其数据描述了一个产品的销量与广告媒体的投入之间影响。将会利用pandas的pd.read()来读取数据。
in:
#通过read_csv来读取我们的目的数据集
adv_data = pd.read_csv("C:/Users/Administrator/Desktop/Advertising.csv")
#清洗不需要的数据
new_adv_data = adv_data.ix[:,1:]
#得到我们所需要的数据集且查看其前几列以及数据形状
print('head:',new_adv_data.head(),'\nShape:',new_adv_data.shape)
out:
head: TV radio newspaper sales
0 230.1 37.8 69.2 22.1
1 44.5 39.3 45.1 10.4
2 17.2 45.9 69.3 9.3
3 151.5 41.3 58.5 18.5
4 180.8 10.8 58.4 12.9
Shape: (200, 4)