本小节内容:
开始的时候,是从三个方面介绍线性回归算法,分别是单变量,多变量,梯度下降。
由于之前这个已经记录过博客,在此就不加以赘述了,可以翻看以前的机器学习栏目中的博客,具体公式推导已经全部写了。
主要来讲一下如何利用线性回归算法去拟合正弦函数
首先我们要随机生成一些正弦函数上的点,然后再生成一些噪声点(不在正弦函数上的点),最后将这些点进行格式化成sklearn试用的点
然后用多阶函数去拟合这些点,最后算出评分,再将这些拟合的数据构建成一个二维的坐标图,直观的观测出拟合的效果
生成点并且格式数组
n_dots = 200
X = np.linspace(-2 * np.pi, 2 * np.pi, n_dots) # 生成200个正弦函数点
Y = np.sin(X) + 0.2 * np.random.rand(n_dots) - 0.1 # 生成一些随机点(噪声点)
X = X.reshape(-1, 1) # 格式化
Y = Y.reshape(-1, 1); # 格式化
多阶函数拟合模型
用pipeline把函数与函数弄在一起,可以在原有阶乘上增加特征矩阵(特征值)
具体的解释:
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
# 生成多项式模型
def polynomial_model(degree=1): # degree是阶乘的阶数
# PolynomialFeatures:生成一个新的特征矩阵
# 如果有a,b两个特征,那么它的2次多项式为(1,a,b,a^2,ab, b^2),这个多项式的形式是使用poly的效果。
# include_bias:默认为True。如果为True的话,那么就会有上面的 1那一项
polynomial_features = PolynomialFeatures(degree=degree,
include_bias=False)
# LinearRegression:普通最小二乘线性回归
# normalize=True是标准化
linear_regression = LinearRegression(normalize=True)
# 这个是一个流水线,先增加多项式的阶数,然后再用线性回归算法来拟合数据
pipeline = Pipeline([("polynomial_features", polynomial_features),
("linear_regression", linear_regression)])
return pipeline
开始拟合并算出score
算出2阶,3阶,5阶,10阶的函数,并算出score
和均方根误差mean_squared_error
,并依此输出
from sklearn.metrics import mean_squared_error
degrees = [2, 3, 5, 10]
results = []
for d in degrees:
model = polynomial_model(degree=d)
model.fit(X, Y)
train_score = model.score(X, Y)
mse = mean_squared_error(Y, model.predict(X))
results.append({"model": model, "degree": d, "score": train_score, "mse": mse})
for r in results:
print("degree: {}; train score: {}; mean squared error: {}".format(r["degree"], r["score"], r["mse"]))
看拟合效果
我们根据上面的数据,可以看出10阶的拟合效果是最好的,但是我们想更加直观的看出效果的话,可以将数据放入图像中直接拟合出来
from matplotlib.figure import SubplotParams
plt.figure(figsize=(12, 6), dpi=200, subplotpars=SubplotParams(hspace=0.3))
for i, r in enumerate(results):
fig = plt.subplot(2, 2, i+1)
plt.xlim(-8, 8)
plt.title("LinearRegression degree={}".format(r["degree"]))
plt.scatter(X, Y, s=5, c='b', alpha=0.5)
plt.plot(X, r["model"].predict(X), 'r-')
思考题
完整代码:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
n_dots = 1000
X = np.linspace(-20, 20, n_dots)
Y = np.sin(X) + 0.2 * np.random.rand(n_dots) - 0.1
X = X.reshape(-1, 1)
Y = Y.reshape(-1, 1);
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
# 生成多项式模型
def polynomial_model(degree=1): # degree是阶乘的阶数
# PolynomialFeatures:生成一个新的特征矩阵
# 如果有a,b两个特征,那么它的2次多项式为(1,a,b,a^2,ab, b^2),这个多项式的形式是使用poly的效果。
# include_bias:默认为True。如果为True的话,那么就会有上面的 1那一项
polynomial_features = PolynomialFeatures(degree=degree,
include_bias=False)
# LinearRegression:普通最小二乘线性回归
# normalize=True是标准化
linear_regression = LinearRegression(normalize=True)
# 这个是一个流水线,先增加多项式的阶数,然后再用线性回归算法来拟合数据
pipeline = Pipeline([("polynomial_features", polynomial_features),
("linear_regression", linear_regression)])
return pipeline
from sklearn.metrics import mean_squared_error
degrees = [2, 3, 5, 10, 13, 15, 18, 20, 21, 22, 23, 24]
results = []
for d in degrees:
model = polynomial_model(degree=d)
model.fit(X, Y)
train_score = model.score(X, Y)
mse = mean_squared_error(Y, model.predict(X))
results.append({"model": model, "degree": d, "score": train_score, "mse": mse})
for r in results:
print("degree: {}; train score: {}; mean squared error: {}".format(r["degree"], r["score"], r["mse"]))
from matplotlib.figure import SubplotParams
plt.figure(figsize=(12, 6), dpi=200, subplotpars=SubplotParams(hspace=0.3))
for i, r in enumerate(results):
fig = plt.subplot(4, 4, i+1)
plt.xlim(-8, 8)
plt.title("LinearRegression degree={}".format(r["degree"]))
plt.scatter(X, Y, s=5, c='b', alpha=0.5)
plt.plot(X, r["model"].predict(X), 'r-')
最后拟合图为: