二手房数据可分析-python

1、jupyter lab或jupyter notebook环境下

项目名称:二手房屋数据可视化

一、导包

In [51]:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
##忽略警告
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.family'] = ['SimHei']   #设置字体为黑体
plt.rcParams['axes.unicode_minus'] = False #解决保存图像时负号“-”显示为方块的问题

In [52]:

%config InlineBackend.figure_format = 'svg'

二、读取数据

In [53]:

house=pd.read_csv('E:/新建文件夹/实训/项目/二手房数据.csv',encoding='gbk')
house

Out[53]:

市区 小区 户型 朝向 楼层 装修情况 电梯 面积(㎡) 价格(万元) 年份
0 朝阳 育慧里一区 1室0厅 西 7 精装 有电梯 52.0 343.0 2001
1 朝阳 大西洋新城A区 2室2厅 南北 10 精装 有电梯 86.0 835.0 1999
2 朝阳 团结湖路 2室1厅 东西 6 精装 无电梯 65.0 430.0 1980
3 朝阳 尚家楼48号院 2室1厅 南北 12 精装 有电梯 75.0 610.0 1998
4 朝阳 望京西园一区 3室2厅 南北 6 精装 无电梯 115.0 710.0 1997
... ... ... ... ... ... ... ... ... ... ...
23672 西城 真武庙六里 2室1厅 南北 18 精装 有电梯 78.0 888.0 1988
23673 西城 右安门内大街 1室1厅 西北 7 其他 无电梯 45.0 405.0 1991
23674 西城 玉桃园二区 2室1厅 南北 6 简装 无电梯 60.0 650.0 1997
23675 西城 红莲南里 2室1厅 南北 7 精装 无电梯 61.0 470.0 1992
23676 西城 白广路6号院 3室0厅 6 简装 NaN 84.0 635.0 1955

23677 rows × 10 columns

一、数据清洗和预处理

In [54]:

###查看是否有空缺值
house.info()##可以看出只有电梯那一列有空缺值

