【机器学习】3.1.多元回归模型 房产估价模型

包含全部示例的代码仓库见GIthub

1 导入库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics

2 数据准备

data_list = []
for i in range(1,8):
    try:
        data = pd.read_csv('./dataset/lianjia{}.csv'.format(i), encoding='gbk')
    except:
        data = pd.read_csv('./dataset/lianjia{}.csv'.format(i))
    finally:
        data_list.append(data)
data = pd.concat(data_list)
data = data.dropna()
data = data[data.cjshijian.str.contains('2015-')]
data.head()
# output
	cjtaoshu	mendian	cjzongjia	zhiwei	haoping	cjdanjia	cjxiaoqu	xingming	cjzhouqi	biaoqian	cjlouceng	cjshijian	congyenianxian	bankuai
0	37	红莲北里店	251.0	店经理	97% 141	43997/平	红莲北里 3157平	郭海龙	36	房东信赖;销售达人;带看活跃	南 北/高楼层/6层	签约时间:2015-05-24	4-5年	马连道
1	37	红莲北里店	159.0	店经理	97% 141	36969/平	红莲南里 1143平	郭海龙	36	房东信赖;销售达人;带看活跃	南/高楼层/7层	签约时间:2015-05-10	4-5年	马连道
2	37	红莲北里店	257.0	店经理	97% 141	39046/平	常青藤嘉园 1165平	郭海龙	36	房东信赖;销售达人;带看活跃	北/低楼层/16层	签约时间:2015-04-26	4-5年	马连道
3	37	红莲北里店	243.0	店经理	97% 141	41313/平	红莲北里 2158平	郭海龙	36	房东信赖;销售达人;带看活跃	南 北/高楼层/6层	签约时间:2015-04-04	4-5年	马连道
4	37	红莲北里店	372.5	店经理	97% 141	42053/平	广安门外大街 3188平	郭海龙	36	房东信赖;销售达人;带看活跃	东 南 西 北/中楼层/18层	签约时间:2015-04-01	4-5年	马连道
data = data[['cjdanjia', 'cjxiaoqu', 'cjlouceng']]
data
# output
    cjdanjia	cjxiaoqu	cjlouceng
0	43997/平	红莲北里 3157平	南 北/高楼层/61	36969/平	红莲南里 1143平	南/高楼层/72	39046/平	常青藤嘉园 1165平	北/低楼层/163	41313/平	红莲北里 2158平	南 北/高楼层/64	42053/平	广安门外大街 3188平	东 南 西 北/中楼层/18...	...	...	...
6591	27835/平	富力又一城C区 2288平	南/高楼层/236592	20820/平	扬州水乡 31122平	南 北/中楼层/56593	20302/平	扬州水乡 2276平	南 北/低楼层/36594	26948/平	富力又一城A区 32139平	南 北/中楼层/226659	11829/平	福城上上城三季 2159平	北/中楼层/26
data.cjdanjia = np.round(data.cjdanjia.str.replace('元/平','').astype(np.float32).map(lambda x:x/10000),2)
data.head()
# output
    cjdanjia	cjxiaoqu	cjlouceng
0	4.40	红莲北里 3157平	南 北/高楼层/61	3.70	红莲南里 1143平	南/高楼层/72	3.90	常青藤嘉园 1165平	北/低楼层/163	4.13	红莲北里 2158平	南 北/高楼层/64	4.21	广安门外大街 3188平	东 南 西 北/中楼层/18

删除异常数据

(data.cjxiaoqu.str.split().map(len) != 3).sum()
# output
3

data = data[data.cjxiaoqu.str.split().map(len) == 3]
data = data.assign(xiaoqu = data.cjxiaoqu.map(lambda x:x.split()[0]))
data = data.assign(huxing = data.cjxiaoqu.map(lambda x:x.split()[1]))
data = data.assign(mianji = data.cjxiaoqu.map(lambda x:x.split()[2]))
del data['cjxiaoqu']
data
# output
	cjdanjia	cjlouceng	xiaoqu	huxing	mianji
