天池_短租數據分析


數據源:https://tianchi.aliyun.com/competition/entrance/231715/information

導入模塊

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.rc("font",family="SimHei",size="12")  #解決中文無法顯示的問題

導入數據

#導入數據
listings=pd.read_csv('F:\\python\\天池_短租數據分析\\listings.csv')

簡單的數據查看

listings.info()
listings.head(5)
listings.shape
listings.describe()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 28452 entries, 0 to 28451
Data columns (total 16 columns):
 #   Column                          Non-Null Count  Dtype  
---  ------                          --------------  -----  
 0   id                              28452 non-null  int64  
 1   name                            28451 non-null  object 
 2   host_id                         28452 non-null  int64  
 3   host_name                       28452 non-null  object 
 4   neighbourhood_group             0 non-null      float64
 5   neighbourhood                   28452 non-null  object 
 6   latitude                        28452 non-null  float64
 7   longitude                       28452 non-null  float64
 8   room_type                       28452 non-null  object 
 9   price                           28452 non-null  int64  
 10  minimum_nights                  28452 non-null  int64  
 11  number_of_reviews               28452 non-null  int64  
 12  last_review                     17294 non-null  object 
 13  reviews_per_month               17294 non-null  float64
 14  calculated_host_listings_count  28452 non-null  int64  
 15  availability_365                28452 non-null  int64  
dtypes: float64(4), int64(7), object(5)
memory usage: 3.5+ MB

 數據情況如上面截圖,主要是有關可租房屋的信息,字段含義和英文含義基本一致,主要包括:房東ID、房東姓名、所屬行政區、經緯度、房間類型、價格、最小可租天數、評論數量、最后一次評論時間、每月評論占比、可出租房屋、每年可出租時長等

查看數據缺失情況

#數據缺失計算
missing=listings.isnull().sum()
missing[missing>0].plot.bar()

 缺失比例

#數據缺失比例計算
missing=listings.isnull().sum()/len(listings)
missing[missing>0].plot.bar()

 

 可以看出來,一共有四個字段有缺失,其中有一個字段缺失特別嚴重,缺失比例達到了100%,可以刪除,還有2個缺失40%左右,也可以考慮將此刪除

區分數據特征個類別特征

#數據特征 numeric_features = listings.select_dtypes(include=[np.number]) numeric_features.columns #類別特征
categorical_features = listings.select_dtypes(include=[np.object])
categorical_features.columns

類別特征

查看類別特征的值的個數

for cat_fea in categorical_features:
    print(cat_fea + "的特征分布如下:")
    print("{}特征有個{}不同的值".format(cat_fea, listings[cat_fea].nunique()))
    print(listings[cat_fea].value_counts())

類別特征['name', 'host_name', 'neighbourhood', 'room_type', 'last_review']

只保留neighbourhood,'/'前面的值

#使用str.split,記住不要忘記.str,不然會出錯
listings['neighbourhood']=listings['neighbourhood'].str.split('/').str[0]

原來是這樣:

0    朝陽區 / Chaoyang
1       密雲縣 / Miyun
2               東城區
3               東城區
4    朝陽區 / Chaoyang
Name: neighbourhood, dtype: object

現在是這樣:

0    朝陽區 
1    密雲縣 
2     東城區
3     東城區
4    朝陽區 
Name: neighbourhood, dtype: object

 分析neighbourhood和room_type對和price的關系

#按照neighbourhood和room_type分組,計算每個值的個數和price的均值
neigh_roomtype=listings.groupby(['neighbourhood','room_type']).agg({'id':'size','price':'mean'}) #將ID改為number
neigh_roomtype=neigh_roomtype.rename(columns={'id':'number'}) #先對number計算統計可視化等
number_n_r=neigh_roomtype.unstack()['number']
number_n_r.plot(figsize=(12,5),title='圖1:不同房屋類型在不同地區的數量')

畫條形圖

#條形圖
number_n_r.plot.bar(figsize=(12,5),title='圖1:不同房屋類型在不同地區的數量')

 

畫餅圖

#畫餅圖(sum(1)是按行求和)
number_n_r.sum(1).sort_values().plot.pie(figsize=(6,6),autopct='%.2f%%',title='圖2:房屋地區占比')

#畫餅圖(按列求和)
number_n_r.sum(0).sort_values().plot.pie(figsize=(6,6),autopct='%.2f%%',title='圖3:房屋類型占比')

不同區域不同房子類型的均價