RangeIndex: 23677 entries, 0 to 23676
Data columns (total 10 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   市区      23677 non-null  object 
 1   小区      23677 non-null  object 
 2   户型      23677 non-null  object 
 3   朝向      23677 non-null  object 
 4   楼层      23677 non-null  int64  
 5   装修情况    23677 non-null  object 
 6   电梯      15420 non-null  object 
 7   面积(㎡)   23677 non-null  float64
 8   价格(万元)  23677 non-null  float64
 9   年份      23677 non-null  int64  
dtypes: float64(2), int64(2), object(6)
memory usage: 1.8+ MB

In [55]:

house['电梯'].fillna('未知', inplace=True)###填充数据

In [56]:

###去除电梯那一列,在原来数据的基础上进行删除
# house.drop(labels='电梯',axis=1,inplace=True)
# house##查看数据

In [56]:

###再次进行查看是否有空缺值
house.info()###确认数据没有空缺值

RangeIndex: 23677 entries, 0 to 23676
Data columns (total 10 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   市区      23677 non-null  object 
 1   小区      23677 non-null  object 
 2   户型      23677 non-null  object 
 3   朝向      23677 non-null  object 
 4   楼层      23677 non-null  int64  
 5   装修情况    23677 non-null  object 
 6   电梯      23677 non-null  object 
 7   面积(㎡)   23677 non-null  float64
 8   价格(万元)  23677 non-null  float64
 9   年份      23677 non-null  int64  
dtypes: float64(2), int64(2), object(6)
memory usage: 1.8+ MB

In [57]:

house.isnull().any()##可以看到每一列都没有空缺值

Out[57]:

市区        False
小区        False
户型        False
朝向        False
楼层        False
装修情况      False
电梯        False
面积(㎡)     False
价格(万元)    False
年份        False
dtype: bool

四、利用pyecharts画图

In [58]:

from pyecharts.globals import CurrentConfig, NotebookType

CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB

In [59]:

import pandas as pd
from pyecharts.charts import Map
from pyecharts.charts import Bar
from pyecharts.charts import Line
from pyecharts.charts import Grid
from pyecharts.charts import Pie
from pyecharts.charts import Scatter
from pyecharts import options as opts
(1)统计各城区二手房数量

In [60]:

g = house.groupby('市区')
df_region = g.count()['小区']
region = df_region.index.tolist()
count = df_region.values.tolist()
df_region

Out[60]:

市区
东城     1533
丰台     2952
大兴     2115
密云       12
平谷       41
延庆      469
怀柔       15
房山     1442
昌平     2811
朝阳     2973
海淀     2983
石景山     882
西城     2130
通州     1602
门头沟     496
顺义     1221
Name: 小区, dtype: int64

In [104]:

g = house.groupby('市区')
df_region = g.count()['小区']
region = df_region.index.tolist()
count = df_region.values.tolist()
new = [x + '区' for x in region]
m = (
        Map()
        .add('', [list(z) for z in zip(new, count)], '北京')
        .set_global_opts(
            title_opts=opts.TitleOpts(title='北京市二手房各区分布',is_show=True),
            visualmap_opts=opts.VisualMapOpts(max_=3000,is_show=True),
        )
    )
m.render('北京市二手房各区分布.html')

Out[104]:

'E:\\新建文件夹\\实训\\北京市二手房各区分布.html'
(2)各城区二手房数量-平均价格柱状图

In [62]:

house_price=house.groupby('市区')['价格(万元)'].mean()
house_price

Out[62]:

市区
东城     851.425245
丰台     525.103591
大兴     460.469693
密云     425.333333
平谷     308.658537
延庆     549.876333
怀柔     785.200000
房山     360.611859
昌平     469.230345
朝阳     757.320148
海淀     827.740194
石景山    468.926757
西城     828.909202
通州     455.107553
门头沟    388.054032
顺义     558.339885
Name: 价格(万元), dtype: float64

In [63]:

price=[round(x,2) for x in house_price.values.tolist()]
price

Out[63]:

[851.43,
 525.1,
 460.47,
 425.33,
 308.66,
 549.88,
 785.2,
 360.61,
 469.23,
 757.32,
 827.74,
 468.93,
 828.91,
 455.11,
 388.05,
 558.34]

In [64]:

# 各城区二手房数量-平均价格柱状图
bar = (
    Bar()
    .add_xaxis(region)
    .add_yaxis('数量', count,
              label_opts=opts.LabelOpts(is_show=True))
    .extend_axis(
        yaxis=opts.AxisOpts(
            name="价格(万元)",
            type_="value",
            min_=200,
            max_=900,
            interval=100,
            axislabel_opts=opts.LabelOpts(formatter="{value}"),
        )
    )
    .set_global_opts(
        tooltip_opts=opts.TooltipOpts(
            is_show=True, trigger="axis", axis_pointer_type="cross"
        ),
        xaxis_opts=opts.AxisOpts(
            type_="category",
            axispointer_opts=opts.AxisPointerOpts(is_show=True, type_="shadow"),
        ),
        yaxis_opts=opts.AxisOpts(name='数量',
            axistick_opts=opts.AxisTickOpts(is_show=True),
            splitline_opts=opts.SplitLineOpts(is_show=False),)
    )
)
line2 = (
    Line()
    .add_xaxis(xaxis_data=region)
    .add_yaxis( 
        series_name="价格",
        yaxis_index=1,
        y_axis=price,
        label_opts=opts.LabelOpts(is_show=True),
        z=10)
)
bar.overlap(line2)
bar.load_javascript()

Out[64]:

In [77]:

bar.render_notebook()

Out[77]:

  • 均价分析
(3)二手房价格最高的Top

In [78]:

####二手房价格最高的Top20
top_price=house.sort_values(by='价格(万元)',ascending=False)[:15]
top_price

Out[78]:

市区 小区 户型 朝向 楼层 装修情况 电梯 面积(㎡) 价格(万元) 年份
20390 西城 朱雀门 4室2厅 东南 5 其他 有电梯 376.0 6000.0 2008
22228 东城 贡院六号 5室2厅 南北 23 精装 有电梯 459.0 5500.0 2002
22907 东城 NAGA上院 6室2厅 东南 12 精装 有电梯 608.0 5000.0 2008
3219 顺义 丽宫 5室2厅 南北 3 精装 未知 685.0 5000.0 2007
22982 东城 当代MOMA 5室2厅 东南 7 精装 未知 384.0 4988.0 2006
20202 西城 耕天下 5室3厅 南北 7 其他 有电梯 330.0 4650.0 2003
6191 昌平 碧水庄园 5室3厅 南北 2 精装 未知 571.0 4600.0 2005
2391 顺义 丽嘉花园 4室2厅 东南 2 其他 未知 548.0 4500.0 2007
17285 朝阳 首府官邸 叠拼别墅 南北 5 精装 未知 523.4 4500.0 2007
15327 海淀 紫御府 4室2厅 南北 12 精装 有电梯 374.0 4368.0 2008
23240 东城 长安太和 4室1厅 24 精装 有电梯 314.0 4350.0 2012
21012 西城 西派国际公寓 5室2厅 东南 17 精装 未知 355.0 4270.0 2009
20240 西城 金融世家 4室2厅 西北 15 精装 有电梯 300.0 4250.0 2008
14531 海淀 西山壹号院 4室3厅 东南 6 毛坯 有电梯 561.0 4150.0 2011
21760 西城 丽豪园 4室2厅 西南 6 精装 有电梯 289.0 4055.0 1999

In [79]:

area=top_price['小区'].values.tolist()
count=top_price['价格(万元)'].values.tolist()
bar_1=(
    Bar()
    .add_xaxis(area)
    .add_yaxis('数量',count,category_gap='50%')
    .set_global_opts(
        yaxis_opts=opts.AxisOpts(name='价格(万元)'),
        xaxis_opts=opts.AxisOpts(name='数量'),
    )
)
bar_1.load_javascript()

Out[79]:

In [80]:

bar_1.render_notebook()

Out[80]:

In [82]:

####二手房价格最高的Top7
top_price=house.sort_values(by='价格(万元)',ascending=False)[:7]
top_price

Out[82]:

市区 小区 户型 朝向 楼层 装修情况 电梯 面积(㎡) 价格(万元) 年份
20390 西城 朱雀门 4室2厅 东南 5 其他 有电梯 376.0 6000.0 2008
22228 东城 贡院六号 5室2厅 南北 23 精装 有电梯 459.0 5500.0 2002
22907 东城 NAGA上院 6室2厅 东南 12 精装 有电梯 608.0 5000.0 2008
3219 顺义 丽宫 5室2厅 南北 3 精装 未知 685.0 5000.0 2007
22982 东城 当代MOMA 5室2厅 东南 7 精装 未知 384.0 4988.0 2006
20202 西城 耕天下 5室3厅 南北 7 其他 有电梯 330.0 4650.0 2003
6191 昌平 碧水庄园 5室3厅 南北 2 精装 未知 571.0 4600.0 2005

In [83]:

area=top_price['小区'].values.tolist()
count=top_price['价格(万元)'].values.tolist()
bar_2=(
    Bar()
    .add_xaxis(area)
    .add_yaxis('数量',count,category_gap='50%')
    .set_global_opts(
        yaxis_opts=opts.AxisOpts(name='价格(万元)'),
        xaxis_opts=opts.AxisOpts(name='数量'),
    )
)
bar_2.load_javascript()

Out[83]:

In [84]:

bar_2.render_notebook()

Out[84]:

(4)装修情况/有无电梯玫瑰图

In [85]:

house_fitment=house.groupby('装修情况')['小区'].count()
house_fitment

Out[85]:

装修情况
其他     3239
毛坯      583
简装     8499
精装    11356
Name: 小区, dtype: int64

In [86]:

house_direction=house.groupby('电梯')['小区'].count()
house_direction

Out[86]:

电梯
无电梯    6078
有电梯    9342
未知     8257
Name: 小区, dtype: int64

In [87]:

house_fitment

Out[87]:

装修情况
其他     3239
毛坯      583
简装     8499
精装    11356
Name: 小区, dtype: int64

In [88]:

fitment=house_fitment.index.tolist()
count1=house_fitment.values.tolist()
directions=house_direction.index.tolist()
count2=house_direction.values.tolist()
bar = (
    Bar()
    .add_xaxis(fitment)
    .add_yaxis('', count1, category_gap = '50%')
    .reversal_axis()
    .set_series_opts(label_opts=opts.LabelOpts(position='right'))
    .set_global_opts(
        yaxis_opts=opts.AxisOpts(name='装修情况'),
        xaxis_opts=opts.AxisOpts(name='数量'),
        title_opts=opts.TitleOpts(title='装修情况/有无电梯玫瑰图(组合图)',pos_left='33%',pos_top="5%"),
        legend_opts=opts.LegendOpts(type_="scroll", pos_left="90%",pos_top="58%",orient="vertical")
    )
)

c2 = (
    Pie(init_opts=opts.InitOpts(
            width='800px', height='600px',
            )
       )
        .add(
        '',
        [list(z) for z in zip(directions, count2)],
        radius=['10%', '30%'],
        center=['75%', '65%'],
        rosetype="radius",
        label_opts=opts.LabelOpts(is_show=True),
        )
        .set_global_opts(title_opts=opts.TitleOpts(title='有/无电梯',pos_left='33%',pos_top="5%"),
                        legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%",pos_top="25%",orient="vertical")
                        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter='{b}:{c} \n ({d}%)'),position="outside")
    )
bar.overlap(c2)
bar.load_javascript()

Out[88]:

In [89]:

bar.render_notebook()

Out[89]:

In [90]:

df=house.groupby('装修情况')[['价格(万元)']].sum()
data1=df['价格(万元)'].values.tolist()

In [91]:

import pyecharts.options as opts
from pyecharts.charts import Grid, Boxplot, Scatter
x_data = fitment
y_data1= data1
s= Scatter()
# 添加横轴的数据
s.add_xaxis(xaxis_data=x_data)
# 添加纵轴的数据
s.add_yaxis(
    series_name='',
    y_axis=y_data1,
    label_opts=opts.LabelOpts(is_show=False),
)
s.set_global_opts(
        title_opts=opts.TitleOpts(title='装修与价格的散点图'),
        yaxis_opts=opts.AxisOpts(name='价格'),
        xaxis_opts=opts.AxisOpts(name='装修情况'),
    )
s.load_javascript()

Out[91]:

In [92]:

s.render_notebook()

Out[92]:

In [93]:

import pyecharts.options as opts
from pyecharts.charts import Grid, Boxplot, Scatter
df1=house.groupby('装修情况')[['面积(㎡)']].sum()
data2=df1['面积(㎡)'].values.tolist()
x_data = fitment
y_data2= data2
line=Line()
line.add_xaxis(xaxis_data=x_data)
line.add_yaxis(
    series_name='',
    y_axis=y_data2,
    label_opts=opts.LabelOpts(is_show=False),
)
line.set_global_opts(
        title_opts=opts.TitleOpts(title='装修与价格的折线图'),
        yaxis_opts=opts.AxisOpts(name='面积'),
        xaxis_opts=opts.AxisOpts(name='装修情况'),
    )
line.load_javascript()

Out[93]:

In [94]:

line.render_notebook()

Out[94]:

(5)二手房总价与面积散点图

In [95]:

s = (
    Scatter()
    .add_xaxis(house['面积(㎡)'].values.tolist())
    .add_yaxis('',house['价格(万元)'].values.tolist())
    .set_global_opts(xaxis_opts=opts.AxisOpts(name='面积(㎡)',type_='value'),
                    yaxis_opts=opts.AxisOpts(name='价格(万元)'),)
)
s.load_javascript()

Out[95]:

In [96]:

s.render_notebook()

Out[96]:

(6)二手房楼层分布柱状图

In [97]:

g1 =house.groupby('楼层')
house_floor = g1.count()['小区']
house_floor

Out[97]:

楼层
1        6
2       94
3      201
4      465
5     1070
6     7658
7      821
8      321
9      670
10     406
11     790
12     702
13     405
14     745
15     787
16    1033
17     373
18    1553
19     347
20     638
21     644
22     577
23     253
24     858
25     357
26     456
27     402
28     505
29     167
30     126
31      64
32      99
33      33
34      21
35      17
36       8
40       3
42       1
57       1
Name: 小区, dtype: int64

In [98]:

floor =house_floor.index.tolist()
count = house_floor.values.tolist()
bar = (
    Bar()
    .add_xaxis(floor)
    .add_yaxis('数量', count)
    .set_global_opts(
        title_opts=opts.TitleOpts(title='二手房楼层分布柱状缩放图'),
        yaxis_opts=opts.AxisOpts(name='数量'),
        xaxis_opts=opts.AxisOpts(name='楼层'),
        datazoom_opts=opts.DataZoomOpts(type_='slider')
    )
)
bar.load_javascript()

Out[98]:

In [99]:

bar.render_notebook()

Out[99]:

(7)房屋面积分布柱状图

In [100]:

area_level = [0, 50, 100, 150, 200, 250, 300, 350, 400, 1500]    
label_level = ['小于50', '50-100', '100-150', '150-200', '200-250', '250-300', '300-350', '350-400', '大于400']    
jzmj_cut = pd.cut(house['面积(㎡)'], area_level, labels=label_level)        
df_area = jzmj_cut.value_counts()
df_area

Out[100]:

50-100     13653
100-150     5809
150-200     1677
小于50        1562
200-250      545
250-300      226
300-350       94
大于400         56
350-400       55
Name: 面积(㎡), dtype: int64

In [101]:

area = df_area.index.tolist()
count = df_area.values.tolist()

bar = (
    Bar()
    .add_xaxis(area)
    .add_yaxis('数量', count)
    .reversal_axis()
    .set_series_opts(label_opts=opts.LabelOpts(position="right"))
    .set_global_opts(
        title_opts=opts.TitleOpts(title='房屋面积分布纵向柱状图'),
        yaxis_opts=opts.AxisOpts(name='面积(㎡)'),
        xaxis_opts=opts.AxisOpts(name='数量'),
    )
)
bar.load_javascript()

Out[101]:

In [102]:

bar.render_notebook()

Out[102]:

模型评价
根据面积和价格预测所要预测数据属于哪种装修情况

In [88]:

X=house[['面积(㎡)', '价格(万元)']]
from sklearn.neighbors import KNeighborsClassifier
y=house[['装修情况']]
knn=KNeighborsClassifier(n_neighbors=5)
knn.fit(X,y)##训练数据
x_test=pd.DataFrame({'面积(㎡)':[55,67,89,34],'价格(万元)':[788.8,789,2343,88]})###预测数据
x_test

Out[88]:

面积(㎡) 价格(万元)
0 55 788.8
1 67 789.0
2 89 2343.0
3 34 88.0

In [89]:

knn.predict(x_test)###预测结果

Out[89]:

array(['简装', '简装', '精装', '其他'], dtype=object)

In [90]:

house.columns

Out[90]:

Index(['市区', '小区', '户型', '朝向', '楼层', '装修情况', '电梯', '面积(㎡)', '价格(万元)', '年份'], dtype='object')
数据的分类转换

In [106]:

house.rename(columns={'市区':'region','小区':'disrict','户型':'room','朝向':'direction','楼层':'floor',
                      '装修情况':'renovation','电梯':'elevator','面积(㎡)':'area','价格(万元)':'price','年份':'year'},inplace=True)
house_data=house[['region', 'disrict', 'room', 'direction', 'renovation','elevator', 'area', 'year', 'floor']]
#对region进行转换
squ=house_data['region'].unique()
m={}
for i,work in enumerate(region):
    m[work]=i
    
#进行转换
house_data['region']=house['region'].map(m)
for col in house_data.columns[1:6]:
    print(col)
disrict
room
direction
renovation
elevator

In [107]:

####批量转换
for col in house_data.columns[1:6]:
    u=house_data[col].unique()
    def convert(x):
        return np.argwhere(u==x)[0,0]
    house_data[col]=house_data[col].map(convert)

In [108]:

house_data.head()

Out[108]:

region disrict room direction renovation elevator area year floor
0 9 0 0 0 0 0 52.0 2001 7
1 9 1 1 1 0 0 86.0 1999 10
2 9 2 2 2 0 1 65.0 1980 6
3 9 3 2 1 0 0 75.0 1998 12
4 9 4 3 1 0 1 115.0 1997 6

In [109]:

house1=house[['region','elevator','area','price']]
####批量转换
for col in house1.columns[0:2]:
    u=house1[col].unique()
    def convert(x):
        return np.argwhere(u==x)[0,0]
    house1[col]=house1[col].map(convert)

In [110]:

house1

Out[110]:

region elevator area price
0 0 0 52.0 343.0
1 0 0 86.0 835.0
2 0 1 65.0 430.0
3 0 0 75.0 610.0
4 0 1 115.0 710.0
... ... ... ... ...
23672 14 0 78.0 888.0
23673 14 1 45.0 405.0
23674 14 1 60.0 650.0
23675 14 1 61.0 470.0
23676 14 2 84.0 635.0

23677 rows × 4 columns

knn模型调参
  • 总体效果来看,n_neighbors=5时要好一点

In [133]:

from sklearn.model_selection import train_test_split
X=house1####数据
y=house1['price']###y===>目标
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
knn=KNeighborsClassifier(n_neighbors=3,weights="distance")
knn.fit(x_train,y_train.astype("int"))
y_=knn.predict(x_test)
result=y_==y_test
result.mean()

Out[133]:

0.7430320945945946

In [148]:

X=house1####数据
y=house1['price']###y===>目标
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
knn=KNeighborsClassifier(n_neighbors=5,weights="distance")
knn.fit(x_train,y_train.astype("int"))
y_=knn.predict(x_test)
result=y_==y_test
result.mean()

Out[148]:

0.7440878378378378

In [187]:

x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
knn=KNeighborsClassifier(n_neighbors=7,weights="distance")
knn.fit(x_train,y_train.astype("int"))
y_=knn.predict(x_test)
result=y_==y_test
result.mean()

Out[187]:

0.7356418918918919

In [230]:

x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
knn=KNeighborsClassifier(n_neighbors=10,weights="distance")
knn.fit(x_train,y_train.astype("int"))
y_=knn.predict(x_test)
result=y_==y_test
result.mean()

Out[230]:

0.730152027027027

In [245]:

x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
knn=KNeighborsClassifier(n_neighbors=15,weights="distance")
knn.fit(x_train,y_train.astype("int"))
y_=knn.predict(x_test)
result=y_==y_test
result.mean()

Out[245]:

0.7164273648648649
决策树模型

In [246]:

from sklearn.model_selection import train_test_split
X=house_data####数据
y=house['price']###y===>目标
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)#修正测试集和训练集的索引
for i in [x_train,x_test,y_train,y_test]:
    i.index = range(i.shape[0])
