欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【机器学习sklearn实战】线性回归器

程序员文章站 2022-07-14 13:39:56
...

一 线性回归的基础概念

线性回归 逻辑回归(logistic) 非线性假设 softmax
机器学习算法之线性回归算法(Linear Regression)

二 sklearn线性回归

使用sklearn中的库,一般使用线性回归器

  • 首先,倒入包: from sklearn.linear_model import LinearRegression
  • 创建模型: linear =LinearRegression()
  • 拟合模型: linear.fit(x,y)
  • 模型的预测值: linear.predict(输入数据)
  • 线性回归模型的权重linear.coef_和偏置linear.intercept_

三 简单实例

案例1:简单的线性回归器

参考:机器学习算法之线性回归算法(Linear Regression)
代码easy_linear_example.py:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 产生数据
x = np.linspace(0,10,50)  # 在规定的时间内,返回固定间隔的数据。他将返回“num”个等间距的样本
print(x.shape)  # 0到10等间隔产生50个数 shape:(50,) 一维向量
noise = np.random.uniform(-2, 2, size=50)
y=5*x+noise

# 创建模型
linear =LinearRegression()
# 拟合模型
linear.fit(np.reshape(x,(-1,1)),np.reshape(y,(-1,1)))
print(linear)
# 预测
y_pred =linear.predict(np.reshape(x,(-1,1)))
plt.figure(figsize=(5,5))  # 产生一个窗口
plt.scatter(x,y)  # 画散点图
plt.plot(x,y_pred,color='red')
plt.show()
print(linear.coef_)
print(linear.intercept_)

'''
np.linspace : https://blog.csdn.net/weixin_39010770/article/details/86015822
np.random.uniform:https://blog.csdn.net/u013920434/article/details/52507173
'''

【机器学习sklearn实战】线性回归器

案例2:单变量回归器(带有数据集)

参考:线性回归sklearn实现
数据集名称:dataset.csv

room_num,area,price
2,100,310
3,60,160
2,110,335
3,50,140
2,90,260
2,80,250
2,120,400
2,70,220

代码 linear_singal_var.py:

'''
单变量线性回归,使用sklearn
'''
# 准备数据集
import pandas as pd
dataset = pd.read_csv('dataset.csv')
# print(dataset.shape)   # (8, 3)
import numpy as np
X = np.asarray(dataset.get('area')).reshape(-1,1)  # (8, 1) X变成了tensor,维度是2
y=dataset.get('price')  # shape(8,)
# print(X)  # X经过了np,是向量
# print(y[0])  # y是列表形式的数字 y[0]  y[1].....形式,每个值是int类型的数字y[0]+y[1],可执行加减等运算

# 划分数据
X_train = X[:-3]  # 第1维一共8个数据,取走5个作为训练
X_test = X[-3:] # 最后3个作为test
y_train = y[:-3]
y_test = y[-3:]  # 标签

from sklearn import  linear_model
regr=linear_model.LinearRegression().fit(X_train,y_train)  # 拟合模型,regr是一个实例化的对象,可以调用对象的各种函数
y_pred = regr.predict(X_test)

# 输出模型的参数:https://www.jianshu.com/p/6a818b53a37e
print("Coefficients",regr.coef_)  # 模型权重
print("Intercept",regr.intercept_)  # 模型偏置
print("the model is : y = ",regr.coef_,'* X + ',regr.intercept_)

# 均方误差
from sklearn.metrics import mean_squared_error,r2_score
print('Mean squared error: %.2f'%mean_squared_error(y_test,y_pred))
print('Variance score: %.2f'%r2_score(y_test,y_pred))  # r2_score越接近1越好

# 画图
import matplotlib.pyplot as plt
plt.xlabel('area')
plt.ylabel('price')
# 画训练集的散点图
plt.scatter(X_train,y_train,alpha=0.8,color='black')
# 画模型
plt.plot(X_train,regr.coef_*X_train+regr.intercept_,color='red',linewidth=1) #  这句话和下面那一句一样
plt.plot(X_train,regr.predict(X_train),color='blue',linewidth=1)
plt.show()

【机器学习sklearn实战】线性回归器

案例3:双变量回归器

参考:线性回归sklearn实现
数据集同上面一样dataset.csv
代码

'''
双变量线性回归
'''

import pandas as pd
dataset=pd.read_csv('dataset.csv')
# print(dataset.shape)  # (8,3)
import numpy as np
X=np.asarray(dataset.get(["room_num","area"]))  # (8, 2)
y=dataset.get("price")
# print(X.shape)

# 划分数据
X_train = X[:-2]  # 第1维一共8个数据,取走5个作为训练
X_test = X[-2:]  # 最后3个作为test
y_train = y[:-2]
y_test = y[-2:]  # 标签

from sklearn import  linear_model
regr=linear_model.LinearRegression().fit(X_train,y_train)  # 拟合模型,regr是一个实例化的对象,可以调用对象的各种函数
y_pred = regr.predict(X_test)