#先對price計算統計可視化等
price_r=neigh_roomtype.unstack()['price']
price_r.plot.bar(figsize=(12,5),title='圖1:不同房屋類型在不同地區的均價')

#先對price計算統計可視化等
price_r=neigh_roomtype.unstack()['price']
price_r.plot(figsize=(12,5),title='圖1:不同房屋類型在不同地區的均價')

 

 

計算不同房源均價

#計不同地區均價
listings.groupby('neighbourhood')['price'].mean().sort_values().plot.bar(figsize=(8,8),title='圖4:不同地區房源均價')

 不能是這樣,因為這樣沒有考慮個數,直接使用三個值平均,這種做法是錯誤了

price_r.mean(1).sort_values().plot.bar(figsize=(6,6),title='圖2:房屋地區占比')

 計算不同房屋類型均價

#不同房屋類型均價
listings.groupby('room_type')['price'].mean().sort_values().plot.bar(figsize=(8,8),title='圖5:不同房屋類型均價')

不同房源地區不同房屋類型均價

#不同房源地區和房子類型均價
n_r_data=listings.groupby(['neighbourhood','room_type'])['price'].mean()
plt.figure(figsize=(8,8))
plt.title('圖6:不同房屋類型在不同地區的均價')
sns.barplot(x='neighbourhood',y='price',hue='room_type',data=n_r_data.reset_index())

#或者是這樣子
#先對price計算統計可視化等
price_r=neigh_roomtype.unstack()['price']
price_r.plot.bar(figsize=(12,5),title='圖1:不同房屋類型在不同地區的均價')

 

 

 查看name 和host_name

listings[['name', 'host_name']].head()

 

 

 房東名字應該是沒有什么信息的,可以考慮去掉,name可以從中提取一些特征

查看最后last_review

listings['last_review'].head()
0    2019-03-04
1    2017-10-08
2    2019-02-05
3    2016-12-03
4    2018-08-01
Name: last_review, dtype: object

 可以構造一些有用的特征

數值特征

查看數值特征的值的分布,連續還是離散的

'''
Index(['id', 'host_id', 'neighbourhood_group', 'latitude', 'longitude',
       'price', 'minimum_nights', 'number_of_reviews', 'reviews_per_month',
       'calculated_host_listings_count', 'availability_365'],
      dtype='object')
'''
for i in numeric_features.columns:
    print(i,listings[i].value_counts())

 

1.id和host_id是沒有什么信息的可以刪除

#可以先保留一下id ,然后再刪除
id=listings['id']
listings=listings.drop(['id', 'host_id'],axis=1)

2.由於neighbourhood_group的值全部一樣,都是空值,因此將此刪除

listings=listings.drop('neighbourhood_group',axis=1)

3.經緯度,可能和房源區域強相關

sns.regplot('latitude','price',data=listings)
sns.regplot('longitude','price',data=listings)

 

 4.最小可租天數

sns.regplot('minimum_nights','price',data=listings)

sns.boxplot('minimum_nights',data=listings)

 

 

 

 這肯定有異常值了,而且一般不都是最小入住天數是1天嗎

#看的出來最小入住天數是1晚,還有30天這個值還挺多的有609個,應該是月租
listings['minimum_nights'].value_counts().sort_index()

5.評論數量、最后一次評論時間(單獨拿出來)、每月評論占比、可出租房屋、每年可出租時長

for i in ['number_of_reviews', 
       'calculated_host_listings_count', 'availability_365']:
    sns.regplot(i,'price',data=listings)
    plt.show()

 

 

 

 目標變量price 

sns.boxplot(listings['price'])
sns.distplot(listings['price'])

 

 

 大於10000的值影響太大了,可以只畫10000以下的

sns.distplot(listings[listings['price']<=10000]['price'])

 

 

查看一下描述性

listings['price'].describe()
count    28452.000000
mean       611.203325
std       1623.535077
min          0.000000
25%        235.000000
50%        389.000000
75%        577.000000
max      68983.000000
Name: price, dtype: float64

 再看一下1000以下的

sns.distplot(listings[listings['price']<=1000]['price'])

 

為什么會有0,好詭異,青年旅館嗎

listings['price'].value_counts().sort_index()
#0        3

 

log一下

sns.distplot(np.log(listings['price']+1))
sns.distplot(np.log(listings[listings['price']<=1000]['price']+1))

 

 

 

 

 特征工程

先復制一份數據,省得對原數據造成影響

train=listings.copy()

 

先對類別特征進行構造特征

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM