前几天大管在文章中讲了回归和L2正则的一些知识点,今天上午有小伙伴问了一些问题并且问我有没有具体的python代码。这篇文章大管就和大家一起学习sklearn中封装好的代码。话不多说直接上代码:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
x_data = np.linspace(-0.5, 0.5, 200)
noise = np.random.normal(0, 0.02,x_data.shape)
y_data = np.square(x_data) + noise
plt.scatter(x_data,y_data)
为了拟合的需要,我们这里随机生成-0.5到0.5的200个点。在分别给这些点加上一些噪声(noise),噪声服从正态分布,并且形状和x_data的形状相同。生成标签y_data,这里的y_data由二次函数加上噪声生成。把这些点打印出来,如下所示:
任务: 拟合上述图中的点:
x_data = x_data.reshape(-1,1)
y_data = y_data.reshape(-1,1)
model = LinearRegression() # 线性回归
model.fit(x_data,y_data)
y_pre = model.predict(x_data)
t = np.arange(len(x_data))
print(model.coef_)
print(model.intercept_)
print(model.score(x_data ,y_data))
plt.plot(x_data,y_pre,color='r')
plt.scatter(x_data, y_data)
plt.show()
上述代码是第一版,直接调用了LinearRegression()函数,最后得到的权重和偏置以及准确率分别是:[0.00212001],[0.08596897]
6.385135765107908e-05,拟合效果如下图。可以说效果是非常非常差了,是哪里出的问题呢?很明显,我用了一次函数来拟合这幅图,而且从权重也可以看出只输出了一个权重。
下面我们要对代码进行调整,调整容量即使用二次函数来进行拟合。
x_data = x_data.reshape(-1,1)
y_data = y_data.reshape(-1,1)
X2 = np.hstack([x_data ** 2, x_data])
print(X2.shape)
model = LinearRegression() # 线性回归
model.fit(X2,y_data)
y_pre = model.predict(X2)
t = np.arange(len(x_data))
print(model.coef_)
print(model.intercept_)
print(model.score(X2 ,y_data))
plt.plot(x_data,y_pre,color='r')
plt.scatter(x_data, y_data)
plt.show()
上述代码中我们对函数进行了调整,用二次函数来拟合。X2 = np.hstack([x_data ** 2, x_data])这一行语句的作用是给x增加一个x2的维度,我们输出X2.shape可以查看其形状:(200, 2)。运行的结果权重和偏置以及准确率分别是:[[ 0.98783197 -0.00478873]],[0.00193266]
0.9259385587912184。可以看到权值变成了两个,准确率也有了很大的提升92.6%。拟合的结果如下图:
下面我们加上正则试一下效果怎么样:
x_data = x_data.reshape(-1,1)
y_data = y_data.reshape(-1,1)
X2 = np.hstack([x_data ** 2, x_data])
print(X2.shape)
model = Lasso(alpha=0.00015) # Lasso回归
model.fit(X2,y_data)
y_pre = model.predict(X2)
t = np.arange(len(x_data))
print(model.coef_)
print(model.intercept_)
print(model.score(X2 ,y_data))
plt.plot(x_data,y_pre,color='r')
plt.scatter(x_data, y_data)
plt.show()
上述代码中,我们使用了Lasso回归来进行拟合即在线性拟合的基础上加了L1正则,进过我简单的参数调整,输出权重和偏置以及准确度如下:
[ 0.96005504 -0. ],[0.00332775],0.9416392990521868。
可以看到这里x一次方的权重为0,但是保留了二次项的系数,并且准确率也提升到了94.2%。拟合的效果如下图:
关于alpha参数,大家可以自己尝试着调整,使准确率更高。
下面使用Ridge回归(岭回归)即前几篇文章中提到的L2正则来尝试一下效果如何:
model = Ridge(alpha=0.0015,solver='auto') # 岭回归,L2正则
这里我们把alpha参数调整为0.0015,输出的权重和偏重以及准确率如下:
[[1.01953883 0.00491386]],[-0.00274412],0.944999419097183。
准确率为94.5%。