Airbnb数据分析Project

其实是前年年底做的,最近重新整理一下放上来啦!数据和代码都在Github可以找得到,会逐步更新~

Github

Data Overview

这个Project包括3个数据集:

  • calendar:历史时间数据,包含listing_id和price
  • listings_details:房源具体信息
  • reviews_details:租客评论的信息

Data Preparation

listings_details数据集:

import os
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt#Dataset: listings_details
listings_details = pd.read_csv("listings_details.csv")#check columns: 106
listings_details.columns#check length: 55501
len(listings_details)#number of listing: 8806
num = len(pd.unique(listings_details['id']))
print(num)

读入数据之后,查看每列数据的名称。这一步我专门有做一张表把每个变量的名称,类型,是否有空值和具体的含义方便查看,因为变量实在是太多了。

接下来,我注意到这个数据含有爬虫的具体日期,这个可以反应数据收集的时间,以及这段时间Airbnb波士顿地区房源数量的变化(如下图),同时最最重要的是我们可以根据这个信息筛选出最新的房源数据(因为有重复抓取的)。

#check scrape details
listings_details['calendar_last_scraped'].value_counts()
num_listings = pd.DataFrame(listings_details['calendar_last_scraped'].value_counts()[:9,])
num_listings['month'] = pd.DatetimeIndex(num_listings.index).month
num_listings = num_listings.sort_values('month', ascending=True)#plot
fig,ax = plt.subplots(1,1)
x = num_listings['month']
y = num_listings['calendar_last_scraped']
ax.plot(x, y, color = '#FF5A5F')
ax.set_title("Number of listings by months")
ax.set_xlabel('Months')
ax.set_ylabel('Number of listings')
ax.set_ylim([3000,6500])
plt.show()

然后我们就可以把每个房源最新的数据挑出来:

#keep only the lastest scraped data of listings
listings_details['calendar_last_scraped'] = pd.to_datetime(listings_details['calendar_last_scraped'])
listings_details = listings_details.sort_values(by=['calendar_last_scraped']).drop_duplicates(subset='id', keep='last')
#check
assert len(listings_details) == num

之后我们考虑数据集的空值和去掉哪些列,先看空值。

#check nan
listings_details.isnull().values.any()
listings_details.isnull().sum().sum()
listings_details.isnull().sum()

True,132118,……首先可以把空值较多的列去掉,因为这些列包含的信息过少。

nan_tb = listings_details.isnull().sum()
nan_vars = list(nan_tb[nan_tb>8000].index)
listings_details = listings_details.drop(nan_vars, axis = 1)

然后可以把这几类的变量去掉,只保留对价格预测有用的变量。

  • 每行都相同的列(相当于没有信息)
  • url:网址信息
  • 爬虫信息
  • 部分host的信息:一般来说租客不太关心房主的信息,更关心房源信息,但是一些房主的信息会影响房源的质量(如经验,是否超级房主等),这部分信息则保留。
  • 价格:将会用calendar数据的价格信息。
  • 地址信息:只保留neighborhood的信息,即neighbourhood_cleansed
  • text类的信息:这类信息用作以后NLP
  • review
  • 其他信息