0	4.40	南 北/高楼层/6层	红莲北里	31571	3.70/高楼层/7层	红莲南里	11432	3.90/低楼层/16层	常青藤嘉园	11653	4.13	南 北/高楼层/6层	红莲北里	21584	4.21	东 南 西 北/中楼层/18层	广安门外大街	3188...	...	...	...	...	...
6591	2.78/高楼层/23层	富力又一城C区	22886592	2.08	南 北/中楼层/5层	扬州水乡	311226593	2.03	南 北/低楼层/3层	扬州水乡	22766594	2.69	南 北/中楼层/22层	富力又一城A区	321396659	1.18/中楼层/26层	福城上上城三季	2159

查看是否还有异常值

data[data.cjlouceng.str.split('/').map(len) != 3]
# output
cjdanjia	cjlouceng	xiaoqu	huxing	mianji
data = data.assign(chaoxiang = data.cjlouceng.map(lambda x:x.split('/')[0]))
data = data.assign(louceng = data.cjlouceng.map(lambda x:x.split('/')[1]))
del data['cjlouceng']
data
# output
	cjdanjia	xiaoqu	huxing	mianji	chaoxiang	louceng
0	4.40	红莲北里	3157平	南 北	高楼层
1	3.70	红莲南里	1143平	南	高楼层
2	3.90	常青藤嘉园	1165平	北	低楼层
3	4.13	红莲北里	2158平	南 北	高楼层
4	4.21	广安门外大街	3188平	东 南 西 北	中楼层
...	...	...	...	...	...	...
6591	2.78	富力又一城C区	2288平	南	高楼层
6592	2.08	扬州水乡	31122平	南 北	中楼层
6593	2.03	扬州水乡	2276平	南 北	低楼层
6594	2.69	富力又一城A区	32139平	南 北	中楼层
6659	1.18	福城上上城三季	2159平	北	中楼层

取出成交量前十五的小区的成交数据

top15 = data.xiaoqu.value_counts()[:15].index
data = data[data.xiaoqu.isin(top15)]  # 取出成交量前十五的小区的成交数据
data
# output
	cjdanjia	xiaoqu	huxing	mianji	chaoxiang	louceng
31	6.62	荣丰2008	1132平	南	低楼层
347	3.97	远洋山水	1--56平	东	中楼层
388	3.01	北京像素北区	2157平	西南	低楼层
716	2.90	北京像素北区	2158平	东北	中楼层
260	3.81	沿海赛洛城	1164平	东	低楼层
...	...	...	...	...	...	...
3769	2.07	天通苑东一区	2196平	东	低楼层
4096	2.96	芍药居北里	1156平	南	低楼层
4230	1.93	天通苑东一区	32130平	南 北	中楼层
4232	2.50	天通苑东一区	2176平	南 北	中楼层
5379	1.94	天通苑东一区	21101平	东 南	高楼层

产出'平'

data.mianji = data.mianji.str.replace('平','').astype(np.float32)
data.head()
# output
 cjdanjia	xiaoqu	huxing	mianji	chaoxiang	louceng
31	6.62	荣丰2008	1132.0	南	低楼层
347	3.97	远洋山水	1--56.0	东	中楼层
388	3.01	北京像素北区	2157.0	西南	低楼层
716	2.90	北京像素北区	2158.0	东北	中楼层
260	3.81	沿海赛洛城	1164.0	东	低楼层

异常值处理

data.xiaoqu.unique()
# output
array(['荣丰2008', '远洋山水', '北京像素北区', '沿海赛洛城', '东亚上北中心', '天通西苑二区', '芍药居北里',
       '北京新天地', '北京像素南区', '新龙城', '青年汇佳园', '天通苑中苑', '天通苑东一区', '海特花园小区',
       '天通西苑三区'], dtype=object)

data.chaoxiang.unique()
# output
array(['南', '东', '西南', '东北', '南 北', '西 南', '东 南', '东 南 北', '西北', '东 北',
       '东 西', '西', '北', '西 北', '东南', '南 西', '东 南 西', '西 南 北', '南 北 西',
       '东 西 北', '南 西 北', '西南 东北', '南 北 东', '暂无数据', '北 东南', '北 西南',
       '东 西 南', '东 北 南'], dtype=object)

