目录
- 北京房源二手房房价预测
- 项目背景
- 变量说明
- 小区数据 community_describe.csv
- 房源数据 house.csv
- 数据融合
- 数据提取
- 在housetype中删除车位和别墅的数据。提取客厅数,房间数,卫生间数
- 去掉square中的平米
- 在taxtype中提取地铁距离,房本类型
- 在tagList中提取地铁站
- 删除没用的列
- 将数值类型字符串转为数值类型
- 处理异常值
- 缺失值处理
- 编码
- 建模
北京房源二手房房价预测
项目背景
提高成单量
促成售卖,促成租赁
变量说明
小区数据 community_describe.csv
- index 索引
- id 小区ID
- community 小区名称
- district 区
- bizcircle 街道
- tagList 标签列表
- onsale 在售房源数量
房源数据 house.csv
- index 索引
- title 房屋标题
- community 小区名(关联字段)
- years 房屋年限信息
- housetype 房屋类型
- square 平米数
- floor 层数
- taxtype 契税信息
- totalPrice 总价格(万元)
- unitPrice 单价(元)
- followInfo 带看信息
数据融合
importpandasaspdimportnumpyasnpimportwarnings warnings.filterwarnings('ignore')house=pd.read_csv('./二手房数据/house.csv')community=pd.read_csv('./二手房数据/community_describe.csv')data=house.merge(community,on='community',how='left')数据提取
使用正则提取数字数据
#当前层data['当前层']=data.years.str.extract('(\w*?)\(')#总楼层data['总楼层']=data.years.str.extract('共(\d+)层')#建成年份data['建成年份']=data.years.str.extract('\)(\d+)年')#建筑结构data['建筑结构']=data.years.str.extract('建(\w+)')deldata['years']deldata['floor']在housetype中删除车位和别墅的数据。提取客厅数,房间数,卫生间数
data=data[~data.housetype.str.contains('别|车')]#卧室data['卧室']=data.housetype.str.extract('(\d+)室|房')#客厅data['客厅']=data.housetype.str.extract('(\d+)厅')#卫生间data['卫生间']=data.housetype.str.extract('(\d+)卫')deldata['housetype']去掉square中的平米
data['square']=data.square.str.replace('平米','')在taxtype中提取地铁距离,房本类型
data['地铁距离']=data.taxtype.str.extract('站(\d+)')data['房本类型']=data.taxtype.str.extract('满(\w+)年')deldata['taxtype']在tagList中提取地铁站
data['地铁站']=data.tagList.str.extract('线(\w+)')deldata['tagList']删除没用的列
data=data.drop(['index_x','title','totalPrice','followInfo','index_y','id','onsale'],axis=1)将数值类型字符串转为数值类型
data['square']=data['square'].astype('float64')data['总楼层']=data['总楼层'].astype('float64')data['建成年份']=data['建成年份'].astype('float64')data['卧室']=data['卧室'].astype('float64')data['客厅']=data['客厅'].astype('float64')data['卫生间']=data['卫生间'].astype('float64')data['地铁距离']=data['地铁距离'].astype('float64')处理异常值
使用掩码调整数据
data=data[data.unitPrice>=30000]data=data[data['总楼层']<40]data=data[data['卧室']<5]data=data[data['客厅']<=2]deldata['卫生间']data=data[data['当前层']!='地下室']data=data[data['建筑结构']!='平房']缺失值处理
data.info()<class'pandas.core.frame.DataFrame'>Int64Index:15255entries,0to16115Data columns(total14columns):# Column Non-Null Count Dtype----------------------------0community15255non-nullobject1square15255non-null float642unitPrice15255non-null int643district14188non-nullobject4bizcircle14188non-nullobject5当前层15255non-nullobject6总楼层15255non-null float647建成年份15221non-null float648建筑结构15145non-nullobject9卧室15255non-null float6410客厅15255non-null float6411地铁距离10117non-null float6412房本类型12821non-nullobject13地铁站10655non-nullobjectdtypes:float64(6),int64(1),object(7)memory usage:1.7+MB# district缺失值删掉data=data[~data.district.isna()]#地铁距离的缺失值,使用最大值填充data.地铁距离[data.地铁距离.isna()]=data.地铁距离.max()#房本类型缺失值,认为不满2年,使用1填充data.房本类型[data.房本类型.isna()]=1#地铁站的缺失值,填充无data.地铁站[data.地铁站.isna()]='无'#建成年份的缺失值,使用同小区的众数,进行填充。填充失败的直接删除defgetyears(items):val=data.建成年份[data.community==items].mode()ifval.size>0:returnval[0]else:returnnp.nan data.建成年份[data.建成年份.isna()]=data.community[data.建成年份.isna()].apply(getyears)# 填充失败的,直接删掉data.dropna(subset=['建成年份'],inplace=True)#建筑结构的缺失值,使用同小区的众数,进行填充。填充失败的直接删除defgetyears(items):val=data.建筑结构[data.community==items].mode()ifval.size>0:returnval[0]else:returnnp.nan data.建筑结构[data.建筑结构.isna()]=data.community[data.建筑结构.isna()].apply(getyears)# 填充失败的,直接删掉data.dropna(subset=['建筑结构'],inplace=True)编码
#districtdis_onehot=pd.get_dummies(data.district)#进行独热编码data=pd.concat((data,dis_onehot),axis=1)deldata['district']# 当前层# data.当前层.unique()dic_floor={'底层':1,'低楼层':2,'中楼层':3,'顶层':4,'高楼层':5}data['当前层']=data.当前层.map(dic_floor)# 建筑结构# data.建筑结构.unique()dic_build={'板塔结合':1,'塔楼':2,'板楼':3}data['建筑结构']=data.建筑结构.map(dic_build)# 房本类型# data.房本类型.unique()dic_housebook={'五':5,'两':2,1:1}data['房本类型']=data.房本类型.map(dic_housebook)# bizcircledic_biz=dict(data.bizcircle.value_counts())data['bizcircle']=data.bizcircle.map(dic_biz)# 地铁站dic_sub=dict(data.groupby('地铁站')['unitPrice'].mean())data['地铁站']=data.地铁站.map(dic_sub)# communitydic_com=dict(data.groupby('community')['unitPrice'].mean())data['community']=data.community.map(dic_com)# 将unitPrice放到最后一列data['y']=data['unitPrice']deldata['unitPrice']建模
importsklearn.model_selectionasms#模型选择x=data.iloc[:,:-1]y=data.iloc[:,-1]train_x,\ test_x,\ train_y,\ test_y=ms.train_test_split(x,y,test_size=0.1,random_state=7)#回归defselect_model(name,model):passdic_model={'模型名':模型对象}forname,objindic_model.items():select_model(name,obj)例子:
defselect_model(name,model):print('--------',name,'----------')model.fit(train_x,train_y)pred_test_y=model.predict(test_x)print(sm.classification_report(test_y,pred_test_y))model_dict={'单颗决策树':st.DecisionTreeClassifier(),'Adaboost':se.AdaBoostClassifier(st.DecisionTreeClassifier(),n_estimators=100),'GBDT':se.GradientBoostingClassifier(n_estimators=100),'随机森林':se.RandomForestClassifier(n_estimators=100)}forname,objinmodel_dict.items():select_model(name,obj)