美文网首页
上海市租房信息分析

上海市租房信息分析

作者: 扬道 | 来源:发表于2017-06-28 18:24 被阅读0次

    项目背景

    随着毕业季和暑假的到来,各大城市又要迎来一批小鲜肉了,摆在大家面前的第一件事就是关于住宿的事了。众所周知,北上广的房价对于大多数刚毕业的或者实习的同学们来说,即使拼爹也是比较难马上定居下来的,所以租房就成了大多数人必须的选择。本项目主要通过对链家网上海地区租房信息的爬取获得数据,进行数据分析后,给出合理的建议。

    项目简介

    本次项目主要是利用爬虫爬取链家网上关于租房方面的信息,然后通过数据清洗和加工,从而进行一些数据探索和分析,从而对整个上海租房市场现状有个了解,并且对在上海租房做出自己的建议。

    数据来源和数据集

    本项目所使用的数据集全部来自链家网,是使用 requests + BeautifulSoup 的方法对页面进行抓取和数据提取。通过使用 requests 库对链家网租房列表页进行抓取,通过 BeautifulSoup 对页面进行解析,并从中获取房源小区,面积,户型和价格等数据。

    具体爬取过程见:Python爬取链家网上海市租房信息

    本次爬取信息的时候,主要获得了以下信息:
    内容字段小区名称 name、户型 room_type、面积 size、区县 region、街道地段 area、楼层 louceng、朝向 chaoxiang、月租价格 price、地铁线subway、到地铁线的距离distance、标题title等。

    目的

    主要是通过实际的数据分析对上海租房市场做一个简单的介绍,给有意向在上海租房的小伙伴们提供一些参考性的意见。具体来说,主要针对以下几个问题:
    1、房源的地域性分布
    2、户型的影响
    3、楼层的影响
    4、地铁及到地铁的距离的影响
    5、不同的宣传标题是否会对销售有影响?有哪些关键词?

    技术和工具

    本项目主要分为两大部分:
    第一部分是数据爬取,采用的是 requests + BeautifulSoup。
    第二部分是数据分析,以 Python 编程语言为基础。数据分析部分主要使用 pandas 作为数据整理和统计分析的工具,matplotlib 用于图形的可视化,seaborn 库包用于图形美化。在进行宣传标题分析的时候,使用了jieba 作为分词工具包,并使用 wordcloud 包制作词云。

    数据整理和清洗

    # -*- coding: utf-8 -*-
    import pandas as pd
    import numpy as np
    import seaborn as sns
    import jieba
    import jieba.analyse
    from wordcloud import WordCloud
    from matplotlib import pyplot as plt
    %matplotlib inline
    plt.rcParams['font.sans-serif']=['SimHei']
    
    #从csv文件中读取数据并存入DataFrame中
    df = pd.read_csv('D:/jupyter/lianjia.csv',sep = ',',encoding='gbk')  #必须得转码,否则后面显示乱码
    
    #清理重复行
    drop_df = df.drop_duplicates()
    
    #初步观察数据情况
    drop_df.info()
    drop_df.describe()
    drop_df.head(5)
    
    1.png 2.png

    经过数据的清洗和整理,我们可以看出,上海一共有39774套房源,平均租金为8142元/月,怎么会这么高,经过发现有个别58万/月的数据,同时楼层值为地上的房源都是别墅,数量少且租价高,需要对其再进行清洗。并且租房面积和租金有着密切的关系,改用每平方米月租金衡量(例如:总的平均月租金为8142.84/97.66=83.38元/平方米)。同时根据《上海市房屋租赁条例》,居住使用人的人均居住面积不得低于5平方米。针对以上几点对数据进行整理:

    #补充缺失值
    drop_df = drop_df.fillna({'distance':0,'subway':u'非地铁房'})
    
    #清理异常值,选取租金和租房面积合适的房源
    drop_df = drop_df[drop_df['louceng'] != u'地上'] #清理高价别墅房源
    drop_df = drop_df[drop_df['price'] < 25000] #清理少数异常高价房源
    drop_df = drop_df[drop_df['size'] > 5]  #根据上海市要求,清理租房面积小于5平米的房源
    
    #给表格添加每平方米月租金列
    Price_average = (drop_df['price'] / drop_df['size']).round(2)
    drop_df['Price_average'] = Price_average
    drop_df.info()
    drop_df.head(5)
    
    3.png

    房源的地域性分布情况

    #观察地域分布情况
    count_by_region = drop_df.groupby(['region'])['name'].count()
    
    figure = plt.figure(figsize = (12,8))
    ax1 = plt.subplot(111)
    rect = ax1.bar(np.arange(len(count_by_region)),count_by_region.values,width =0.6)
    
    #设置x轴刻度标签
    def auto_xticks(rects,xticks):
        x = []
        for rect in rects:
            x.append(rect.get_x() + rect.get_width()/2)
        x = tuple(x)
        plt.xticks(x,xticks)
    auto_xticks(rect,count_by_region.index)
    
    #设置数据标签数:
    def auto_tag(rects, data = None, offset = [0,0]):
        for rect in rects:
            try:
                height = rect.get_height()
                plt.text(rect.get_x() + 0.1, 1.01 * height, '%s' % int(height))
            except AttributeError:
                x = range(len(data))
                y = data.values
                for i in range(len(x)):
                    plt.text(x[i] - 0.2 + offset[0],y[i] + .05 + offset[1],y[i])
    auto_tag(rect)
    plt.legend(rect,[u'房源数量'],loc = 'upper left')
    
    #各区每平方月租均价
    Price_per_square_meter = (drop_df.groupby(['region'])['Price_average'].mean()).round(2)
    
    #绘制每平米月租金折线图
    ax2 = ax1.twinx()
    x = [i for i in range(len(Price_per_square_meter))]
    y = Price_per_square_meter.values
    rect2 = ax2.plot(x,y,'mo-', label = 'right')
    auto_tag(rect2,Price_per_square_meter)
    auto_xticks(rect,Price_per_square_meter.index)
    
    ax1.set_title(u'不同区域的房源数量及每平米月租金')
    plt.legend(rect2,[u'每平米月租金'],loc = 'upper right')
    
    4.png

    从上图可以看出四分之一以上的房源位于浦东,相对于其他地方浦东似乎更容易找到租住的房子,另外闵行,徐汇也有着较多的选择,但是根据每平米租金来算,徐汇,长宁的租金更贵,所以综合来看,浦东和闵行似乎更好一点,选择比较多,租金也是在可以接受的范围内。

    #观察各区的月租金箱形图
    count_by_region_rent = drop_df.groupby(['region'])['price']
    mm =[]
    for group in count_by_region.index:
        v = count_by_region_rent.get_group(group).values
        mm.append(v)
    fig = plt.figure(figsize = (10,10))
    ax3 = plt.subplot(111)
    rect3 = ax3.boxplot(mm)
    #设置标签
    ax3.set_xticklabels(count_by_region.index)
    plt.yticks(range(0,30000,2500))
    
    5.png

    从箱形图中可以看出各区的月租分布差距比较大,这和上海的一线城市的地位是相同的,不仅有新来的求职者,也有工作多年的白领和成功人士,从而导致了房租的分布差距大。经过对比上海市政规划可以看出,其中徐汇、长宁、静安等月租较高的原因可能是:
    1、徐汇区有上海最多的各式花园洋房,决定了区域内租房市场多为高端租房。
    2、上海最集中的涉外高标准住宅商务办公综合区、虹桥路沿线和西郊宾馆周围建有许多幢花园别墅,上海市大多数外国领事馆和外交官的官邸分布在长宁,果然是真正的土豪租房优选区域。
    3、静安是上海出名的小资区域,其中有多处名人故居,文化气息浓郁;而且其中高档小区与写字楼都很多,导致了租金一直居高不下等。

    户型分布情况

    #查看户型分布情况
    count_by_room_type = drop_df.groupby(['room_type'])['name'].count().sort_values(ascending = False)
    
    figure = plt.figure(figsize=(15,9))
    ax4 = plt.subplot(111)
    rect4 = ax4.bar(np.arange(len(count_by_room_type)),count_by_room_type.values,width =0.4)
    auto_tag(rect4)
    auto_xticks(rect4,count_by_room_type.index)
    ax4.set_title(u'户型分布情况')
    plt.legend(rect4,[u'房源数量'],loc = 'upper right')
    
    6.png

    我们发现只有少数几种的户型数量比较多,其余的都非常少,明显属于长尾分布类型(严重偏态),所以,考虑将800套一下的户型统统归为一类。

    # 把低于八百套的房型设置为其他
    drop_df2 = drop_df.copy()
    for i in range(len(drop_df2['room_type'])):
        if drop_df2['room_type'].iloc[i] not in [u'2室2厅',u'2室1厅',u'3室2厅',u'1室1厅',u'4室2厅',u'3室1厅',u'1室0厅',u'1室2厅',u'2室0厅']:
            drop_df2['room_type'].iloc[i] = u'其他'
    new_room_type_count = drop_df2.groupby(['room_type'])['name'].count()
    
    figure = plt.figure(figsize=(15,9))
    ax5 = plt.subplot(111)
    rect5 = ax5.bar(np.arange(len(new_room_type_count)),new_room_type_count.values,width =0.4)
    auto_tag(rect5)
    auto_xticks(rect5,new_room_type_count.index)
    plt.legend(rect5,[u'房源数量'],loc = 'upper right')
    #每个地区的单位面积月租均价
    Price_per_by_room = (drop_df2.groupby(['room_type'])['Price_average'].mean()).round(2)
    
    #绘制每平米月租金折线图
    ax6 = ax5.twinx()
    x = [i for i in range(len(Price_per_by_room))]
    y = Price_per_by_room.values
    rect6 = ax6.plot(x,y,'mo-', label = 'right')
    auto_tag(rect6,Price_per_by_room)
    plt.legend(rect6,[u'每平米月租金'],loc = 'upper center')
    ax5.set_title(u'户型分布情况')
    
    7.png

    从上图可以看出2室和3室的房源数量最多,考虑到舒适性和生活的便利性,同时根据租金情况来看,不妨选择2室1厅,2室2厅合租的房源性价比更高。

    楼层的影响

    #查看楼层分布情况
    count_by_louceng = drop_df.groupby(['louceng'])['name'].count().sort_values(ascending = False)
    figure = plt.figure(figsize = (5,5))
    ax7 = plt.subplot(111)
    rect7 = ax7.bar(np.arange(len(count_by_louceng)),count_by_louceng.values,width =0.4)
    auto_tag(rect7)
    auto_xticks(rect7,count_by_louceng.index)
    ax7.set_title(u'楼层数量分布情况')
    
    8.png
    #观察各区的月租金箱形图
    count_by_louceng_rent = drop_df.groupby(['louceng'])['price']
    nn =[]
    for group in count_by_louceng.index:
        v = count_by_louceng_rent.get_group(group).values
        nn.append(v)
    fig = plt.figure(figsize = (5,5))
    ax9 = plt.subplot(111)
    rect9 = ax9.boxplot(nn,whis = 1)
    #设置标签
    ax9.set_xticklabels(count_by_louceng.index)
    plt.yticks(range(0,20000,3000))
    
    9.png

    由上图可以看出低中高楼层对房屋租金的影响不是特别大,但是高层的房屋价格相对于低层的房子要稍微便宜一点,可能与通勤时间有关。如果不在意每天爬楼的通勤时间,选择高区或者是个不错的选择。

    地铁及到地铁的距离的影响

    上海地铁是一线城市中最发达的,所以如果能够在地铁附近租房对日常的出行都有很大的便利,所以地铁房的价格也必然增加。

    #查看地铁分布情况
    count_by_subway = drop_df.groupby(['subway'])['name'].count().sort_values(ascending = False)
    Price_average_of_subway = (drop_df.groupby(['subway'])['Price_average'].mean()).round(2)
    
    angles = np.linspace(0, 2 * np.pi, len(Price_average_of_subway), endpoint=False)
    data = np.concatenate((Price_average_of_subway.values, [Price_average_of_subway.values[0]])) # 闭合
    angles = np.concatenate((angles, [angles[0]])) # 闭合
    
    fig = plt.figure(figsize=(8,8))
    ax = fig.add_subplot(111, polar=True)# polar参数!!
    ax.plot(angles, data, 'bo-', linewidth=2)# 画线
    ax.set_thetagrids(angles * 180/np.pi, Price_average_of_subway.index)
    ax.set_title(u'上海各地铁线附近房源租金雷达图')
    ax.set_rlim(0,130)
    ax.grid(True)
    for i in range(len(Price_average_of_subway)):
        plt.text(angles[i]+0.01,data[i]+5,data[i])
    plt.show()
    
    10.png

    4号线、10号线、13号线的房源价格最高,相对而言,非地铁房的价格较低,绝大多数都是低价房和少部分的高档别墅,这与我们的认知预测相符。我们单独的取房源最多的各区的地铁分布情况拿出来看:

    j=0
    for i in count_by_region.sort_values(ascending =False)[:4].index:
        j += 1
        #查看各区地铁分布情况
        count_by_subway1 = drop_df[drop_df['region']== i].groupby(['subway'])['name'].count().sort_values(ascending = False)
        Price_average_of_subway1 = (drop_df[drop_df['region']== i].groupby(['subway'])['Price_average'].mean()).round(2)
        angles = np.linspace(0, 2 * np.pi, len(Price_average_of_subway1), endpoint=False)
        data = np.concatenate((Price_average_of_subway1.values, [Price_average_of_subway1.values[0]])) # 闭合
        angles = np.concatenate((angles, [angles[0]])) # 闭合
    
        fig = plt.figure(figsize=(20,20))
        ax = fig.add_subplot(2,4,j, polar=True)# polar参数!!
        ax.plot(angles, data, 'bo-', linewidth=2)# 画线
        ax.set_thetagrids(angles * 180/np.pi, Price_average_of_subway1.index)
        ax.set_title(i+u'各地铁线附近房源租金雷达图')
        ax.set_rlim(0,150)
        ax.grid(True)
        for i in range(len(Price_average_of_subway1)):
            plt.text(angles[i]+0.01,data[i]+5,data[i])
    
    11.png 12.png

    由各区地铁雷达图可以看出不同区的地铁线路不同,价格也不一样,但是非地铁房的价格依然相对于地铁房的价格要便宜不少,如果公司离住的地方很近,没有地铁需求的话,可以找非地铁房比较划算。

    #以浦东新区6号线为例,查看到地铁站距离对租金的影响
    data_of_distance = drop_df[drop_df['region'] == u'浦东']
    data_of_distance = data_of_distance[data_of_distance['subway'] == u'6号线']
    dd = data_of_distance.sort_values(by = ['distance'])
    #画散点图
    fig = plt.figure(figsize = (10,9))
    ax1 = fig.add_subplot(111)
    ax1.scatter(dd['distance'].values,dd['Price_average'].values) 
    plt.xlabel(u'到地铁站距离')
    plt.ylabel(u'租金')
    ax1.set_title(u'地铁站距离对租金影响图')
    
    13.png

    由上图可以看出到地铁站的距离多在350m-750m之间,且在此距离内租金也相对较高一点。

    不同的宣传标题关键词的影响

    #处理title字段
    #抽取关键词
    def key_words(text):
        key_words = jieba.analyse.extract_tags(text,topK = 20,withWeight = False,allowPOS=())
        return key_words
    
    drop_df['key_words'] = drop_df['title'].apply(key_words)
    
    #创建一个文本,将关键词列表全部写入该文本
    def new_text(wordlist):
        f =open('D:/jupyter/wordlist_text.txt','a')
        for word in wordlist:
            f.writelines((word + u',').encode('utf-8'))
        f.close()
        
    drop_df['key_words'].apply(new_text)
    
    text = open('wordlist_text.txt','r').read()
    text = unicode(text,encoding = 'utf-8') #必须将utf-8转码为unicode中间值才能生成词云
    my_wordcloud = WordCloud(width = 800,height = 400,background_color= 'white').generate(text) #读入文本写入词云
    fig = plt.figure(figsize =(10,8))
    plt.imshow(my_wordcloud)
    plt.axis('off')
    plt.show()
    
    14.png

    从词云上可以看出,宣传标题很大程度上反映了租客们的需求和关注点,地铁沿线,交通便利,生活方便,光线充足,视野开阔等是大家比较关注的一些租房要素,同时改善,精致等也有不小的比例,这类房源的客户对象应该是工作几年后有了积蓄后的改善性租房。同时一链倾城的出现频率接近最高,应该是与链家网的“一链倾城,有爱有家”的宣传口号有关系。

    分析结论

    通过上面的分析,我们可以得到的结论有这些:
    1、租房的房源主要分布在浦东新区和闵行、宝山等郊区,租金也相对城区便宜很多;
    2、徐汇、长宁、静安等中心城区的租房价格仍高居不下;
    3、户型多为2室1厅,2室2厅,3室两厅,比较适合居家常驻,可以选择2室,3室的合租相对更加便利些;
    4、低中高楼层对房屋租金的影响不是特别大,但是高层的房屋价格相对于低层的房子要稍微便宜一点,所以如果不在意每天爬楼的通勤时间,选择高区或许是个不错的选择;
    5、不同城区的地铁线路不同,租金价格也不一样,非地铁房的价格要更加便宜;
    6、地铁房到地铁站的距离多为350m—750m之间,租金也相对高一点;
    7、选择租房的时候不妨多实地看看,地铁沿线,交通便利,生活方便,光线充足,视野开阔都是很好的衡量点。

    总而言之,大家可以根据公司的地点选择合适的区域进行租房,能租在公司附近是最优的选择,如果无法在公司附近租房且手头较紧,浦东和闵行等区或许是个不错的选择,同时地铁比较发达,交通也比较方便。希望大家都能租到自己合适的房子。

    相关文章

      网友评论

          本文标题:上海市租房信息分析

          本文链接:https://www.haomeiwen.com/subject/dcqscxtx.html