1 多变量线性回归应用场景目前为止,我们探讨了单变量/特征的回归模型,现在我们对房价模型增加更多的特征,例如房间数楼层等,构成一个含有多个变量的模型.。1.1 单变量线性回归案例模型: h(x) = 0 + 1x1.2 多变量线性回归案例模型:新的概念例如: x(1) = [40, 1, 1, 10] x(2) = [96, 2, 1, 5] x(3) = [135, 3, 2, 20]例如:x(1)1 = 40x(1)2 = 1…….2 多元梯度下降法模型:参数:损失函数:梯度下降公式(重复执行):2.1 一元梯度下降n=1, 重复执行,直到收敛2.2 多元梯度下降n>12.3 多元批梯度下降代码import numpy as np# 1). 模拟数据X1 = 2 * np.random.randn(100, 1)X2 = 4 * np.random.rand(100, 1)X3 = 6 * np.random.rand(100, 1)y = 4 + 3 * X1 + 4 * X2 + 5 * X3 + np.random.randn(100, 1)# 2). 实现梯度下降算法# np.c_是将数据组合成向量格式: (n, 1) (n,1) = (n, 2)X_b = np.c_[np.ones((100, 1)), X1, X2, X3]# 初始化theta的值, 需要计算四个theta的值;theta = np.random.randn(4, 1)# 设置学习率和收敛次数learning_rate = 0.1n_iterations = 1000# 根据公式计算for iteration in range(n_iterations): # 梯度下降公式 = 1/样本数 * (预测值 - 真实值) Xi gradients = 1 / 100 * X_b.T.dot(X_b.dot(theta) - y) # theta = theta - 学习率 * 梯度值 theta = theta - learning_rate * gradientsprint(theta)代码执行结果:3 梯度下降法实践一:特征缩放3.1 梯度下降法遇到的问题在我们面对多维特征问题的时候,我们要保证这些特征都具有相近的尺度,这将帮助梯度下降算法更快地收敛。而特征缩放是为了确保特征在一个数量级上。 以房价问题为例,假设我们使用两个特征,房屋的尺寸和房间的数量,其中x1 = 房屋面积(0-400 m2), x2 = 卧室数量(1-5), 以两个参数分别为横纵坐标,绘制代价函数的等高线图能,看出图像会显得很扁,梯度下降算法需要非常多次的迭代才能收敛。3.2 解决方法解决方法一:尝试将所有特征的尺度都尽量缩放到-1到1之间。比如:x1 = 房屋面积 / 400x2 = 卧室数量 / 5解决方法二: 平方均值法在原来的基础上把特征 xi 替换成 xi – ;也可以把最大值换成标准差,或者最大值 – 最小值。4 梯度下降法实践二: 学习率4.1 梯度下降法遇到的问题梯度下降算法收敛所需要的迭代次数根据模型的不同而不同,我们不能提前预知,我们可以绘制迭代次数和代价函数的图表来观测算法在何时趋于收敛。梯度下降算法的每次迭代受到学习率的影响,如果学习率过小,则达到收敛所需的迭代次数会非常高;如果学习率过大,每次迭代可能不会减小代价函数,可能会越过局部最小值导致无法收敛。4.2 解决方法自动测试是否收敛的方法,例如将代价函数的变化值与某个阀值(例如0.001)进行比较,但通常看上面这样的图表更好。尝试在如下的数值中选择 : …, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1,…5 梯度下降算法补充5.1 三种梯度下降总结如何选择?训练集比较小: 使用批梯度下降(小于2000个)训练集比较大:使用Mini-bitch梯度下降 一般的Mini-batch size 是64,128,256, 512,1024, Mini-batch size要适用CPU/GPU的内存5.2 随机梯度下降随机梯度下降思想:把m个样本分成m份,每次用1份做梯度下降;也就是说,当有m个样本时,批梯度下降只能做一次梯度下降,但是随机梯度下降可以做m次。实现代码import numpy as npimport randomX = 2 * np.random.rand(100, 1)Y = 4 + 3 * X + np.random.randn(100, 1)X_b = np.c_[np.ones((100, 1)), X]# 每轮epochs处理m个样本;n_epochs = 1000# 学习率a0 = 0.1# 定义衰减率decay_rate = 1def learning_schedule(epoch_num): """ 定义一个学习率衰减的函数 """ return (1.0 / (decay_rate * epoch_num + 1)) * a0# 初始化theta值theta = np.random.randn(2, 1)# 初始化随机值num = [i for i in range(100)]m = 100for epoch in range(n_epochs): rand = random.sample(num, 100) for i in range(m): random_index = rand[i] xi = X_b[random_index:random_index + 1] yi = Y[random_index:random_index + 1] # 随机梯度下降值 gradients = xi.T.dot(xi.dot(theta) - yi) # 学习率 learning_rate = learning_schedule(epoch+1) theta = theta - learning_rate * gradientsprint(theta)执行结果展示:5.3 Mini-batch梯度算法随机梯度下降会丧失向量带来的加速,所以我们不会太用随机梯度下降。实现代码import numpy as npimport randomX = 2 * np.random.rand(100, 1)y = 4 + 3 * X + np.random.randn(100, 1)X_b = np.c_[np.ones((100, 1)), X]# print(X_b)n_epochs = 500a = 0.03m = 100num = [i for i in range(100)]theta = np.random.randn(2, 1)batch_num = 5batch_size = m // 5# epoch 是轮次的意思,意思是用m个样本做一轮迭代for epoch in range(n_epochs): # 生成100个不重复的随机数 for i in range(batch_num): start = ibatch_size end = (i+1)batch_size xi = X_b[start:end] yi = y[start:end] gradients = 1/batch_size * xi.T.dot(xi.dot(theta)-yi) print(a) learning_rate = a theta = theta - learning_rate * gradientsprint(theta)执行结果展示:5.4 Mini-batch梯度算法优化: 学习率衰减在做Mini-batch的时候,因为噪声的原因,可能训练结果不是收敛的,而是在最低点周围晃动,如果我们要解决这个问题,那我们就需要减少学习率,让他在尽量小的范围内晃动1 epoch = 1 次遍历所有的数据学习率衰减公式:实现代码import numpy as npimport randomX = 2 * np.random.rand(100, 1)y = 4 + 3 * X + np.random.randn(100, 1)X_b = np.c_[np.ones((100, 1)), X]# print(X_b)n_epochs = 500t0, t1 = 5, 50m = 100num = [i for i in range(100)]def learning_schedule(t): return float(t0) / (t + t1)theta = np.random.randn(2, 1)batch_num = 5batch_size = m // 5# epoch 是轮次的意思,意思是用m个样本做一轮迭代for epoch in range(n_epochs): # 生成100个不重复的随机数 for i in range(batch_num): start = ibatch_size end = (i+1)batch_size xi = X_b[start:end] yi = y[start:end] gradients = 1/batch_size * xi.T.dot(xi.dot(theta)-yi) learning_rate = learning_schedule(epochm + i) theta = theta - learning_rate * gradientsprint(theta)执行结果展示:6 特征和多项式回归6.1 过拟合的问题过拟合的问题出现在变量()过多的时候,这时候我们没有更多的数据去拟合模型,虽然损失函数的值基本接近于0。6.2 过拟合的解决方法:减少特征的数量(一般不用) 1)手动选择特征数2)模型选择正则化(特征缩放) 保留所有特征,但是减少量级或者参数_j的大小6.2 特征缩放房价预测时, 假设我们不知道房屋面积,但是知道房屋的长宽。 模型设计: h(x) = 0 + 1 x 房屋的长度 + 2 x 房屋的宽度特征未缩放图形展示特征缩放图形展示注:如果我们采用多项式回归模型,在运行梯度下降算法前,特征缩放非常有必要。6.3 正则化如何不想要theta3和theta4?首先, 我们可以在损失函数中,加入关于theta3和theta4的项, 迫使若损失函数想要最小化, 必须让theta3和theta4尽可能的小。然后正则化, 公式如下图:6.4 L1 正则和 L2 正则的区别L1 会趋向于减少特征值L2 会趋向于保留特征值7 正则化算法与代码实现7.1 Ridge(岭)回归7.1.1 算法理解7.1.2 实现公式7.1.3 代码实现两种实现岭回归的方法:“““岭回归方法一: 岭回归运用了L2正则化”““import numpy as npfrom sklearn.linear_model import Ridgefrom sklearn.linear_model import SGDRegressorX = 2 * np.random.rand(100, 1)y = 4 + 3 * X + np.random.randn(100, 1)# alpha是惩罚项里的alpha, solver处理数据的方法,auto是根据数据自动选择,svd是解析解,sag就是随机梯度下降ridge_reg = Ridge(alpha=1, solver=‘auto’)# 学习过程ridge_reg.fit(X, y)# 预测print(ridge_reg.predict([[1.5], [2], [2.5]]))# 打印截距print(ridge_reg.intercept_)# 打印系数print(ridge_reg.coef_)“““方法二: 岭回归和sgd & penalty=2是等价的”““sgd_reg = SGDRegressor(penalty=‘l2’)sgd_reg.fit(X, y.ravel())print(sgd_reg.predict([[1.5], [2], [2.5]]))# 打印截距print(“W0=”, sgd_reg.intercept_)# 打印系数print(“W1=”, sgd_reg.coef_)7.2 Lasso(拉索)回归7.2.1 算法理解7.2.2 实现公式7.2.3 代码实现”““Lasso 回归Lasso用的是l1的正则化”““import numpy as npfrom sklearn.linear_model import Lassofrom sklearn.linear_model import SGDRegressorX = 2 * np.random.rand(100, 1)y = 4 + 3 * X + np.random.randn(100, 1)lasso_reg = Lasso(alpha=0.15)lasso_reg.fit(X, y)print(lasso_reg.predict([[1.5]]))print(lasso_reg.coef_)sgd_reg = SGDRegressor(penalty=‘l1’, n_iter=1000)sgd_reg.fit(X, y.ravel())print(sgd_reg.predict([[1.5]]))print(sgd_reg.coef_)7.3 Elastic Net回归7.3.1 算法理解7.3.2 实现公式7.3.3 代码实现import numpy as npfrom sklearn.linear_model import ElasticNetX = 2 * np.random.rand(100, 1)Y = 4 + 3 * X + np.random.randn(100, 1)elastic_reg = ElasticNet(alpha=0.15, l1_ratio=0.5)elastic_reg.fit(X, Y)print(elastic_reg.predict([[1.5]]))print(elastic_reg.coef_)print(elastic_reg.intercept_)from sklearn.linear_model import SGDRegressorelastic_reg = SGDRegressor(penalty=‘elasticnet’)elastic_reg.fit(X, Y)print(elastic_reg.predict([[1.5]]))print(elastic_reg.coef_)8 正规方程和梯度下降比较梯度下降:需要选择合适的需要多次迭代当n很大时,效果很好正规方程:不需要选择学习率a不需要迭代需要计算X的转置乘X整体的逆当n很大时,计算很慢总结:根据经验,当特征数量到10000的时候,是会换成梯度下降比较好8.1 多项式回归的梯度下降代码import numpy as npimport matplotlib.pyplot as pltfrom sklearn.preprocessing import PolynomialFeaturesfrom sklearn.linear_model import LinearRegression# 1). 数据准备;# 样本数m = 100X = 6 * np.random.randn(m, 1) - 3Y = 0.5 * X ** 2 + X + 2 + np.random.randn(m, 1)# 2). 处理# 2-1). 将一个高阶方程转化为一个一阶方程;(多元线性回归)# degree:用几维处理数据;poly_features = PolynomialFeatures(degree=2, include_bias=False)# fit_transform === fit() + transform(), 其中transform就是用来做归一化的;X_poly = poly_features.fit_transform(X, Y)# 2-2). 处理一阶方程line_reg = LinearRegression()line_reg.fit(X_poly, Y)print(line_reg.coef_)print(line_reg.intercept_)8.2 不同维度绘制的图形import numpy as npimport matplotlib.pyplot as pltfrom sklearn.preprocessing import PolynomialFeaturesfrom sklearn.linear_model import LinearRegression# 1). 数据准备;# 样本数m = 100X = 6 * np.random.randn(m, 1) - 3Y = 7 * X ** 2 + 5 X + 2 + np.random.randn(m, 1)# plt.plot(X, Y, ‘b.’)# plt.show()# 设置图像维度及线条的字体显示d = {1: ‘g-’, 2: ‘r.’, 10: ‘y’}# d = {2: ‘g-’}for i in d: # 2). 处理 # 2-1). 将一个高阶方程转化为一个一阶方程;(多元线性回归) # degree:用几维处理数据; poly_features = PolynomialFeatures(degree=i, include_bias=False) # fit_transform === fit() + transform(), 其中transform就是用来做归一化的; X_poly = poly_features.fit_transform(X) print(X_poly) # 2-2). 处理一阶方程 line_reg = LinearRegression() line_reg.fit(X_poly, Y) print(line_reg.coef_) print(line_reg.intercept_) y_predict = line_reg.predict(X_poly) plt.plot(X_poly[:, 0], y_predict, d[i])plt.show()
...