print("Coefficients",regr.coef_)  # 模型权重
print("Intercept",regr.intercept_)  # 模型偏置
print("the model is : y = ",regr.coef_,'* X + ',regr.intercept_)

# 均方误差
from sklearn.metrics import mean_squared_error,r2_score
print('Mean squared error: %.2f'%mean_squared_error(y_test,y_pred))
print('Variance score: %.2f'%r2_score(y_test,y_pred))  # r2_score越接近1越好

# 画图
# 这一段是为了画模型准备的数据,因为模型是平面,所以需要很多个点才能画出
# 给room_num 和area,用coef_[0]*room +coef_[1]*area + intercept_就得到一个点,
# 然后我们需要很多点,才能画一个平面,所以利用np.meshgrid扩增了输入数据room_num 和area,
# 然后都按照上面的操作进行,最终的到y,然后画很多点,得到了平面
x0,x1 = np.meshgrid(np.asarray(X_train)[:,0],np.asarray(X_train)[:,1])  # 画三维图的时候要转为meshgrid,然后后米纳在画图
print(x0)
print(np.asarray(X_train)[:,0])  # [2 3 2 3 2 2]
print(x1)
print(np.asarray(X_train)[:,1])  # [100  60 110  50  90  80]
y = np.asarray(regr.coef_[0]*x0+regr.coef_[1]*x1+regr.intercept_)
y_pred = regr.predict(X_train)
print(y)
print(y_pred)  # 只有(1,1) (2,2) (3,3)位置的点,才是原数据得到的点,其他位置都是我们自己为了画平面扩增的点

import matplotlib.pyplot as plt
fig = plt.figure()
from mpl_toolkits.mplot3d import Axes3D
ax = Axes3D(fig)
ax.set_xlabel("room_num")
ax.set_ylabel("area")
ax.set_zlabel("price")

# # 画训练集的散点图
ax.scatter(np.asarray(X_train)[:, 0], np.asarray(X_train)[:, 1], np.asarray(y_train), alpha=0.8, color='black')
# 画模型,三维空间中的一个平面
ax.plot_surface(x0, x1, y, shade=False)
plt.show()

【机器学习sklearn实战】线性回归器

四 波士顿房价预测案例

参考:线性回归之波士顿房价实例分析
代码boston_all.py:

'''
boston 房价预测整体,boston数据集有506个数据,每个数据有13个特征,数据有data部分和target部分,获取的数据都是float类型的
python3
'''
import numpy as np
from sklearn import datasets
boston = datasets.load_boston()
# print(boston.DESCR)  # 打印描述文档 506个数据,每个数据有13个特征

# 划分train test 利用采样频率划分
sampleRatio = 0.5
n_samples = len(boston.target)  # 506
# print(n_samples)
sampleBoundary = int(sampleRatio * n_samples)  # 训练集个数
# 洗乱整个集合,并取出相应的train 和test 数据集
shuffleIdx = list(range(n_samples))  # 获取数据编号
np.random.shuffle(shuffleIdx)  # 打乱
# train的特征和回归值
train_features = boston.data[shuffleIdx[:sampleBoundary]]  # shape(253,13)  取出打乱以后的前一半作为train
# print(train_features.shape)
train_target = boston.target[shuffleIdx[:sampleBoundary]]
#test 的特征和回归值
test_features = boston.data[shuffleIdx[sampleBoundary:]]
test_target = boston.target[shuffleIdx[sampleBoundary:]]

# 获取回归模型
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()  # 获取模型
regressor.fit(train_features,train_target)  # 拟合
test_pred = regressor.predict(test_features)  # 得到test的预测结果

# 画出预测结果的图
import matplotlib.pyplot as plt
plt.plot(test_pred,test_target,'rx')  # 画出test的预测值和test的真实值
# 表示,横坐标为预测值,纵坐标为真实值,如果预测值和真实值相同,就会显示在图中的y=x这条线上,
# 也就是,y=x这条线上的值,预测准确
plt.plot([test_pred.min(),test_pred.max()],[test_pred.min(),test_pred.max()],'b-',lw=4)
plt.xlabel("预测值")
plt.ylabel("真实值")
plt.show()
# 蓝色线上的点准确,蓝色上下的点错误

【机器学习sklearn实战】线性回归器

所有的代码都上传到github上

补充说明:

波士顿房价预测案例,我附上的链接中用到了另一种交叉验证的方式,所以补充介绍一下交叉验证

  • 一般来说,数据充足情况下,是将数据分为训练集(训练模型),测试集(评估模型性能),验证集(模型选择)三部分,选择验证误差最小的模型。若数据不充足情况下,选择模型可采用交叉验证方法
  • 交叉验证是在机器学习建立模型和验证模型参数时常用的办法,重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏,选择测试误差最小的模型。

关于cross-validation,很容易陷入一个错误的疑惑

“经过cross-validation验证后,其最终的模型该如何确定?“即如10折交叉检验,每次检验就可以得到一个模型,10折就有10个模型,如何选择最终的一个模型?

其实,这样想已经陷入了一个本末倒置的错误了。因为k-fold cross validation的目的不是为了选择模型,而是先是有了一个模型,对这个模型进行精度评定

当我们说一个model的时候,通常指的是一种特定的描述输入数据与预测输出数据是怎样关联的方法(比如是线性还是逻辑还是神经网络,这才是3种不同的model)。而一般不是指某一种方法的不同的实例,就可以作为不同的模型。
所以,你可以说,我有一个线性回归模型。但是,由两个不同的数据集训练出不同的神经网络模型,你就说,这是两个不同的model,这种说法明显是错误的,因为这明明都是神经网络model,是一个model。线性回归模型和神经网络模型,这才可以视作2个不同的model。
曾经应该这样做过,将数据集的80%用作training,剩下的20%用作testing。但是,当你选作testing的20%数据里包含有一些特别容易predict的数据点,或者包含了一些特别难predict的点,这时候该怎么办?我们可能得到的model就不是理想的model。但是这样你就说这个模型不合适,这样对这个模型来说不公平啊,你的test本来就很难预测对,这是你挑选数据的问题,不应该怪模型不好啊。
所以,当你做k-fold cross validation的时候,由一些训练集训练得到一个model,你是用未放入训练的数据集来测试这个model有多好。我们使用cross validation的目的是单纯的判断这个模型的好坏,不想受到因为数据集划分不合理导致我认为模型不好的影响。
所以,我们想要的是使用全部的数据用作训练和验证。接着上面80/20分割数据集的例子,我们使用5-fold cross validation,训练80%的数据5次,用20%的数据测试。因此,我们就使用了每个数据点来检测模型的好坏。这样才对模型来说是公平的。
但是cross validation的目的并不是构建出最终的model。我们并不使用这5个训练的模型实例来做实际的prediction。因为我们想要所有的数据来做训练,尽可能得到好的模型。cross validation的目的是检测各类模型哪个比较好,而不是为了检测一个模型的各种实例化哪个好。
现在,我们说我们有两个模型,一个是线性回归模型,另一个是神经网络模型。怎样说哪个模型比较好呢?我们可以做 k-fold cross-validation,看哪一个模型在test sets上表现的更好。每个模型都会有5个(默认)test结果,然后求平均值,比较判断哪个模型更好。但是,一旦我们使用cross-validation来选择一个更好表现的模型,我们要用所有的数据来训练模型,对linear regression model与neural network模型都要使用所有的数据集再强调一遍,我们并不使用在cross-validation时训练得到的具体的model instance来最为最终的predictive model。

看一下代码

# 交叉验证
# 基本思想就是将原始数据(dataset)进行分组,一部分做为训练集来训练模型,另一部分做为测试集来评价模型。
# 交叉验证的意义:https://blog.csdn.net/qq_39751437/article/details/85071395
# 交叉验证的意义:https://blog.csdn.net/u010167269/article/details/51340070
from sklearn import datasets
from sklearn.model_selection import  cross_val_predict   # 模型选择库
from sklearn import linear_model
from sklearn import datasets

import matplotlib.pyplot as plt
regressor = linear_model.LinearRegression()
boston = datasets.load_boston()
y = boston.target

predicted = cross_val_predict(regressor,boston.data,y,cv=10)
# cross_val_predict : https://www.cnblogs.com/lzhc/p/9175707.html
# 用来评价线性回归器用来房价回归到底好还是不好,而不是为了从10个线性回归器中选择一个好的线性回归器
# 采用的是k-fold cross validation的方法
# print(predicted.shape)  # (506,)
fig,ax =plt.subplots()  # fig, axes = plt.subplots(23):即表示一次性在figure上创建成2*3的网格,使用plt.subplot()只能一个一个的添加
ax.scatter(y,predicted,edgecolors=(0,0,0,))
ax.plot([y.min(),y.max()],[y.min(),y.max()],'k--',lw=4)
ax.set_xlabel("measured")
ax.set_ylabel("predicted")
plt.show()
# 交叉验证模型打分
# from sklearn import cross_validation train_test_split
from sklearn.model_selection import cross_val_score
print (cross_val_score(regressor,boston.data,y,cv=10))
# 采用的是k-fold cross validation的方法
# 默认算的就是r-squared系数  值为多少好?https://blog.csdn.net/weixin_43715458/article/details/94405046
# R2:反映的是,模型本身对于自变量和因变量的反映,而损失函数是反映两种模型的好坏

【机器学习sklearn实战】线性回归器
得到的交叉验证的分数:

[ 0.73376082  0.4730725  -1.00631454  0.64113984  0.54766046  0.73640292
  0.37828386 -0.12922703 -0.76843243  0.4189435 ]

如果还有其他模型,可以也看一看分数,然后比较哪个模型好,就选择哪个模型。