雷锋网按:文章原标题《Predicting Portland Home Prices》,作者:Lauren Shareshian,译者:夏天,审校:主题曲。本文原载于知乎专栏 我是程序员 。
对于我在梅蒂斯的最后一个项目,我希望能包含过去三个月里所学到的东西,而预测波特兰房价这个题目正符合我的要求,因为我能够将网络爬取技术、文本自然语言处理,图像上的深度学习模型以及梯度增强技术进行整合来实现这个项目。
下面你可以看到我抓取到的 2016 年 7 月至 2017 年 7 月这段时间内波特兰市 8300 个独户住宅的销售数据。
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/a70dbdf1540febe5aab1763960697d5f.png" data-rawwidth="1061" data-rawheight="818" class="origin_image zh-lightbox-thumb" width="1061" data-original="https://pic2.zhimg.com/v2-719f60a2bd3b436a6040507f5a23b649_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/a70dbdf1540febe5aab1763960697d5f.png"/>
显然,街区在这其中起了非常重要的作用。西山(红色)是镇上最昂贵的地区之一,而东波特兰则便宜很多。平均售价为 44.2 万美元。
我希望能够在比街区更细粒度的水平上预测价格。例如,假设以下房子是彼此毗邻的。
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/5227f4bd3823a293c05394ba244746fe.png" data-rawwidth="610" data-rawheight="440" class="origin_image zh-lightbox-thumb" width="610" data-original="https://pic1.zhimg.com/v2-58c62c51e0147fa1fc872e806f783104_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/5227f4bd3823a293c05394ba244746fe.png"/>
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/c963e3fd23c92b75409abce5c753ba44.png" data-rawwidth="610" data-rawheight="403" class="origin_image zh-lightbox-thumb" width="610" data-original="https://pic1.zhimg.com/v2-f0ba7beccfec7d52b07623d416b8c828_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/c963e3fd23c92b75409abce5c753ba44.png"/>
这些房子面积相同,在同一年份建成,并位于同一条街上。但是,一个明显能让人产生购买的欲望,而另一个则没有。那么 Zillow 或 Redfin(美国的两家大型房地产网站)或其他公司能够仅仅依靠一些房屋的文字数据来预测它们的价格呢?他们不能。这就是为什么我要把对房屋门口照片的分析作为其中一个特征纳入预测模型的原因。
当务之急就是要获取到所有的数据。这比原本预想的要困难的多。首先,我使用波特兰地图 的官方 API 来爬取波特兰独户住宅的销售数据。不幸的是,API 存在调用限制(每 10 分钟约 150 次调用),所以我不得不在 AWS 服务器上长时间地运行程序来抓取所有的详细数据。我使用 Zillow API 抓取了每个家庭的元数据和房地产商对房屋的描述。但是,抓取的速度也很慢,因为 Zillow 只允许你每天调用 API 1000 次。(我让丈夫、母亲和几个朋友来帮我获取更多的 API 密钥)
最后,数据收集过程中最困难的部分是获取图像。这是因为 Zillow 有获取图片的 API,但 Redfin 没有,但 Redfin 会在房子出售后仍把图片留那,而 Zillow 不会。为了获取到 Redfin 网站上的图片,我编写了一个 Selenium 脚本,在 Google Images 上通过在搜索条目后增加 “Redfin” 一词来搜索房屋地址,然后抓取 Google 列出的第一张图片的 URL。
不幸的是,虽然我有了图像的 URL,实际要直接将它们下载下来并不简单。这是因为 Redfin 不允许你使用标准的 Python 包,例如发送请求获取数据,也不允许你使用简单的 curl 命令。幸运的是,在与别人讨论后,我们提出了这样一个想法:在 curl 命令的末尾加上 “User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)……”,以此来将你的终端请求伪装成浏览器请求。这终于成功了,最终我抓取到了 8300 个房屋的数据和图片!
现在数据有了,我准备要开始实现模型了。如下图所示:
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/03ebd852c2f4f0854cd6a18878138e4e.png" data-rawwidth="718" data-rawheight="325" class="origin_image zh-lightbox-thumb" width="718" data-original="https://pic3.zhimg.com/v2-ab7416804f4a7841b64f1998f5e4ff82_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/03ebd852c2f4f0854cd6a18878138e4e.png"/>
让我们来详细介绍一下这三种输入数据类型。 Zillow 元数据包含你原本预期的描述性文字:平方英尺、街区、建造年份等等。当我按 p 值对每个特征进行排序时,出现了一些惊喜的发现。我一直不知道格鲁吉亚建筑是什么样子的,直到我查了一下之后。
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/db72f462fab86d9aa92a2cb75b091970.png" data-rawwidth="1240" data-rawheight="676" class="origin_image zh-lightbox-thumb" width="1240" data-original="https://pic1.zhimg.com/v2-92db04842873df5b528e5cd63b6e1914_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/db72f462fab86d9aa92a2cb75b091970.png"/>
我准备采用自然语言处理技术来分析地产商的描述性文字。我对地产商的描述性文字做了两件事情:为每一个描述创建一个字矢量矩阵,这样就可以将其与 Zillow 元数据合并到一个特征矩阵中,还有,用 NLTK 情绪包来计算情绪评分:
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/82f25d3b96ce61c072597fc139ee46d0.png" data-rawwidth="830" data-rawheight="429" class="origin_image zh-lightbox-thumb" width="830" data-original="https://pic2.zhimg.com/v2-f5a4bd5de69b9b237213695d411ed21d_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/82f25d3b96ce61c072597fc139ee46d0.png"/>
我想,房地产经纪商的平均积极分数很高(平均分数为 0.6,范围在 - 1 到 + 1 之间)并不让人觉得奇怪。因此,把情绪评分作为特征并没有改善模型。但是,在数据集中挖取最积极和最负面的分数非常有趣:
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/a54e1ccfac45cceac956e28d5dd94990.png" data-rawwidth="766" data-rawheight="401" class="origin_image zh-lightbox-thumb" width="766" data-original="https://pic2.zhimg.com/v2-622828f65e197e9a52733f1a6a7392f1_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/a54e1ccfac45cceac956e28d5dd94990.png"/>
最后,为了将图片合并到模型中,我采用了 VGG16 深度神经网络对图像进行处理,以便提取出它们的特征(8300 x 25000 的图像特征矩阵)。运行该模型的计算量相当得大,所以我需要在 AWS 上安装一个 g2.8xlarge 的 GPU ubuntu 实例。
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/f7b4c5236e5186c278e40696ce4358a1.png" data-rawwidth="797" data-rawheight="444" class="origin_image zh-lightbox-thumb" width="797" data-original="https://pic4.zhimg.com/v2-5d7aa32a58a2fd6f1bc3ac531e101a77_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/f7b4c5236e5186c278e40696ce4358a1.png"/>
图片模型在预测房价方面的效果如何呢?不错!这些是测试集中预测价格最高的三间屋子,显然,它们真的不错:
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/2f093d8f40638cd6f703ce1f013a3b3c.png" data-rawwidth="815" data-rawheight="369" class="origin_image zh-lightbox-thumb" width="815" data-original="https://pic3.zhimg.com/v2-fd48a69b77d2ad2dc05761650f1b7d66_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/2f093d8f40638cd6f703ce1f013a3b3c.png"/>
同样的,图片模型在预测廉价房屋方面也表现得很好:
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/baea0dc1e48ce692a6d3d4cee6274ef5.png" data-rawwidth="807" data-rawheight="366" class="origin_image zh-lightbox-thumb" width="807" data-original="https://pic1.zhimg.com/v2-30c0ca6e5937c237206ca35ddeea0c5c_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/baea0dc1e48ce692a6d3d4cee6274ef5.png"/>
我的模型在处理什么类型的图片时会存在问题呢?包含绿化的房屋!我的模型预测下面这个房屋价值 250 万,但实际上,图中的很多绿化都是免费赠送的!
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/7b13683d000387c1795c686d2ea91c6b.png" data-rawwidth="280" data-rawheight="270" class="content_image" width="280" _src="https://static.leiphone.com/uploads/new/article/pic/201709/7b13683d000387c1795c686d2ea91c6b.png"/>
好的,现在我确信我的图像模型已经挺不错了。我准备将 Zillow 元数据、地产商描述字矩阵和图像特征矩阵组合并到一个矩阵中,然后通过使用梯度提升算法来预测房价。作为一个基准预测,回想一下,数据集的平均房价是 44.2 万元。如果我预测每个家庭都值得这么多,那么平均而言,每个房子的价格就会下降 16.1 万元。而将图像合并到模型中能够立即将该错误降低 2 万元。把地产商描述添加到模型中则会将错误再降低 1 万元。最后,将 Zillow 元数据添加进来,则将平均绝对误差降低到大约 7.1 万元。
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/a072d61b0a4052e0c5aea599007d1063.png" data-rawwidth="599" data-rawheight="448" class="origin_image zh-lightbox-thumb" width="599" data-original="https://pic1.zhimg.com/v2-7a472f4f24e66821309d783cd9f3b84c_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/a072d61b0a4052e0c5aea599007d1063.png"/>
也许你想知道如果在预测房价上只使用 Zillow 元数据的话效果会怎么样?平均来说,它给出了一个 7.0 万元的误差。在添加了房地产商的描述后略微下降到 6.9 万元,但后来添加了图片后却增加到 7.1 万元。换句话说,现在的图片会轻微地降低模型的质量,而不是提升质量。
<img src="https://static.leiphone.com/uploads/new/article/pic/201709/0f7aeb0d5a521fced8b51315965b8624.png" data-rawwidth="518" data-rawheight="440" class="origin_image zh-lightbox-thumb" width="518" data-original="https://pic4.zhimg.com/v2-407532b5947b938dd4006b964eab536b_r.png" _src="https://static.leiphone.com/uploads/new/article/pic/201709/0f7aeb0d5a521fced8b51315965b8624.png"/>
但是,请注意,图像特征矩阵具有 25000 列,而我只使用了 8300 张照片。我根本没有足够的数据来支撑这种模型。如果我在网上爬一个月并能获得更多的图片的话,我相信将图片整合到模型中将有助于提升预测的准确率。
总而言之,在完成这个项目的过程中,我学到了很多东西,也克服了几个重要的困难。我遇到的最大的困难是如何抓取 Redfin 图像以及如何使用 VGG16 模型。我发现 Keras 的文档仍然很少,所以在使用它的时候需要试错很多次。我为自己能完成这个项目而感到自豪,现在我需要做的只是获取更多的数据!你可以在这里 找到 GitHub 项目。
文章为简译,更为详细的内容,请查看原文 。