from sklearn.model_selection import cross_val_score
""""初始模型"""
from sklearn.model_selection import KFold
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import make_scorer
from sklearn.model_selection import GridSearchCV
clf = DecisionTreeRegressor(splitter='best',max_depth=12)
clf=clf.fit(x_train, y_train)
score_tr = clf.score(x_train,y_train)
score_te = clf.score(x_test,y_test)#测试集分数
score_tc= cross_val_score(clf,X,y,cv=10).mean()#使用交叉验证
print(score_tr,score_te,score_tc)
0.9531080066732065 0.7745982538131777 0.6047073569939521

In [247]:

tr = []
te = []
tc = []
N = 10
for i in range(N):
    clf = DecisionTreeRegressor( random_state=25
                                ,max_depth=i+1 #拟合不同最大深度的决策
                                ,criterion="friedman_mse"#尝试调参
                               )
    clf = clf.fit(x_train,y_train)
    score_tr = clf.score(x_train, y_train)#训练集分数
    score_te = clf.score(x_test,y_test)#测试集分数
    score_tc = cross_val_score(clf,X, y, cv=10).mean()#模型交叉验证分数
    tr.append(score_tr)
    te.append(score_te)
    tc.append(score_tc)
print(max(tc))###发现结果还比原来的好
0.6383923356782749

