需求: 58 租房网希望为房东用户提供一个建议租金功能, 当房东用户发布信息之前, 网站会提示他什么样的租金价位比较合理. 我们需要用机器学习算法从 58 租房以往的租房信息数据集中找到规律, 根据房东用户输入的各种信息计算得到一个合理的租金价位.
数据集
请参考这两个文章:
破解 58 租房 font-face 反爬虫加密
58 租房数据集 - pandas 存储 CSV
我们已经利用爬虫技术从 58 租房网站爬取到了数据, 并且存储到了 CSV 文件中, 其中包含了 4000 多条已有的租房信息.
请到百度网盘下载使用 58suzhou_zufang_4k.CSV 文件:
链接: https://pan.baidu.com/s/1PkjnKxNLWhnd2RBURTrs-w 密码: 5a9n.
由于上面两篇文章已经修正更新, 您自己爬取的文件可能与我这个不同, 所以强烈建议使用我这个.
将下载的数据集放到代码目录一起, 我们使用 Anaconda
的 JupyterNotebook 编写代码, 读取这个数据集:
- import pandas as pd
- csvfile='58suzhou_zufang_4k.csv'
- df=pd.read_csv(csvfile)
- df[:3] #显示前 3 条信息
运行结果如下图:
每一行数据都有这么几个特征列:
Unamed 未命名, 其实是序号
title 标题信息
momey 每月租金
shi 卧室数量
ting 客厅数量
wei 卫生间数量
area 房屋面积平米数
add 房屋地址
jjr 经纪人
其中对租金影响最大的可能是房屋面积和房屋地址(好的地段租金会明显贵很多), 其他因素也或多或少会产生影响, 甚至一些这里没有包含的信息, 比如楼层数, 照片数量等.
为了简化案例, 我们不考虑其他因素. 而且我们首先从都是数字组成的面积因素开始入手.
思路分析
前一篇文章中使用了下图表示房屋面积和租金直接的关系:
我们把问题再简化一下, 只考虑 y=ax 的情况, 这样我们就只要找出 a 的值就可以了.
怎么找呢? 可以先假设 a 是 1, 然后增加一点点(比如 0.1, 这可以视作学习率 learn rate), 评估一下是否更合理了, 如果的确更好了, 就继续增加, 否则就减少, 直到无论增加还是减少只会变得更糟, 那么此时就是最好了.
价值函数 Cost
我们的问题于是就变成了怎么评估的问题. 看下图:
这张图上灰色的线表示 y=ax, 如果足够完美的话所有蓝色小点所代表的样本都应该位于这条灰色的线上, 满足房租 y 等于 a 乘以面积 x.
所以, 图上橙色线的绝对值相加越大, 代表偏移越多, 绝对值相加越小, 也就越接近正确答案.
与其计算橙色线绝对值的和, 不如直接计算橙色线平方的和, 也就是和方差, 假设 100 个样本列表 S, 即:
价值函数的代码是:
import math def getCost(a): cost=0 for n in range(10): item=df.loc[n] area=float(item['area']) offset=(a*area-float(item['money'])) cost+=math.pow(offset,2) return cost
训练函数 Train
我们使用一个初始值 a=1, 然后使用学习率 learnRate=1 来循环增加 a, 并计算 (a+1) 的价值 newCost, 如果这个新的价值比之前的价值 lastCost 大了, 那就把 learnRate 乘以 - 1, 这样下次 (a+learnRate) 就会变小, 以此类推, 当价值函数来回震荡之后我们最终就能得到最佳值.
def train(): lastA = 1 lastCost = 0 learnRate = 1 for i in range(100): newA = lastA + learnRate newCost = getCost(newA) if newCost> lastCost: learnRate = learnRate * (-1) lastCost = newCost lastA = newA return newA train()
在上面 cost 函数只取 10 个样本的时候, 当使用 lastA=1,learnRate=1, 循环 100 次之后, 得到的是 39, 如果 learnRate=10, 那么得到的就是 41, 如果 learnRate=2 得到的就是 37. 当然, 其中 39 是最好的, 如果使用 learnRate=0.1, 循环 1000 次就可以得到更好的.-- 从此可以看出循环次数和学习率对最终结果的影响很大.
a=39 意味着什么? 这代表着每平米会导致租金上升 39 元, 因为 y=ax.
如果把 cost 函数中的样本数量增加到 100 个, 得到的结果就变为 35, 或者 34.8. 这明显是一个更加接近的数字, 因为它有更大的样本作为参照.
注意不要尝试学习率 0.1 而只循环 100 次, 因为那样最多增加 10, 还不足够增加到 34.
后续文章我们继续进一步分析这个思路的更多细节和改进优化方法.
来源: http://www.jianshu.com/p/3e34ed4b56cf