基于Python数据分析的西安碑林区租房攻略:如何找到最适合自己的房子

在寻找租房的过程中,我们面临着各种各样的问题。如何快速地找到合适的房源?如何确定房租的合理价格?这些问题一直以来都困扰着我们。随着Python等工具的广泛使用,我们可以更加高效地解决这些问题。使用Python进行租房数据分析,我们可以从海量数据中提取有用信息,预测租金价格,评估房源优劣等等。Python不仅是一种编程语言,更是一种分析和解决问题的利器,为我们提供了更多更优的解决方案。

数据说明

时间节点:2022.2

去掉重复后数据条数:2117条

爬取数据:

import requests  # 数据请求模块
import parsel  # 数据解析模块

'''
url:链接,
title:标题,
type:租赁方式,
layout:户型,
rent_area:面积,
rent_price:租金,
distance:距最近地铁站距离,
dist:所在区,
bc:二级区(商圈),
location:地址,
lng:经度,
lat:纬度
# '''
f = open('xablzufang.csv', 'a', encoding='utf-8-sig')
f.write('url,title,type,layout,rent_area,rent_price,distance,dist,bc,location,lng,lat\n')

headers = {

}


def spider(url):
    htmldata = requests.get(url=url, headers=headers).text
    # print(htmldata)
    select = parsel.Selector(htmldata)
    info = {}
    info['url'] = url
    info['title'] = (select.xpath('/html/body/div[3]/div[1]/div[3]/p/text()').get()).replace("\n", '').strip()  # 标题
    info['type'] = select.xpath('//*[@id="aside"]/ul/li[1]/text()').get()  # 租赁方式
    info['layout'] = select.xpath('//*[@id="aside"]/ul/li[2]/text()').get()[0:5]  # 户型
    info['rent_area'] = select.xpath('//*[@id="info"]/ul[1]/li[2]/text()').get()[3:-1]  # 面积
    info['rent_price'] = select.xpath('/html/body/div[3]/div[1]/div[3]/div[2]/div[2]/div[1]/span/text()').get()  # 租金
    info['distance'] = select.xpath('/html/body/div[3]/div[1]/div[4]/ul[2]/li[1]/span[2]/text()').get()  # 最近的地铁站距离
    dist = select.xpath('/html/body/div[3]/div[1]/div[10]/p[1]/a[2]/text()').get()[:-2]  # 所在区
    info['bc'] = select.xpath('/html/body/div[3]/div[1]/div[10]/p[1]/a[3]/text()').get()[:-2]  # 二级区域
    xq = select.xpath('/html/body/div[3]/div[1]/div[10]/h1/a/text()').get()[:-2]  # 小区名称
    location = '西安市' + dist + '区' + xq
    info['dist'] = dist
    info['xq'] = xq
    info['location'] = location
    # 调用百度api获得地址对应经纬度
    base = "http://api.map.baidu.com/geocoder?address=" + location + "&output=json&key=----------------"  # key在百度地图开放平台获取
    response = requests.get(base)
    answer = response.json()
    info['lng'] = answer['result']['location']['lng']
    info['lat'] = answer['result']['location']['lat']
    try:
        f.write(
            '{url},{title},{type},{layout},{rent_area},{rent_price},{distance},{dist},{bc},{location},{lng},{lat}\n'.format(
                **info))
    except:
        print("写入错误!")
    print('正在抓取:', info['url'], info['title'])


# 在一级页面获取链接
hreflist = []
for i in range(1, 101):
    ljurl = 'https://xa.lianjia.com/zufang/pg' + str(i) + 'rs%E7%A2%91%E6%9E%97%E5%8C%BA/?showMore=1'
    res = requests.get(url=ljurl, headers=headers)
    selector = parsel.Selector(res.text)
    href = selector.css('.content__list--item--title a::attr(href)').getall()
    hreflist.extend(href)
for index in hreflist:
    index = 'https://xa.lianjia.com' + index
    try:
        spider(index)
    except:
        print('链接访问不成功')

碑林区租房房源分布怎么样?