In [248]:

plt.plot ( range(1,N+1) ,tr,color="red" ,label="train")
plt.plot (range(1,N+1) ,te,color="blue" ,label="test")
plt.plot(range(1,N+1) ,tc,color="green",label="cross")
plt.xticks ( range (1,N+1))#横坐标标尺,只显示1-10。
plt.legend()
plt.xlabel("max_depth")
plt.ylabel("score")
plt.show()
线性回归

In [249]:

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X=house_data####数据
y=house['price']###y===>目标
x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)#修正测试集和训练集的索引
for i in [x_train,x_test,y_train,y_test]:
    i.index = range(i.shape[0])
# lr=LinearRegression(fit_intercept=False)
# lr.fit(x_train,y_train)
from sklearn.model_selection import cross_val_score
""""初始模型"""
from sklearn.model_selection import KFold
from sklearn.metrics import make_scorer
from sklearn.model_selection import GridSearchCV
lr = LinearRegression(fit_intercept=False)
lr=lr.fit(x_train, y_train)
score_tr = lr.score(x_train,y_train)
score_te = lr.score(x_test,y_test)#测试集分数
score_tc= cross_val_score(lr,X,y,cv=10).mean()#使用交叉验证
print(score_tr,score_te,score_tr)
0.6905104199409964 0.6829968035712277 0.6905104199409964