#drop variables
#drop vars that have less diversity
col_unique = listings_details.nunique(axis=0)
print(col_unique[col_unique == 1])
drop_colnames = list(col_unique[col_unique == 1].index)
listings_details = listings_details.drop(drop_colnames, axis = 1)#drop url
url_colnames = listings_details.columns[listings_details.columns.str.contains(pat = 'url')]
listings_details = listings_details.drop(url_colnames, axis = 1)#drop scrape
scrape_colnames = listings_details.columns[listings_details.columns.str.contains(pat = 'scrape')]
listings_details = listings_details.drop(scrape_colnames, axis = 1)#drop host
host_columns = listings_details.columns[listings_details.columns.str.contains(pat = 'host')]
keep_vars = {'host_since','host_response_time','host_response_rate','host_is_superhost','host_has_profile_pic', 'host_identity_verified'}
host_columns = [ele for ele in host_columns if ele not in keep_vars]
listings_details = listings_details.drop(host_columns, axis = 1)
listings_details = listings_details.drop(['host_response_time'], axis = 1)#drop price
listings_details = listings_details.drop(['price'], axis = 1)#drop address vars
#listings_details['state'].value_counts()
address_vars = ['market','state','jurisdiction_names','street','city','neighbourhood','zipcode','latitude','longitude']
listings_details = listings_details.drop(address_vars, axis = 1)#drop text
text_vars = ['name','summary','space','description','neighborhood_overview','notes','transit','access','interaction','house_rules','amenities']
listings_details = listings_details.drop(text_vars, axis = 1)#drop reviews
review_vars = ['number_of_reviews_ltm','first_review', 'last_review']
listings_details = listings_details.drop(review_vars, axis = 1)
#drop other vars
other_vars = ['instant_bookable','require_guest_profile_picture','require_guest_phone_verification']
listings_details = listings_details.drop(other_vars, axis = 1)

检查一下现在变量的数量和空值情况:

#final number of columns:45
listings_details.columns
listings_details.isnull().sum()

简单清洗一下数据,用均值填充变量:

#clean vars
listings_details['host_response_rate'] = listings_details['host_response_rate'].str.replace("%", "").astype(float)
listings_details['security_deposit'] = listings_details['security_deposit'].str.replace("[$,]", "").astype(float)
listings_details['cleaning_fee'] = listings_details['cleaning_fee'].str.replace("[$,]", "").astype(float)
listings_details['extra_people'] = listings_details['extra_people'].str.replace("[$,]", "").astype(float)#fill na
listings_details = listings_details.fillna(listings_details.mean())
listings_details.isnull().sum()
#deep clean
listings_details['host_since'] = pd.to_datetime(listings_details['host_since'])
listings_details['host_since'] = round((pd.to_datetime('11/01/19') - listings_details['host_since']).dt.days/365,3)tf_col = listings_details.nunique(axis=0)
tf_vars = list(tf_col[tf_col == 2].index)for col in tf_vars:listings_details[col] = pd.Series(np.where(listings_details[col].values == 't', 1, 0),listings_details.index)

这样我们对这个数据集的数据清洗就基本完成了。

calendar数据集:

读取数据,简单看一下这个数据的基本属性:

#Dataset: calendar
calendar = pd.read_csv("calendar.csv")
calendar.head()
#number of listing:8806
print(len(pd.unique(calendar['listing_id'])))
#time length
#first: 2019-01-17 last:2020-10-09 unique:632
calendar['date'] = pd.to_datetime(calendar['date'], format="%Y-%m-%d")
calendar['date'].describe()

处理空值,相对于数据量来说,空值的数量较少,放心大胆地全部drop掉

#check nan
calendar.isnull().values.any()
calendar.isnull().sum().sum()
calendar.isnull().sum()#drop nan
calendar = calendar.dropna()
calendar.isnull().sum().sum()

calendar数据集中有两个关于价格的变量,一个是price,另一个是adjust_price,比较一下两个变量发现区别不大,我们直接drop掉adjust_price。

#clean price
calendar['price'] = calendar['price'].str.replace("[$,]", "").astype(float)
calendar['adjusted_price'] = calendar['adjusted_price'].str.replace("[$,]", "").astype(float)
calendar['price'].describe()
calendar['adjusted_price'].describe()#compare price and adjust price
sum(calendar['price'] != calendar['adjusted_price'])
calendar[calendar['price'] != calendar['adjusted_price']]['listing_id'].value_counts()
calendar = calendar.drop(['adjusted_price'], axis = 1)

Price Distribution画图:

房源的平均价格是223.06,但是价格分布是否均匀呢?

avg_price = calendar['price'].mean() 

listings:

#mean price of the listings
avg_price = calendar.groupby(['listing_id']).mean()#remove outliers
avg_price = avg_price[avg_price['price']<=1000]
#plot
fig,ax = plt.subplots(1,1)
x = avg_price.iloc[:,0]
ax.hist(x, bins = 50, color = '#FF5A5F')
ax.set_title("Distribution of listing price")
ax.set_xlabel('Price')
ax.set_ylabel('Freq. of price')
plt.show()

图一:房源之间的价格相差非常大,1000刀以上的房源较少,认为1000刀以上的房源属于outlier,应该去掉。图二:去掉outliers之后重新画图,房源价格在0-200刀之间较多。

weekdays&months:

#weekdays
#price by weekdays
calendar['weekday'] = pd.to_datetime(calendar['date']).dt.day_name()
avg_price = calendar.groupby(['weekday']).mean()
avg_price = avg_price.reindex(['Monday','Tuesday', 'Wednesday','Thursday','Friday','Saturday', 'Sunday'])#plot
#listing price is higher on Friday and Saturday
fig,ax = plt.subplots(1,1)
x = avg_price.index
y = avg_price['price']
ax.plot(x, y, color = '#FF5A5F')
ax.set_title("Avg. listing price by weekdays")
ax.set_xlabel('Weekdays')
ax.set_ylabel('Price')
plt.show()#months
calendar['month'] = pd.DatetimeIndex(calendar['date']).month
avg_price_month = calendar.groupby(['month']).mean()
avg_price_month = avg_price_month.round(2)#prices in summer season are higher than winter seasons
fig,ax = plt.subplots(1,1)
x = avg_price_month.index
y = avg_price_month['price']
ax.plot(x, y, color = '#FF5A5F')
ax.set_title("Avg. listing price by months")
ax.set_xlabel('Months')
ax.set_ylabel('Price')
plt.savefig('pricedistribution4.jpg',dpi=150)
plt.show()

图一:周五和周六的房源价格相较于一周的其他时间较高,呈现非常明显的波动。图二:整体价格在夏季较高,冬季较低(大概是冬天比较冷,大家都不愿意来吧……)

根据我们得到的信息来处理一下数据:

  • 把周五和周六标为1,其他标为0
  • 标注每个月的波动相对平均价格的波动比率
  • drop available和date
#clean data
calendar['weekday'] = calendar['weekday'].apply(lambda x: 1 if (x == 'Friday')| (x == 'Saturday')else 0)
calendar['month'] = calendar['month'].apply(lambda x: avg_price_month['price'][x]/avg_price)
calendar = calendar.drop(['available','date'], axis = 1)

calendar数据集也整理好了~

Merge datasets

#merge dataset
airbnb = pd.merge(listings_details, calendar,left_on='id', right_on='listing_id')
airbnb = airbnb.drop(['id','listing_id'], axis = 1)
airbnb = airbnb.drop_duplicates()#one-hot encoding
dtype = airbnb.dtypes
one_hot_vars = list(dtype[dtype == 'object'].index)
one_hot_df = airbnb[one_hot_vars]
airbnb_df = pd.concat([airbnb,pd.get_dummies(one_hot_df)],axis=1)

下一步就是用各种regression model去预测价格~