data = data[data.chaoxiang != '暂无数据']
data.chaoxiang.unique()
# output
array(['南', '东', '西南', '东北', '南 北', '西 南', '东 南', '东 南 北', '西北', '东 北',
       '东 西', '西', '北', '西 北', '东南', '南 西', '东 南 西', '西 南 北', '南 北 西',
       '东 西 北', '南 西 北', '西南 东北', '南 北 东', '北 东南', '北 西南', '东 西 南',
       '东 北 南'], dtype=object)

data.louceng.unique()
# output
array(['低楼层', '中楼层', '高楼层', '地下室'], dtype=object)

data.huxing.unique()
# output
array(['1室1厅', '1室--厅', '2室1厅', '2室2厅', '3室2厅', '4室2厅', '1室2厅', '3室1厅',
       '5室1厅', '3室--厅', '5室--厅', '4室1厅', '5室2厅', '3室3厅', '2室--厅', '2室3厅',
       '4室--厅'], dtype=object)

data = data.join(pd.get_dummies(data[['xiaoqu','huxing','louceng']]))
data
# output
	cjdanjia	xiaoqu	huxing	mianji	chaoxiang	louceng	xiaoqu_东亚上北中心	xiaoqu_北京像素北区	xiaoqu_北京像素南区	xiaoqu_北京新天地	...	huxing_4室--厅	huxing_4室1厅	huxing_4室2厅	huxing_5室--厅	huxing_5室1厅	huxing_5室2厅	louceng_中楼层	louceng_低楼层	louceng_地下室	louceng_高楼层
31	6.62	荣丰2008	1132.0	南	低楼层	0	0	0	0	...	0	0	0	0	0	0	0	1	0	0
148	3.86	芍药居北里	1143.0	南	地下室	0	0	0	0	...	0	0	0	0	0	0	0	0	1	0
260	3.81	沿海赛洛城	1164.0	东	低楼层	0	0	0	0	...	0	0	0	0	0	0	0	1	0	0
261	3.32	沿海赛洛城	1157.0	东	中楼层	0	0	0	0	...	0	0	0	0	0	0	1	0	0	0
285	3.96	沿海赛洛城	22105.0	南 北	中楼层	0	0	0	0	...	0	0	0	0	0	0	1	0	0	0
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
56956	3.59	新龙城	1156.0	北	低楼层	0	0	0	0	...	0	0	0	0	0	0	0	1	0	0
56957	2.20	天通苑东一区	2194.0	东南	中楼层	0	0	0	0	...	0	0	0	0	0	0	1	0	0	0
56960	3.11	新龙城	1270.0	南	低楼层	0	0	0	0	...	0	0	0	0	0	0	0	1	0	0
56961	3.18	新龙城	32111.0	南 北	高楼层	0	0	0	0	...	0	0	0	0	0	0	0	0	0	1
56962	2.83	新龙城	2298.0	东 西	中楼层	0	0	0	0	...	0	0	0	0	0	0	1	0	0	0
1852 rows × 42 columns

chaoxiang进行独热编码

len(data.chaoxiang.unique())
# output
27

data.chaoxiang.unique()
# output
array(['南', '东', '南 北', '东 西', '南 西', '南 北 西', '西南', '西 北', '东南', '东 北',
       '东 南', '西 南', '东北', '东 南 北', '西北', '西', '北', '西南 东北', '西 南 北',
       '东 南 西', '南 北 东', '南 西 北', '东 西 北', '东 西 南', '北 东南', '北 西南',
       '东 北 南'], dtype=object)
data['dong'] = (data.chaoxiang.map(lambda x:'东' in x.split())).astype(np.int32)
data['xi'] = (data.chaoxiang.map(lambda x:'西' in x.split())).astype(np.int32)
data['nan'] = (data.chaoxiang.map(lambda x:'南' in x.split())).astype(np.int32)
data['bei'] = (data.chaoxiang.map(lambda x:'北' in x.split())).astype(np.int32)
data['dongnan'] = (data.chaoxiang.map(lambda x:'东南' in x.split() or '南东' in x.split())).astype(np.int32)
data['dongbei'] = (data.chaoxiang.map(lambda x:'东北' in x.split())).astype(np.int32)
data['xinan'] = (data.chaoxiang.map(lambda x:'西南' in x.split())).astype(np.int32)
data['xibei'] = (data.chaoxiang.map(lambda x:'西北' in x.split())).astype(np.int32)
data.drop(data.columns[[1,2,4,5]], axis=1, inplace=True)  # 删除多列
data
# output
	cjdanjia	mianji	xiaoqu_东亚上北中心	xiaoqu_北京像素北区	xiaoqu_北京像素南区	xiaoqu_北京新天地	xiaoqu_天通苑东一区	xiaoqu_天通苑中苑	xiaoqu_天通西苑三区	xiaoqu_天通西苑二区	...	louceng_地下室	louceng_高楼层	dong	xi	nan	bei	dongnan	dongbei	xinan	xibei
31	6.62	32.0	0	0	0	0	0	0	0	0	...	0	0	0	0	1	0	0	0	0	0
148	3.86	43.0	0	0	0	0	0	0	0	0	...	1	0	0	0	1	0	0	0	0	0
260	3.81	64.0	0	0	0	0	0	0	0	0	...	0	0	1	0	0	0	0	0	0	0
261	3.32	57.0	0	0	0	0	0	0	0	0	...	0	0	1	0	0	0	0	0	0	0
285	3.96	105.0	0	0	0	0	0	0	0	0	...	0	0	0	0	1	1	0	0	0	0
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
56956	3.59	56.0	0	0	0	0	0	0	0	0	...	0	0	0	0	0	1	0	0	0	0
56957	2.20	94.0	0	0	0	0	1	0	0	0	...	0	0	0	0	0	0	1	0	0	0
56960	3.11	70.0	0	0	0	0	0	0	0	0	...	0	0	0	0	1	0	0	0	0	0
56961	3.18	111.0	0	0	0	0	0	0	0	0	...	0	1	0	0	1	1	0	0	0	0
56962	2.83	98.0	0	0	0	0	0	0	0	0	...	0	0	1	1	0	0	0	0	0	0
Y = data.cjdanjia
X = data[[x for x in data.columns if x != 'cjdanjia']]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y)
X_train.shape, np.shape(X_train), np.shape(X_train.values)
# output
((1389, 45), (1389, 45), (1389, 45))

3 模型构建

model = LinearRegression()
model.fit(X_train, Y_train)

4 模型评价

metrics.mean_squared_error(model.predict(X_test), Y_test)
# output
0.3120292004271854

5 模型预测

data_test = pd.Series(np.zeros(len([x for x in data.columns if x != 'cjdanjia'])),
                      index = [x for x in data.columns if x != 'cjdanjia'])
data_test.mianji = 80
data_test.xiaoqu_天通西苑三区 = 1
data_test.nan = 1
data_test.bei = 1
data_test.huxing_2室2= 1
data_test.louceng_高楼层 = 1
data_test
# output
mianji           80.0
xiaoqu_东亚上北中心     0.0
xiaoqu_北京像素北区     0.0
xiaoqu_北京像素南区     0.0
xiaoqu_北京新天地      0.0
xiaoqu_天通苑东一区     0.0
xiaoqu_天通苑中苑      0.0
xiaoqu_天通西苑三区     1.0
xiaoqu_天通西苑二区     0.0
xiaoqu_新龙城        0.0
xiaoqu_沿海赛洛城      0.0
xiaoqu_海特花园小区     0.0
xiaoqu_芍药居北里      0.0
xiaoqu_荣丰2008     0.0
xiaoqu_远洋山水       0.0
xiaoqu_青年汇佳园      0.0
huxing_1室--0.0
huxing_1室10.0
huxing_1室20.0
huxing_2室--0.0
huxing_2室10.0
huxing_2室21.0
huxing_2室30.0
huxing_3室--0.0
huxing_3室10.0
huxing_3室20.0
huxing_3室30.0
huxing_4室--0.0
huxing_4室10.0
huxing_4室20.0
huxing_5室--0.0
huxing_5室10.0
huxing_5室20.0
louceng_中楼层       1.0
louceng_低楼层       0.0
louceng_地下室       0.0
louceng_高楼层       1.0
dong              0.0
xi                0.0
nan               1.0
bei               1.0
dongnan           0.0
dongbei           0.0
xinan             0.0
xibei             0.0
model.predict(data_test.values.reshape(1,-1))
# output
array([3.25528068])
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LouHerGetUp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值