In [250]:

lr.predict(x_test)

Out[250]:

array([ 514.01980998,   16.55808561, 1177.51447509, ..., 1071.80962829,
        795.808886  ,  467.86695568])

In [251]:

house_data.columns

Out[251]:

Index(['region', 'disrict', 'room', 'direction', 'renovation', 'elevator',
       'area', 'year', 'floor'],
      dtype='object')

In [252]:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import sklearn
plt.style.use('ggplot')
from sklearn import tree
import sys
import os
import time
##忽略警告
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.family'] = ['SimHei']   #设置字体为黑体
plt.rcParams['axes.unicode_minus'] = False #解决保存图像时负号“-”显示为方块的问题
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score

In [112]:

data=pd.read_csv('E:/新建文件夹/实训/项目/二手房数据.csv',encoding='gbk')
data.head()

Out[112]:

市区 小区 户型 朝向 楼层 装修情况 电梯 面积(㎡) 价格(万元) 年份
0 朝阳 育慧里一区 1室0厅 西 7 精装 有电梯 52.0 343.0 2001
1 朝阳 大西洋新城A区 2室2厅 南北 10 精装 有电梯 86.0 835.0 1999
2 朝阳 团结湖路 2室1厅 东西 6 精装 无电梯 65.0 430.0 1980
3 朝阳 尚家楼48号院 2室1厅 南北 12 精装 有电梯 75.0 610.0 1998
4 朝阳 望京西园一区 3室2厅 南北 6 精装 无电梯 115.0 710.0 1997