首先来看一张图,这是我将西安市碑林区的租房房源根据经纬度以小点的形式投射在地图上。可以看出比较分散,无法找到明显的聚集区域,所以我们依据所在区域/商圈进行统计分析。

# 统计不同地区的房源数量
counts = df['bc'].value_counts()

# 绘制条形图
plt.bar(counts.index, counts.values)
plt.title('碑林区租房房源分布')
plt.xlabel('地区')
plt.ylabel('房源数量')
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] # 设置字体
plt.savefig('房源数量条形图.png')  # 保存图像
plt.show()  # 显示图像

根据上图,可以看出南稍门和城东的房源数量远高于其他区域。这说明南稍门和城东是碑林区相对比较受欢迎的居住区域,房源供应也相应较多。相比之下,黄雁村、李家村、城西和城内的房源数量相对较少。需要注意的是,“城内”这个标签可能是由于房东在上传数据时的不规范造成的。结合碑林区地图可知,碑林区在城墙内的部分包括城东和城西,因此仅依据“城内”这一标签无法确定具体位置。

碑林区租金分布怎么样?

分析碑林区的租金分布,我们可以使用Python的数据分析工具,例如pandas、numpy、matplotlib等,对数据进行预处理和可视化,进而得出租金的分布情况。我绘制了绘制直方图或箱线图等方式来展示碑林区租金的分布情况,以及不同租金区间的租房数量。

# 按地区分组,并计算平均租金
grouped = df.groupby('bc').mean()['aver_price']

# 按平均租金进行排序
grouped = grouped.sort_values()

# 绘制条形图
fig, ax = plt.subplots(figsize=(8,6))
ax.barh(grouped.index, grouped.values)
ax.set_xlabel('平均租金(元/平米·月)')
ax.set_ylabel('地区')
ax.set_title('不同地区平均租金')
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] # 设置字体
plt.tight_layout()
plt.savefig('aver_price_by_bc.png')
plt.show()

# 绘制箱线图
plt.figure(figsize=(8, 6))
sns.boxplot(x='bc', y='aver_price', data=df, order=grouped['bc'])
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei']
plt.xlabel('地区')
plt.ylabel('平均租金')
plt.title('不同地区平均租金的箱线图')
plt.savefig('aver_price_boxplot.png')
plt.show()

通过对每个区域的租金进行分析,可以发现南稍门地区的房屋每平米租金相对较高,甚至出现了每平米租金超过200元的房屋;城东、李家村和黄雁村的房屋每平米租金相对较低,但是在其内部租金范围差距大。同时,通过箱线图的分析可以发现,南稍门、城东、李家村和黄雁村的房屋每平米租金都存在离群值,说明在这些地区还存在一些高价或低价房源,需要谨慎选择。

距离最近地铁站距离和租金的关系

距离地铁站越近,交通便利程度越高,房租应该越高,那么西安碑林区的这些出租房符合这一规律吗?为了弄清楚这一问题,我使用Python先绘制了距离最近地铁站距离与每平米租金的散点图,并计算了他们的相关系数。

# 数据预处理
# 去掉距离字段中的'm'
df['distance'] = df['distance'].str.strip('m')

# 删除值为'None'的整行数据
df_clean = df[df['distance'] != 'None']

# 将distance字段转换为float类型
df_clean['distance'] = df_clean['distance'].astype(float)

# 将aver_price字段转换为float类型
df_clean['aver_price'] = df_clean['aver_price'].astype(float)

# 绘制散点图
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] # 设置字体
plt.scatter(df_clean['distance'], df_clean['aver_price'])
plt.xlabel('距离最近地铁站距离')
plt.ylabel('每平方米租金')
plt.title('距离最近地铁站距离与每平方米租金的关系')
plt.savefig('distance_price_scatter.png')
plt.show()

# 计算距离最近地铁站距离和每平方米租金的相关系数
corr = np.corrcoef(df_clean['distance'], df_clean['aver_price'])[0][1]

# 输出相关系数和p-value
print('距离最近地铁站距离和每平方米租金的相关系数为: {:.2f}'.format(corr))