波士顿地区Airbnb价格预测Project (一)相关推荐

  1. 波士顿地区房价预测完整数据集(CSV格式)

    Scikit-Learn库中自带Boston(美国波士顿地区)房价数据集,它包含关于Boston住房和价格的数据,它通常用于机器学习,是学习线性回归问题的一个很好的选择. 网络上CSV格式的数据集普遍 ...

  2. python svr回归_机器学习入门之机器学习之路:python支持向量机回归SVR 预测波士顿地区房价...

    本文主要向大家介绍了机器学习入门之机器学习之路:python支持向量机回归SVR  预测波士顿地区房价,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助. 支持向量机的两种核函数模型进行预 ...

  3. 使用机器学习预测天气_使用机器学习的二手车价格预测

    使用机器学习预测天气 You can reach all Python scripts relative to this on my GitHub page. If you are intereste ...

  4. 机器学习项目实战(五) 住房价格预测

    机器学习项目实战系列   住房价格预测 目录 机器学习项目实战系列   住房价格预测 一.概述 二.分析数据 1.数据导入 2.基础统计运算 3.特征观察 4.建立模型 5.分析模型表现 (1)学习曲 ...

  5. 【直播】王茂霖:二手车交易价格预测-千变万化特征工程(河北高校数据挖掘邀请赛)

    二手车交易价格预测-千变万化特征工程 目前 河北高校数据挖掘邀请赛 正在如火如荼的进行中.为了大家更好的参赛,王茂霖分享了 从0梳理1场数据挖掘赛事!,完整梳理了从环境准备.数据读取.数据分析.特征工 ...

  6. 【直播】王茂霖:二手车交易价格预测 Baseline 提高(河北高校数据挖掘邀请赛)

    二手车交易价格预测 Baseline 提高 目前 河北高校数据挖掘邀请赛 正在如火如荼的进行中.为了大家更好的参赛,王茂霖分享了 从0梳理1场数据挖掘赛事!,完整梳理了从环境准备.数据读取.数据分析. ...

  7. 满帮如何将机器学习应用于车货匹配和公路干线价格预测?

    http://www.infoq.com/cn/articles/ml-dl-highway-price 物流的战火,从来都是"非传统"的竞争者从"非传统"的角 ...

  8. 【算法竞赛学习】二手车交易价格预测-Task2数据分析

    二手车交易价格预测-Task2 数据分析 二. EDA-数据探索性分析 Tip:此部分为零基础入门数据挖掘的 Task2 EDA-数据探索性分析 部分,带你来了解数据,熟悉数据,和数据做朋友,欢迎大家 ...

  9. 【算法竞赛学习】二手车交易价格预测-Task1赛题理解

    二手车交易价格预测-Task1 赛题理解 一. 赛题理解 Tip:此部分为零基础入门数据挖掘的 Task1 赛题理解 部分,为大家入门数据挖掘比赛提供一个基本的赛题入门讲解,欢迎后续大家多多交流. 赛 ...

最新文章

  1. getdate函数_SQL日期函数和GETDATE解释为带有语法示例
  2. 如何解决在数据显示的时候,页面出现null的情况
  3. SQL Server数据库镜像部署 错误1418’处理及证书验证
  4. 从一个页面跳转到用swiper写的全屏滚动页面的指定位置
  5. excel统计行数_值得收藏的6个Excel函数公式(有讲解)
  6. 软件测试简历,这一点你是否漏掉
  7. neo4j图数据库导入scv文件
  8. 简单旅游景点HTML网页设计作品 DIV布局故宫介绍网页模板代码 DW家乡网站制作成品 web网页制作与实现
  9. Linux正则表达式grep,egrep 及相应的正则表达式用法详解
  10. 电镀用整流电源设计matlab,高功率因数的大功率开关电镀电源研究
  11. 人生算法之「延迟满足感」
  12. win10如何关闭自动更新及修改更新时间
  13. 在无聊的时候玩小游戏
  14. html5级联菜单,h5级联下拉、分类筛选
  15. Python使用pyecharts库制作桑基图
  16. DJI M210+manifold 2C配置
  17. java @around,Spring AOP基于注解的Around通知
  18. android 获取用户双开,android 5.0 创建多用户 双开多开应用(1)
  19. JS 下载文件方法分享(解决图片文件无法直接下载和 IE兼容问题)
  20. 从小白到入门,入行量化必须知道的几点

热门文章

  1. python tableau_Tableau集成Python机器学习实践(下)
  2. 电话骚扰 【响完一声开始没有任何声音】
  3. 嵌入式知识-ARM裸机-学习笔记(9):SD卡启动详解(S5PV210)
  4. 哈夫曼树的构建及应用
  5. 【RHCSA】Linux中执行命令
  6. Windows+cygwin下构造arm-linux交叉编译环境最简单的方法
  7. UISwitch - 开关按钮 的使用详解
  8. 计算机系大二学期计划范文,大二学期学习计划范文6篇
  9. Metasploit终端下的辅助扫描工具 (auxiliary模块讲解)
  10. vue实现购物车简单的功能-单选全选总价计算、批量删除