In [114]:

data.info()

RangeIndex: 23677 entries, 0 to 23676
Data columns (total 10 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   市区      23677 non-null  object 
 1   小区      23677 non-null  object 
 2   户型      23677 non-null  object 
 3   朝向      23677 non-null  object 
 4   楼层      23677 non-null  int64  
 5   装修情况    23677 non-null  object 
 6   电梯      15420 non-null  object 
 7   面积(㎡)   23677 non-null  float64
 8   价格(万元)  23677 non-null  float64
 9   年份      23677 non-null  int64  
dtypes: float64(2), int64(2), object(6)
memory usage: 1.8+ MB

In [113]:

data.describe

Out[113]:

In [115]:

data.rename(columns={'市区':'region','小区':'disrict','户型':'room','朝向':'direction','楼层':'floor',
                      '装修情况':'renovation','电梯':'elevator','面积(㎡)':'area','价格(万元)':'price','年份':'year'},inplace=True)
data.head()

Out[115]:

region disrict room direction floor renovation elevator area price year
0 朝阳 育慧里一区 1室0厅 西 7 精装 有电梯 52.0 343.0 2001
1 朝阳 大西洋新城A区 2室2厅 南北 10 精装 有电梯 86.0 835.0 1999
2 朝阳 团结湖路 2室1厅 东西 6 精装 无电梯 65.0 430.0 1980
3 朝阳 尚家楼48号院 2室1厅 南北 12 精装 有电梯 75.0 610.0 1998
4 朝阳 望京西园一区 3室2厅 南北 6 精装 无电梯 115.0 710.0 1997

In [116]:

data1=data[['year','region','disrict','room','direction','renovation','elevator','floor','area','price']]
data1.loc[(data['floor']>=6)&(data["elevator"].isnull()),"elevator"]="有电梯"
data1.loc[(data['floor']<=6)&(data["elevator"].isnull()),"elevator"]="无电梯"
data0=data[(data["elevator"]=="有电梯")|(data["elevator"]=="无电梯")]

In [117]:

data1["room"]=data1["room"].apply(lambda x:x.replace("房间","室"))
data1=data1[~data1["room"].str.contains("卫")]#筛选不包含“卫"的数据
data1["room_num"]=data1["room"].apply(lambda x:x[0])
data1[ "hall_num" ]=data1[ "room" ].apply(lambda x:x[2])
特征工程

In [118]:

"""追加新特征,选用需要分析的属性列,调整属性列顺序"""
data1["perprice"]=round(data1["price"]/data1["area"],2)
data1=data1[["year" , "region", "disrict", "direction", "room", "room_num","hall_num", "floor", "elevator", "renovation", "perprice","area","price"]]

In [119]:

data1.head()###数据预览

Out[119]:

year region disrict direction room room_num hall_num floor elevator renovation perprice area price
0 2001 朝阳 育慧里一区 西 1室0厅 1 0 7 有电梯 精装 6.60 52.0 343.0
1 1999 朝阳 大西洋新城A区 南北 2室2厅 2 2 10 有电梯 精装 9.71 86.0 835.0
2 1980 朝阳 团结湖路 东西 2室1厅 2 1 6 无电梯 精装 6.62 65.0 430.0
3 1998 朝阳 尚家楼48号院 南北 2室1厅 2 1 12 有电梯 精装 8.13 75.0 610.0
4 1997 朝阳 望京西园一区 南北 3室2厅 3 2 6 无电梯 精装 6.17 115.0 710.0

In [127]:

figl=plt.figure(figsize=(15,15))#设置图窗口
import seaborn as sns
sns.barplot( x='region',y='perprice',palette="Blues_d",data=data1)#统计北京各大区二手房每平米单价
plt.tick_params (axis='x' ,labelsize=20)
plt.tick_params ( axis='y' ,labelsize=20)
plt.xlabel('区域' ,fontsize=30)
plt.ylabel('每平米单价(均价)',fontsize=30)

Out[127]:

Text(0, 0.5, '每平米单价(均价)')

In [128]:

figl=plt.figure(figsize=(15,15))#设置图窗口
sns.boxplot(x='region',y='price',data=data1)
plt.tick_params(axis='x' ,labelsize=20)
plt.tick_params(axis='y' ,labelsize=20)
plt.xlabel('区域',fontsize=30)
plt.ylabel( '二手房总价',fontsize=30)
plt.show()

In [131]:

"""面积分析"""
sns.distplot(data['area'],bins=20,color="skyblue")#面积分布情况(直方图)
plt.tick_params(axis='x' ,labelsize=15)
plt.tick_params(axis='y' ,labelsize=15)
plt.xlabel('area',fontsize=20)
plt.ylabel( '',fontsize=20)
plt.show()

In [134]:

plt.figure(figsize=(40,40))#设置图窗口
fig3,[ax1,ax2]=plt.subplots(2,1)
df_layout=data.groupby("room")["area"].count().sort_values(ascending=False).to_frame ().reset_index()
sns.barplot(y="room",x="area",data=df_layout.head(20) , ax=ax1,orient="h")
ax1.set_xlabel("数量" ,fontsize=12)
ax1.set_ylabel("户型",fontsize=12)
sns.barplot( x='room',y='perprice',data=data1,ax=ax2)#统计各户型二手房每平米单价
ax2.tick_params (axis='x' ,labelsize=6)
ax2.tick_params (axis='y' ,labelsize=6)
ax2.set_xlabel('户型',fontsize=10)
ax2.set_ylabel( '每平米单价(均价)',fontsize=10)
plt.show()

In [135]:

"""年份分析"""
fig4=plt.figure()
ax1=plt.subplot2grid((2,1),(0,0))#设置第一张子图,位置0,0
ax2=plt.subplot2grid((2,1),(1,0))#设置第二张子图,位置0,1
sns.regplot( x="year" , y="price" ,data=data1,ax=ax1)
sns.barplot(x="year",y="price",data=data1,ax=ax2)
ax2.tick_params(axis='x' ,labelsize=4)
plt.show()

二、源码文件

链接:https://pan.baidu.com/s/15N8ESHjAU58ZyL39VOgbpQ 
提取码:yyss

html格式源码文件:

链接:https://pan.baidu.com/s/1LM2ZLQElIN7m2wc5UqMiOA 
提取码:yyss

所采用的数据:

链接:https://pan.baidu.com/s/1QSiS0Is57nZmRVUhiDwKtg 
提取码:yyss

三、作者有话

建议提取html源码格式文件,自己试着在jupyter lab中运行,此上面运行出的图片就不展示了,本人超级懒,懒得截图。

你可能感兴趣的:(python,开发语言)