实验要求

  1. 调试并理解回归示例的源代码实现regression.py。掌握其中的datasets.make_regression函数和np.random.normal函数。并生成500个1维的回归数据,以及100个噪声点,作为数据集。
  2. 使用train_test_split函数将数据集划分为训练集和测试集(8:2),使用一元线性回归和一元二次多项式回归对数据进行拟合。
  3. 使用sklearn.metrics模块中的r2_score函数计算R方确定系数。
  4. 将测试样本和回归曲线进行可视化。
  5. 在测试集上分别测试一元线性回归和一元二次多项式回归,并使用sklearn.metrics的mean_squared_error函数计算预测值和实际值之间的平均平方误差MSE。

实验代码

引入库

import numpy as np
from matplotlib import pyplot as plt
from sklearn import linear_model, datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score, mean_squared_error

设置噪声和样本数

n_samples = 500 #样本数
n_outliers = 100 #噪声数

生成回归模型数据

# 构造数据集  sample为样本数 feature为X维度 informative为y维度  noise为数据之间的间隔,高斯噪声
# coef为系数  random_state是否随机,none的时候随机,参数相当于标记,使得标记相同的时候产生的数据一样
X, y, coef = datasets.make_regression(n_samples=n_samples, n_features=1,
                                      n_informative=1,bias = 0, noise=10,
                                      coef=True, random_state=0)
#x的shape(500,1)  y的shape(500,)

bias

bias:偏差(截距)

bias0150
图片
plt.scatter(X,y) #显示生成的回归模型
plt.show()


生成噪声点

np.random.seed(0) #随机数种子,参数表示随机数起始的位置,使得每次生成的噪声点位置一样,使得X,y的生成规律一样
X[:n_outliers] = 3 + 0.5 * np.random.normal(size=(n_outliers, 1)) #正态分布,size表示生成(n_outlier, 1)的数组
y[:n_outliers] = -3 + 10 * np.random.normal(size=n_outliers) #截取的是前100个数
#3+0.5是让数据点的横坐标以3为中心呈现正态分布,0.5取值是因为横坐标的差值小
plt.scatter(X,y) #显示生成添加了噪声的回归模型
plt.show()


对样本进行划分

#train_test_split函数用于将矩阵随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签。
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=0)
#划分好训练集和测试集的样本
fig = plt.figure()
train = fig.add_subplot(121)
test = fig.add_subplot(122)
train.set_title('train')
train.scatter(X_train,y_train)
test.set_title('test')
test.scatter(X_test,y_test)
plt.show()

一元线性回归

lr = linear_model.LinearRegression()# 创建一个LinearRegression模型
lr.fit(X_train, y_train) #训练集上训练一个线性回归模型

line_X = np.arange(X_train.min(), X_train.max())[:, np.newaxis] #增加维度,见下方。作用是平均取点,使得直线更加的直
#一元线性训练集预测
line_trainy = lr.predict(line_X) #以LinearRegression的模型预测y
plt.scatter(X_train, y_train, color='gold', marker='.')
plt.plot(line_X, line_trainy, color='navy')
plt.xlabel("Input")
plt.ylabel("Response")
plt.show()

y_train = bias + coef*X_train
最小二乘法

ransac = linear_model.RANSACRegressor( base_estimator = linear_model.LinearRegression(),#base_estimator 仅限于回归估计,默认LinearRegression
                                      min_samples = 10,residual_threshold = 25.0,stop_n_inliers = 320,#最小样本  残差  内集阈值
                                      max_trials = 100,random_state = 0)# 迭代次数
ransac.fit(X_train, y_train)                                             
inlier_mask = ransac.inlier_mask_
outlier_mask = np.logical_not(inlier_mask)#自动识别划分内点集和外点集
line_y_train_ransac = ransac.predict(line_X)

plt.scatter(X_train[inlier_mask], y_train[inlier_mask], color='yellowgreen', marker='.')
plt.scatter(X_train[outlier_mask], y_train[outlier_mask], color='gold', marker='.')
plt.plot(line_X, line_y_train_ransac, color='cornflowerblue',label='RANSAC regressor')
plt.xlabel("Input")
plt.ylabel("Response")
plt.show()

  • 随机选择n个样本点(n是人为指定的模型所需最小样本点数量);
  • 根据这些样本得出回归模型;
  • 根据上一步得到的模型计算所有样本点的残差(residual),将残差小于预设残差阈值的点归为inlier,其余是outlier;(残差为真实值与预测值的差)
  • 判断inlier数量是否达到预设的样本数阈值,如果达到则说明模型足够合理,如果未达到则重复上述步骤。
#初始化二次多项式生成器
poly2 = PolynomialFeatures(degree=2)#设置多项式阶数为2
X_train_poly2 = poly2.fit_transform(X_train)#用fit_transform将X_train变成2阶

#一元二次多项式回归
lr2 = linear_model.LinearRegression()
lr2.fit(X_train_poly2,y_train)

X_train_poly1=poly2.fit_transform(line_X)
#一元二次多项式训练集预测
line2_trainy = lr2.predict(X_train_poly1)

plt.scatter(X_train, y_train, color='gold', marker='.')
plt.plot(line_X, line2_trainy, color='navy')

plt.show()

plt.scatter(X_train[inlier_mask], y_train[inlier_mask], color='yellowgreen', marker='.',label='Inliers')
plt.scatter(X_train[outlier_mask], y_train[outlier_mask], color='gold', marker='.',label='Outliers')
plt.plot(line_X, line_trainy, color='navy',label='Line_degree1')
plt.plot(line_X, line_y_train_ransac, color='cornflowerblue',label='RANSAC regressor')
plt.plot(line_X, line2_trainy, color='red',label='Line_degree2')
plt.legend(loc='lower right')
plt.xlabel("Input")
plt.ylabel("Response")
plt.show()

line1 = lr.predict(X_train)
line_ransac = ransac.predict(X_train)
line2 = lr2.predict(X_train_poly2)
#利用sklearn.metrics模块中的r2_score函数计算R方确定系数
print("LinearRegression之一元线性train的R方系数:")
print(r2_score(y_train,line1))
print("RANSACRegressor之一元线性train的R方系数:")
print(r2_score(y_train,line_ransac))
print("LinearRegression之一元二次多项式train的R方系数:")
print(r2_score(y_train,line2))


#利用sklearn.metrics模块中的mean_squared_error函数计算均方误差 真实值与预测值之间的差的平方求平均
print("LinearRegression之一元线性train的MSE:")
print(mean_squared_error(y_train,line1))
print("RANSACRegressor之一元线性train的MSE:")
print(mean_squared_error(y_train,line_ransac))
print("LinearRegression之一元二次多项式train的MSE:")
print(mean_squared_error(y_train,line2))
回归模型R方系数均方误差
LinearRegression之一元线性0.33536843833620091175.5447139156627
RANSACRegressor之一元线性-1.36715780238227814186.830722616691
LinearRegression之一元二次多项式0.7334945258284558471.3725911656628

Last modification:July 1st, 2020 at 05:03 pm
如果觉得我的文章对你有用,请随意赞赏