本系列作品尽量不涉及到高深的数学公式,一切以实际工作为主,以实际工作中遇到的问题及解决问题的思路为主。所有代码均已提交到github上,供读者参考。
github:https://github.com/worry1613/gongyu-recommend
出租公寓项目是笔者2016年的项目,出租公寓的数据全部来自58同城品牌公寓馆,爬虫代码我就不发上来了,我手下的小孩写的,事先沟通不细,所以原始数据格式真是惨不忍睹啊。
出租公寓推荐系统1-特征工程
抓回来的原始数据格式很不好,mysql表结构如下
浏览内容如下
可以看到不算是数字的还是文字的内容,保存下来全部都是字符格式的,这不行,不管内容是文字,数字,图片,声音,视频或者其它什么格式,数据特征必须是可量化的可计算的数值。
接下来要进行特征选择,用哪些特征(或属性)来表示一个出租公寓的信息。仔细看一下就能很容易的分析出来,title字段是在网页上显示信息的,内容是多个其它字段的组合,特征中去掉 title字段。pay_unit内容全部一样,有和没有一样,特征中去掉 pay_unit字段。特征中去掉phone字段,无意义字段。overage字段(剩作房间数),本项目 不涉及到在线订房功能,本字段信息无效,特征中去掉 overage字段。images字段是图片信息,本项目不涉及图片识别功能,无法把图片信息量化成数字,所以放弃,特征中去掉 images字段。
到此为止,我们完成了最基础的工作,把数据中一些无用无意义的字段信息去掉了,留下来的都是要用到的。
大部分的数据特征都是比较明显的,例如:单价,楼层,区域,也有一些数据特征不太明显,需要多个特征计算得来或者更复杂,例发:增长率,激活率等等,找到越多的有效的数据特征,那就能更详细的描述这个物品,能不能找到更多的特征,是看你对业务是不是足够的了解,了解的越深,就能找到越多的数据特征。
接下来,要把字些数据特征转换成可量化的数字。苦活,累活(脏活)开始了。
flats_name公寓名字,理论上是可以用NLP来处理,TFIDF来算一下权重,但数据查看后,公寓的名字都很独立,不做处理,放弃。
flats_property内容只有‘合租’,‘整租’这两种情况,枚举类型,例如:1-男,2-女。换成数字表示1-合租,2-整租。数字可以是任意的,30,100,999都可以,只要区别开就行。
city,area,place字段和flats_property字段情况一样,枚举类型,数字表示即可。
price_start和price_end字段是数字,不用处理。
tag,house_config,service这3个字段是一种类型,多选类型,处理这种信息有2种办法,一种是用NLP的方式来处理,TFIDF比较,就相当于已经分好词的文字内容;另一种方式就是分散化处理,每个关键词内容变成一个新数据特征,用数字来表示它的意义,例发:新加一个字段house_chuang来表示house_config中是否有‘床’,0表示没有,1表示有,包含‘床’的数据house_chuang是1,不包含的是0。
update_time时间格式变成时间戳即可,例如:1521183472。
house_area取出平米数即可,不要后面的单位。
room和floor情况类型,同tag情况差不多,我们把room拆成3个新的特征,室,厅,卫,floor拆成2个特征公寓所在楼层,和总楼层。
traffic因为爬虫的原因,没有处理好,放弃。
house_detail要保留,虽然 我不认为这个对想租公寓的人有什么用,但还是要保存,用TFIDF来处理。
map_info中最重要的要把经纬度取出来保留,其它的就不需要了。注意精度。
deposit和room类似,全是有很多空数据,默认改成‘押一付三’,之后处理方式和room相同。
基本上是处理完成了,最后的数据格式是这样的
`_id` bigint(20) NOT NULL AUTO_INCREMENT,
`price_start` smallint(6) unsigned NOT NULL COMMENT '租金下限',
`price_end` smallint(6) unsigned NOT NULL COMMENT '租金上限',
`house_area` smallint(5) unsigned NOT NULL COMMENT '房屋面积',
`flats_property_i` tinyint(4) unsigned NOT NULL COMMENT '公寓性质(1,合租、2,整租) ',
`city_i` tinyint(4) unsigned NOT NULL COMMENT '城市',
`area_i` smallint(5) unsigned NOT NULL COMMENT '所在区域(朝阳区、丰台区',
`place_i` smallint(5) unsigned NOT NULL COMMENT '所在地(朝阳公园、国贸 ',
`shi` tinyint(3) unsigned NOT NULL COMMENT '几室',
`ting` tinyint(3) unsigned NOT NULL COMMENT '几厅',
`wei` tinyint(3) unsigned NOT NULL COMMENT '几卫',
`floor_i` tinyint(3) unsigned NOT NULL COMMENT '总楼层',
`floor_zhu_i` tinyint(3) unsigned NOT NULL COMMENT '当前楼层',
`loc` point DEFAULT NULL COMMENT '经纬度(纬,经)',
`deposit_ya` tinyint(3) unsigned NOT NULL COMMENT '房租押金',
`deposit_pay` tinyint(3) unsigned NOT NULL COMMENT '交几个月的房租',
`s_jsf` tinyint(1) NOT NULL DEFAULT '0' COMMENT '健身房',
`s_gycs` tinyint(1) NOT NULL DEFAULT '0' COMMENT '公寓超市 ',
`s_znms` tinyint(1) NOT NULL DEFAULT '0' COMMENT '智能门锁 ',
`s_atm` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'ATM机 ',
`s_dskd` tinyint(1) NOT NULL DEFAULT '0' COMMENT '代收快递',
`s_zskf` tinyint(1) NOT NULL DEFAULT '0' COMMENT ' 专属客服',
`s_fjqj` tinyint(1) NOT NULL DEFAULT '0' COMMENT ' 房间清洁',
`s_24hba` tinyint(1) NOT NULL DEFAULT '0' COMMENT '24H安保 ',
`s_bjwx` tinyint(1) NOT NULL DEFAULT '0' COMMENT '保洁维修 ',
`s_sqhd` tinyint(1) NOT NULL COMMENT '社区活动',
`c_chuang` tinyint(1) NOT NULL DEFAULT '0' COMMENT '床 ',
`c_yigui` tinyint(1) NOT NULL DEFAULT '0' COMMENT '衣柜 ',
`c_shuzhuo` tinyint(1) NOT NULL DEFAULT '0' COMMENT '书桌 ',
`c_kongtiao` tinyint(1) NOT NULL DEFAULT '0' COMMENT '空调 ',
`c_canzhuo` tinyint(1) NOT NULL DEFAULT '0' COMMENT '餐桌 ',
`c_nuanqi` tinyint(1) NOT NULL DEFAULT '0' COMMENT '暖气 ',
`c_tv` tinyint(1) NOT NULL DEFAULT '0' COMMENT '电视机 ',
`c_ranqi` tinyint(1) NOT NULL DEFAULT '0' COMMENT '燃气 ',
`c_wbl` tinyint(1) NOT NULL DEFAULT '0' COMMENT '微波炉 ',
`c_dcl` tinyint(1) NOT NULL DEFAULT '0' COMMENT '电磁炉 ',
`c_rsq` tinyint(1) NOT NULL DEFAULT '0' COMMENT '热水器 ',
`c_xyj` tinyint(1) NOT NULL DEFAULT '0' COMMENT '洗衣机 ',
`c_bx` tinyint(1) NOT NULL DEFAULT '0' COMMENT '冰箱 ',
`c_wifi` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'WIFI ',
`c_sf` tinyint(1) NOT NULL DEFAULT '0' COMMENT '沙发 ',
`c_cg` tinyint(1) NOT NULL DEFAULT '0' COMMENT '橱柜 ',
`c_yyj` tinyint(1) NOT NULL DEFAULT '0' COMMENT '油烟机',
数据看上去是这样子的,应该全部都是数字
具体的格式我会直接上传到github上。
在data目录下我已经把数据导入成了一个csv文件,gongyu.1.csv,可以直接操作这个文件来处理了。
还有重要的一步没有做,那就是数据标准化(归一化),如果要计算公寓的相似性,就必须要进行这一步操作,不然相似性计算不准确。代码很简单,在jupyter notebook上都有。
import pandas as pd
out=pd.read_csv('./data/gongyu.1.csv',index_col = '_id')
del out['update_time_i']
from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()
out_train_minmax = min_max_scaler.fit_transform(out)
到这里我们前期的处理算是完成了。
下一篇马上就来了,敬请期待.......