虽然根据散点图无法观测到他们的关系,但是经计算,距离最近地铁站距离和每平方米租金的皮尔森相关系数为-0.18,呈现负相关关系。这表明,距离最近地铁站越近,每平方米租金越高的趋势较为明显。

房屋面积和租金的关系

房屋越大,租金越多?那么房屋越大,每平米租金也会越多吗?同样,我们使用Python把所有房源的面积和每平米均价绘制出关系图。

# 绘制散点图
plt.rcParams['font.sans-serif'] = ['Kaitt', 'SimHei'] # 设置字体
plt.scatter(df_clean2['rent_area'], df_clean2['aver_price'], alpha=0.5)
plt.xlabel('租赁面积', fontsize=14)
plt.ylabel('每平米租金', fontsize=14)
plt.xticks(range(0, 61, 5))
plt.title('租赁面积与每平米租金散点图', fontsize=16)

# 保存图片
plt.savefig('面积-租金scatter_plot.png')

# 显示图形
plt.show()

我们可以看到,房屋面积越大,每平米均价越低。特别地,在房屋面积小于20平米的情况下,每平米租金最贵。当然,由于数据中包含合租类型的房屋,合租类型房屋面积一般较小,这部分数据可能存在影响,因此我们将合租和整租分开进行绘图,如下。

分别对整租和合租房源数据进行观察,仍然可以发现房屋面积越大,每平米均价越低的趋势。

回归建模

我们使用pandas和scikit-learn库对一个包含2000多条房屋租赁数据的数据集进行了处理和建模。我们首先对数据进行了一些预处理,包括将距离的"None"值替换为"100000000"并将其转换为数值类型,将租赁面积的值缩放到0到1的范围内,使用OneHotEncoder将租赁类型和区域编码为二进制形式。然后,我们使用train_test_split将数据集拆分为训练集和测试集,并使用scikit-learn库中的线性回归模型训练了一个模型。我们还使用测试集评估了模型的性能,计算了预测结果与实际值之间的平均绝对误差。最后,我们可以使用训练好的模型对新数据进行预测,例如给定一个新房屋的租赁类型、区域、距离和租赁面积等特征,可以使用模型预测其租金价格。

import pandas as pd
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error

# 从csv文件中读取数据集
data = pd.read_csv('xablzufang.csv',encoding='utf-8-sig')
col=['type','bc','distance','rent_area','rent_price']
data=pd.DataFrame(data,columns=col)

# 将"None"替换为"100000000",并将距离转换为数字类型
data["distance"] = data["distance"].replace("None", "100000000")
data["distance"] = data["distance"].str.replace("m", "").astype(float)

# 将rent_area列的值缩放到0到1的范围内
data["rent_area"] = data["rent_area"] / 5000.0

# 使用OneHotEncoder将类型和区域编码为二进制形式
encoder = OneHotEncoder(sparse=False)
data_encoded = pd.DataFrame(encoder.fit_transform(data[["type", "bc"]]))
data_encoded.columns = encoder.get_feature_names(["type", "bc"])
data = pd.concat([data, data_encoded], axis=1)

# 删除原始的"type"和"bc"列
data = data.drop(["type", "bc"], axis=1)

# 将数据集拆分为训练集和测试集
train_data, test_data = train_test_split(data, test_size=0.2)

# 训练线性回归模型
model = LinearRegression()
model.fit(train_data.drop("rent_price", axis=1), train_data["rent_price"])

# 对测试集进行预测,并计算MAE
predictions = model.predict(test_data.drop("rent_price", axis=1))
mae = mean_absolute_error(test_data["rent_price"], predictions)
print("MAE:", mae)

我们计算所得MAE=838.4235 ,MAE是一个衡量预测值和真实值之间平均绝对误差的指标,根据该模型的MAE 值对模型的预测精度进行初步评估。MAE 是指平均绝对误差,它表示模型的平均预测误差的大小,越小表示模型的预测精度越高。因此,MAE=838.4235 意味着模型的预测误差较大,此模型较为粗糙。

猜你喜欢

转载自blog.csdn.net/Gauss_m10/article/details/129218766