在上一篇讲了最小二乘法实现线性回归的原理,实现方面用的是python的static.optimize中的leastsq求出拟合函数。本篇通过sklearn库中的模块来进行拟合和线性回归,并计算拟合误差。
对于线性回归来说,无论是用什么工具实现,步骤都是大同小异的:
from sklearn.pipeline import Pipeline
clf = PolynomialFeatures(degree=3)
其中,degree参数为多项式的阶数
from sklearn import linear_model
clf = linear_model.LinearRegression()
在线性回归预测过程中,可能会出现过拟合、欠拟合等现象,使模型预测效果或表现效果下降,此时需要调整参数,常见的做法是在损失函数后加上惩罚项。
lasso = linear_model.Lasso(alpha=0.0001)
lassocv = linear_model.LassoCV(alphas=[0.0001, 0.01, 0.1, 1])
ridge = linear_model.Ridge(alpha=0.0001)
ridgecv= linear_model.RidgeCV (alphas=[0.0001, 0.01, 0.1, 1])
elasticNet = linear_model.ElasticNet()
elasticNetcv = linear_model.ElasticNetCV()
在本次拟合中,还用到了Pipeline构建工作流,对模型进行统一封装管理。
from sklearn.pipeline import Pipeline
clf = Pipeline(steps=[('name1': transform1), ('name2': transform2)
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn import linear_model
import scipy as sp
from scipy.stats import norm
import matplotlib.pyplot as plt
""" 标准误差 """
def stdError_func(y_test, y):
return np.sqrt(np.mean((y_test-y)**2))
def R2_1_func(y_test, y):
return 1-((y_test-y)**2).sum() / ((y.mean() - y)**2).sum()
def R2_2_func(y_test, y):
y_mean = np.array(y)
y_mean[:] = y.mean()
return 1 - stdError_func(y_test, y) / stdError_func(y_mean, y)
x = np.linspace(0, 1, 500)
y = norm.rvs(loc=0, size=500, scale=0.1) ##生成随机分布, 增加抖动(噪声)
y = y + x**6
plt.scatter(x, y, s=5, color='black', alpha=0.8)
degrees = [2, 10, 200, 400]
for degree in degrees:
clf = Pipeline([('poly', PolynomialFeatures(degree=degree)),
('linear', linear_model.LinearRegression(fit_intercept=False))])
clf.fit(x[:, np.newaxis], y) ## 自变量需要二维数组
predict_y = clf.predict(x[:, np.newaxis])
strError = stdError_func(predict_y, y)
R2_1 = R2_1_func(predict_y, y)
R2_2 = R2_2_func(predict_y, y)
score = clf.score(x[:, np.newaxis], y) ##sklearn中自带的模型评估,与R2_1逻辑相同
print 'degree={}: strError={:.2f}, R2_1={:.2f}, R2_2={:.2f}, clf.score={:.2f}'.format(
degree, strError,R2_1,R2_2,score)
plt.plot(x, predict_y, linewidth=2, label=degree)
plt.legend()
plt.show()
由结果可知,当多项式的阶数逐渐增加时,模型的效果也逐渐增加。但当到达一定阶数时,再增加阶数对模型的提升效果不大,甚至会出现过拟合现象(如degree=400)。此时统计拟合函数中有效阶数:
sum(clf.named_steps['linear'].coef_ != 0)
输出结果为401,即一些畸形系数导致拟合曲线畸形化。
接下来分别通过Lasso法和岭回归对模型进行纠正,改写PileLine的工作流为:
clf = Pipeline([('poly', PolynomialFeatures(degree=degree)), ('linear', linear_model.Lasso())]) ##Lasso法
clf = Pipeline([('poly', PolynomialFeatures(degree=degree)), ('linear', linear_model.RidgeCV())]) ##岭回归