失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 梯度下降法实战案例(波士顿房价)

梯度下降法实战案例(波士顿房价)

时间:2019-12-24 23:24:14

相关推荐

梯度下降法实战案例(波士顿房价)

本次实战思路是先找到波士顿房价数据中与房价有较强相关性的一列数据,通过梯度下降法找合适的参数,拟合出这列数据与房价的线性关系。

直接上代码

from sklearn.datasets import load_bostonimport matplotlib.pyplot as pltimport pandas as pdimport seaborn as snsimport numpy as npimport random%matplotlib inline

dataset = load_boston()#导入数据集dataframe = pd.DataFrame(dataset['data'])#将数据转成DataFrame格式dataframe.columns = dataset['feature_names']#添加列索引dataframe#打印数据

dataframe['price'] = dataset['target']#增加“price”列dataframe.head()

sns.heatmap(dataframe.corr(), annot=True, fmt='.1f')#根据相关系数画出热力图,其中越接近1说明这两列数据正相关性越强

基于以上分析,卧室数量和房价正相关较强,我们可以根据卧室数量估计房子价格。

X_rm = dataframe['RM'].valuesY = dataframe['price'].valuesrm_to_price = {r: y for r, y in zip(X_rm, Y)}rm_to_price

可以把卧室数量作为字典的键,房价作为值。用键查找值,假如字典中没有要查询的卧室数量,就会报错。

第一种方法:用K-NN算法思想估计出卧室数量与房价的对应关系

#topn:邻居数量def knn(history_price, query_x, topn=3):#找出与query_x距离最近的topn个卧室数量most_similar_items = sorted(history_price.items(), key=lambda e:(e[0] - query_x)**2)[:topn]#找出对应的房子价格most_similar_prices = [price for rm, price in most_similar_items]#求出价格的平均值作为输出结果average_prices = np.mean(most_similar_prices)return average_prices

进行测试

#7个个卧室的房价大约是29.23334knn(rm_to_price, 7)

#画出卧室数量与房价的散点图 plt.scatter(X_rm, Y)

散点图给我们提供了另外一种思路,将X_rm和Y拟合成一条直线,找到合适的k和b,我们只需把卧室数量作为变量输入,即可输出得到房价。

第二种方法:拟合线性函数

损失函数

Loss(k,b)=1n∑i∈N(yi^−yi)2Loss(k, b) = \frac{1}{n} \sum_{i \in N} (\hat{y_i} - y_i) ^ 2 Loss(k,b)=n1​i∈N∑​(yi​^​−yi​)2

Loss(k,b)=1n∑i∈N((k∗rmi+b)−yi)2Loss(k, b) = \frac{1}{n} \sum_{i \in N} ((k * rm_i + b) - y_i) ^ 2 Loss(k,b)=n1​i∈N∑​((k∗rmi​+b)−yi​)2

对k求偏导

∂loss(k,b)∂k=2n∑i∈N(k∗rmi+b−yi)∗rmi\frac{\partial{loss(k, b)}}{\partial{k}} = \frac{2}{n}\sum_{i \in N}(k * rm_i + b - y_i) * rm_i ∂k∂loss(k,b)​=n2​i∈N∑​(k∗rmi​+b−yi​)∗rmi​

对b求偏导

∂loss(k,b)∂b=2n∑i∈N(k∗rmi+b−yi)\frac{\partial{loss(k, b)}}{\partial{b}} = \frac{2}{n}\sum_{i \in N}(k * rm_i + b - y_i)∂b∂loss(k,b)​=n2​i∈N∑​(k∗rmi​+b−yi​)

#损失函数,在这里用的是MSEdef loss(y, yhat):return np.mean(np.array(y) - np.array(yhat) ** 2)#代入k和b,返回预测结果def model(x, k , b):return x * k + b#对k求偏导def partial_k(x, y, k, b):return 2 * np.mean((y - (k * x + b)) * (-x))#为什么是负值#对b求偏导def partial_b(x, y, k, b):return 2 * np.mean((y - (k * x + b)) * (-1))

梯度下降过程:

在微积分中,对多元函数的参数求偏导数,求得参数的偏导数以向量形式表达就是梯度。如图所示,θ₀到θ₁的距离为θ₀在函数L(θ)上的梯度,记做∂L/∂θ

在数学上,梯度越大,则函数的变化越大。对于函数L(θ)在点θ₀处,梯度向量∂L/∂θ的方向就是函数L(θ)增加最快的方向。也就是说,沿着梯度向量的方向易于找到函数的最大值。反之亦然,沿着梯度向量相反的方向,梯度减少最快,易于找到函数的最小值。

假设函数L(θ)为损失函数,为了找到损失函数的最小值,需要沿着与梯度向量相反的方向 -∂L / ∂θ更新变量θ,这样可以使梯度减少最快,直到损失收敛至最小值。其基本公式:

θ←θ−η∂L∂θθ ← θ - η\dfrac{∂L}{∂θ}θ←θ−η∂θ∂L​

其中,η∈R为学习率,用于控制梯度下降的幅度(快慢)。看上图,梯度下降算法每次计算参数θₓ在当前位置的梯度,然后让参数θₓ顺着梯度的反方向前进一段距离,不断重复该过程。直到梯度接近于零的时候,算法认为找到了损失函数L(θ)的最小值并停止计算。此时可以认为参数θ*恰好到达让损失函数位于最小值的状态。

VAR_MAX, VAR_MIN = 100, -100#k、b随机取值范围k, b = random.random(), random.random()min_loss = float('inf')best_k, best_b = None, Nonetotal_times = 5000#迭代次数alpha = 1e-2#学习率k_b_history = []for t in range(total_times):#梯度下降法找k、b的值k = k + (-1) * partial_k(X_rm, Y, k, b) * alphab = b + (-1) * partial_b(X_rm, Y, k, b) * alphaloss_ = loss(Y, model(X_rm, k, b))if loss_ < min_loss:min_loss = loss_best_k, best_b = k, bk_b_history.append((best_k, best_b))#print('在{}时刻 我找到了更好的k:{}和b:{}, 这个时候的loss是{}'.format(t, k, b, loss_))

把结果print一下,可以看到几乎在每一个时刻的损失函数值都比上一时刻的更优,说明使用梯度下降法是有效的。

#打印最终的损失函数值min_loss

#查看拟合效果plt.scatter(X_rm, Y)plt.plot(X_rm, best_k * X_rm + best_b, 'yo')

比较两种方法用时

%%timemodel(6, best_k, best_b)

%%timeknn(rm_to_price, 6)

事实证明第二种方法比第一种快将近一百万倍!!!

有人会提出来说训练模型的耗时不算嘛?但是相对于knn每次用时那么久,训练出模型一劳永逸就太香了。

本次实战到这里就结束了,假如有喜欢可视化的同学可以透视一下训练过程。

#透视拟合过程#选取某几个范围内的时刻test_0 = 0test_1 = 10test_2 = 100test_3 = 5000test_4 = -1plt.scatter(X_rm, Y)plt.scatter(X_rm, k_b_history[test_0][0] * X_rm + k_b_history[test_0][1], color='red')plt.scatter(X_rm, k_b_history[test_1][0] * X_rm + k_b_history[test_1][1])plt.scatter(X_rm, k_b_history[test_2][0] * X_rm + k_b_history[test_2][1])plt.scatter(X_rm, k_b_history[test_3][0] * X_rm + k_b_history[test_3][1])plt.scatter(X_rm, k_b_history[test_4][0] * X_rm + k_b_history[test_4][1])

完!

如果觉得《梯度下降法实战案例(波士顿房价)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。