上几节讲述了真实数据集在回归问题以及分类问题上的总流程,但是对于模型的选择及参数的选择仍然一知半解,因此本节开始讲述关于模型的一些知识,本节会略过一些比较基础的知识,将一些较为深入的知识。如果在哪个方面没有看懂,可以在网上查询,网上基础资料也比较多,也可以在下方评论。
五、训练模型
1、线性模型
线性模型形如:
Normal Equation
使用数学方法推导能直接求得参数θθ的方法为Normal Equation。而对于线性模型,数学方法为:最小二乘法。
通过最小二乘法能直接得到线性模型:
import numpy as np X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1) from sklearn.linear_model import LinearRegression lin_reg = LinearRegression() lin_reg.fit(X, y) lin_reg.intercept_, lin_reg.coef_
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
可以看到得到的结果接近4和3,没有达到准确值是由于加入了随机噪声的原因。
XTXXTXO(n2.4)O(n3)
梯度下降法(Gradient Descent)
Batch Gradient Descent
Batch Gradient Descent即每次迭代使用所有样本计算梯度,取平均,来更新参数。可以看到这个方法能直接朝着最优解方向前进。
eta = 0.1 # learning rate n_iterations = 1000 m = 100 theta = np.random.randn(2,1) # random initialization X_b = np.c_[np.ones((100, 1)), X] for iteration in range(n_iterations): gradients = 2/float(m) * X_b.T.dot(X_b.dot(theta) - y) theta = theta - eta * gradients
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
Stochastic Gradient Descent
随机梯度下降skicit-learn也有对应的函数:其中n_iter为迭代次数,eta0为学习率,penalty下面会说到。
from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(n_iter=50, penalty=None, eta0=0.1) sgd_reg.fit(X, y.ravel()) sgd_reg.intercept_, sgd_reg.coef_
- 1
- 2
- 3
- 4
Mini-batch Gradient Descent
2、多项式模型
m = 100 X = 6 * np.random.rand(m, 1) - 3 y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1) from sklearn.preprocessing import PolynomialFeatures poly_features = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly_features.fit_transform(X) X[0],X_poly[0]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
可以看到,通过PolynomialFeatures以后,得到新的特征(x,x2)(x,x2),再用这个新特征训练一个线性模型。
lin_reg = LinearRegression() lin_reg.fit(X_poly, y)
- 1
- 2
注:若存在两个特征a和b,若degree=2时,不仅增加了a2a2和b2b2,还有abab
Learning Curves
import matplotlib.pyplot as plt from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split def plot_learning_curves(model, X, y): X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2) train_errors, val_errors = [], [] for m in range(1, len(X_train)): model.fit(X_train[:m], y_train[:m]) y_train_predict = model.predict(X_train[:m]) y_val_predict = model.predict(X_val) train_errors.append(mean_squared_error(y_train_predict, y_train[:m])) val_errors.append(mean_squared_error(y_val_predict, y_val)) plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="train") plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="val") plt.xlabel("Training set size") plt.ylabel("RMSE") lin_reg = LinearRegression() plot_learning_curves(lin_reg, X, y)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
from sklearn.pipeline import Pipeline polynomial_regression = Pipeline(( ("poly_features", PolynomialFeatures(degree=10, include_bias=False)), ("sgd_reg", LinearRegression()), )) plot_learning_curves(polynomial_regression, X, y) plt.ylim(0,2)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3、正则化线性模型(Regularized Linear Models)
为了防止过拟合,可以给模型损失函数(如均方误差)增加正则项。
Ridge Regression(L2正则化)
Ridge Regression的损失函数为:
θθ靠近0,直观上可以理解为对MSE(θ)MSE(θ)(即模型)贡献越小的θθ,惩罚越大,这样的θθ越小,所以通过正则化能够减小这些无关特征带来的影响。
需要注意的是:在Ridge Regression之前要先对特征进行缩放(标准化或最大最小缩放),这是因为Ridge Regression对特征的尺度大小很敏感。
对应的代码为
from sklearn.linear_model import Ridge ridge_reg = Ridge(alpha=1, solver="cholesky") ridge_reg.fit(X, y)
- 1
- 2
- 3
随机梯度下降L2正则化对应的代码为
from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(penalty="l2") sgd_reg.fit(X, y.ravel())
- 1
- 2
- 3
αα值,可以看到通过正则化后曲线变得平缓,看起来比没有正则化的曲线有着更好的泛化推广能力。
Lasso Regression(L1正则化)
#最小二乘LASSO方法 from sklearn.linear_model import Lasso lasso_reg = Lasso(alpha=0.1) lasso_reg.fit(X, y) #随机梯度下降正则化L2(线性) from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(penalty="l1") sgd_reg.fit(X,