【数据分析师-数据分析项目案例一】600w+条短租房数据案例分析
短租房數(shù)據(jù)案例分析
- 1 前言
- 1.1 數(shù)據(jù)集
- 1.2 數(shù)據(jù)分析思路梳理
- 2 數(shù)據(jù)分析
- 2.1 數(shù)據(jù)加載
- 2.2 數(shù)據(jù)查看
- 3 數(shù)據(jù)可視化
- 3.1 每天房屋入住率
- 3.2 房屋月份價(jià)格走勢
- 3.3 房屋星期價(jià)格特征
- 3.4 不同社區(qū)的房源數(shù)量
- 3.5 房源評(píng)分情況
- 3.6 房源價(jià)格情況
- 3.7 不同社區(qū)與房源價(jià)格的關(guān)系
- 3.8 品質(zhì)房和普通房
- 3.8 配套設(shè)施和房價(jià)的關(guān)系
- 3.9 房型和房價(jià)的關(guān)系
- 3.10 配套設(shè)施必備類型
- 3.11 床位的數(shù)量和房價(jià)的關(guān)系
- 3.12 關(guān)聯(lián)關(guān)系探索
- 4 特征工程
- 5 機(jī)器學(xué)習(xí)
- 5.1 隨機(jī)森林
- 5.2 LightGBM
手動(dòng)反爬蟲,禁止轉(zhuǎn)載: 原博地址 https://blog.csdn.net/lys_828/article/details/119940333(CSDN博主:Be_melting) 知識(shí)梳理不易,請尊重勞動(dòng)成果,文章僅發(fā)布在CSDN網(wǎng)站上,在其他網(wǎng)站看到該博文均屬于未經(jīng)作者授權(quán)的惡意爬取信息
1 前言
1.1 數(shù)據(jù)集
-
本案例中的數(shù)據(jù)來自于愛彼迎(Airbnb)網(wǎng)站2018-2019年度的多倫多市的真實(shí)數(shù)據(jù)。
-
數(shù)據(jù)集中包含listings數(shù)據(jù)集,約有2萬條數(shù)據(jù),記錄著所有的房屋信息,包括價(jià)格在內(nèi)的幾十項(xiàng)信息字段。
-
數(shù)據(jù)集中的另一個(gè)數(shù)據(jù)集是calendar,包含約650萬條的租房交易數(shù)據(jù),擁有每一天每一所住房的入駐信息。
1.2 數(shù)據(jù)分析思路梳理
常規(guī)數(shù)據(jù)分析,數(shù)據(jù)字段載入和常見數(shù)據(jù)ETL四板斧的清洗處理
-
方法1: .isnull().sum() 檢查空值情況
-
方法2: .shape 檢查數(shù)據(jù)尺寸
-
方法3: .describe() 查看數(shù)據(jù)字段數(shù)據(jù)類型
-
方法4: .value_counts() 查看數(shù)據(jù)集合數(shù)據(jù)分布情況
數(shù)據(jù)分析師最終是要把結(jié)果以可視化的方式進(jìn)行呈現(xiàn),所以對于分析得到的數(shù)據(jù)要進(jìn)行圖表化展示。由于本案例主要研究的目標(biāo)是價(jià)格的依賴因素,所以我們采用價(jià)格和另一個(gè)因素的對比作圖來觀察。常見圖形包括:
-
圖形1: 柱狀圖,來觀察數(shù)據(jù)的分布情況
-
圖形2: 箱型圖,來觀察數(shù)據(jù)的范圍
-
圖形3: 散點(diǎn)矩陣圖,來觀察不同因素間的相互聯(lián)系
-
圖形4: 熱力圖,來快速篩選出高關(guān)聯(lián)度的信息因素
傳統(tǒng)的數(shù)據(jù)分析一般就會(huì)到此為止,但是對于探索試數(shù)據(jù)分析來說,事情才剛剛開始,為了更深入的進(jìn)行數(shù)據(jù)分析,本案例開始引入機(jī)器學(xué)習(xí)模型,由于機(jī)器學(xué)習(xí)模型本質(zhì)上就是數(shù)學(xué)模型,所以我們需要對數(shù)據(jù)集合進(jìn)行特征工程,把數(shù)據(jù)集合變?yōu)榉奖隳P妥R(shí)別的數(shù)組,本例中采用如下幾個(gè)步驟:
- 步驟1:數(shù)據(jù)的標(biāo)準(zhǔn)化
- 步驟2:缺失數(shù)據(jù)的修復(fù)
- 步驟3:字符串類數(shù)據(jù)的編碼化
- 步驟4:數(shù)據(jù)類型轉(zhuǎn)換和單位統(tǒng)一
對于本例中的眾多字段用簡單的線性回歸等模型已經(jīng)不能很好的捕捉出數(shù)據(jù)的動(dòng)態(tài),所以我們采用一些符合機(jī)器學(xué)習(xí)模型,也就是利用一系列若關(guān)聯(lián)的特性組合出強(qiáng)特性的模型,在本例中我們采用兩個(gè)模型:
-
模型1 :隨機(jī)森林模型,這個(gè)模型是一個(gè)復(fù)合模型,對特征和標(biāo)簽進(jìn)行任意排列組合,然后通過概率方式進(jìn)行建模,最大程度的降低過擬合的出現(xiàn)。
-
模型2 :微軟的LightGBM模型也是最近幾年非常火的復(fù)合模型,在本例中我們使用這個(gè)模型和隨機(jī)森林進(jìn)行模型對比,利用R2值來選出最合適的機(jī)器學(xué)習(xí)模型。
2 數(shù)據(jù)分析
2.1 數(shù)據(jù)加載
代碼編寫是在Anaconda集成環(huán)境下的jupyter notebook上進(jìn)行,首先導(dǎo)入數(shù)據(jù)分析所需要的模塊以及數(shù)據(jù)集
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns %matplotlib inlinecalendar = pd.read_csv('toroto/calendar.csv.gz') print('We have', calendar.date.nunique(), 'days and', calendar.listing_id.nunique(), 'unique listings in the calendar data.')輸出結(jié)果如下:(數(shù)據(jù)包含了365天共17333份房間信息,nunique()方法是進(jìn)行字段的唯一值查詢,返回字段中唯一元素的個(gè)數(shù))
2.2 數(shù)據(jù)查看
(1)數(shù)據(jù)維度和字段信息
calendar.shapecalendar.head()輸出結(jié)果如下:(共有630w+條交易記錄,4個(gè)字段。listing_id: 房屋數(shù)據(jù)編號(hào), date: 當(dāng)前記錄時(shí)間, available: 當(dāng)前房間是否沒被租賃, price 如果沒有被租賃,則顯示價(jià)格)
(2)交易的起止日期
輸出結(jié)果如下:(交易的時(shí)間范圍是在2018年10月6號(hào)至2019年10月5號(hào),整整一年的時(shí)間)
(3)字段缺失值和字段統(tǒng)計(jì)
輸出結(jié)果如下:(price字段,由于房子出租后,就沒有價(jià)格顯示,只有未出租才有價(jià)格,所以該字段存在著缺失值;available字段中f (false) 代表已經(jīng)被租用 , t(true) 代表可以被出租)
3 數(shù)據(jù)可視化
3.1 每天房屋入住率
讀取的數(shù)據(jù)中包含了1w多套房源,共有600w+交易記錄,涵蓋了交易的起止日期,因此可以探究每天房屋的入住情況(當(dāng)天入住的數(shù)量除以總的房間數(shù)量)。具體分析的步驟如下:
#提取時(shí)間日期和房間狀態(tài)字段并賦值新變量 calendar_new = calendar[['date', 'available']] #添加一個(gè)新的字段記錄房源是夠被出租 calendar_new['busy'] = calendar_new.available.map( lambda x: 0 if x == 't' else 1) #按照時(shí)間日期進(jìn)行分組求解每日入住的均值并重置索引 calendar_new = calendar_new.groupby('date')['busy'].mean().reset_index() #最后將時(shí)間日期轉(zhuǎn)化為datetime時(shí)間格式 calendar_new['date'] = pd.to_datetime(calendar_new['date']) #查看處理后的結(jié)果前五行 calendar_new.head()輸出結(jié)果如下:(date字段就是時(shí)間日期,busy字段就代表這個(gè)每天的平均入住率)
輸出結(jié)果匯總發(fā)現(xiàn)有個(gè)粉紅色的警示輸出提醒xxxWarning,需要了解一下pandas在進(jìn)行數(shù)據(jù)處理和分析過程中會(huì)存在版本和各類模塊兼容的情況,xxxWarning是一種善意的提醒,并不是xxxError,這類提醒不會(huì)影響程序的正常運(yùn)行,也可以導(dǎo)入模塊進(jìn)行提醒忽略
導(dǎo)入運(yùn)行后,重新執(zhí)行上述分析過程,輸出結(jié)果如下:(此時(shí)就沒有粉紅色的xxxWarning提醒了)
每天房屋入住率求解完畢后,就可以進(jìn)行可視化展現(xiàn),由于繪制圖形的x軸部分為時(shí)間日期,且時(shí)間跨度較大,一般是采用折線圖進(jìn)行繪制圖形
輸出結(jié)果如下:(通過圖中我們可以看到,10-11月是最繁忙的,然后是第二年的7-9月,由于這份數(shù)據(jù)是來自愛彼迎多倫多地區(qū),所以可以推斷出整個(gè)短租房的入住率是在下半年會(huì)比較旺盛)
3.2 房屋月份價(jià)格走勢
此次有兩個(gè)分析技巧,由于價(jià)格部分帶有$符號(hào)和,號(hào),所以我們需要對數(shù)據(jù)進(jìn)行格式化處理,并且轉(zhuǎn)換時(shí)間字段。處理完時(shí)間字段后,使用柱狀圖進(jìn)行數(shù)據(jù)分析
#先將時(shí)間日期字段轉(zhuǎn)化為datetime字段方便提取月份數(shù)據(jù) calendar['date'] = pd.to_datetime(calendar['date']) #清洗price字段中的$符號(hào)和,號(hào),最后轉(zhuǎn)化為浮點(diǎn)數(shù)方便記性計(jì)算 calendar['price'] = calendar['price'].str.replace(',', '') calendar['price'] = calendar['price'].str.replace('$', '') calendar['price'] = calendar['price'].astype(float)#按照月份進(jìn)行分組匯總求解價(jià)錢的均值 mean_of_month = calendar.groupby(calendar['date'].dt.strftime('%B'),sort=False)['price'].mean() #繪制條形圖 mean_of_month.plot(kind = 'barh' , figsize = (12,7)) #添加x軸標(biāo)簽 plt.xlabel('average monthly price')輸出結(jié)果如下:(上一次轉(zhuǎn)化datetime數(shù)據(jù)類型是calendar_new變量中的date字段,但是calendar變量中的date字段的數(shù)據(jù)類型還仍是字符串?dāng)?shù)據(jù)類型)
如果想要月份按照1-12月的方式進(jìn)行順序輸出,可以重新指定索引。已有的索引放置在一個(gè)列表中,排好序后傳入reindex()函數(shù)中,操作如下
輸出結(jié)果如下:(圖中可以看出7月 8月和10月是平均價(jià)格最高的三個(gè)月)
3.3 房屋星期價(jià)格特征
#獲取星期的具體天數(shù)的名稱 calendar['dayofweek'] = calendar.date.dt.weekday_name #然后指定顯示的索引順序 cats = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] #提取要分析的兩個(gè)字段 price_week=calendar[['dayofweek','price']] #按照星期進(jìn)行分組求解平均價(jià)錢后重新設(shè)置索引 price_week = calendar.groupby(['dayofweek']).mean().reindex(cats) #刪除不需要的字段 price_week.drop('listing_id', axis=1, inplace=True) #繪制圖形 price_week.plot() #指定軸刻度的數(shù)值及對應(yīng)的標(biāo)簽值 ticks = list(range(0, 7, 1)) labels = "Mon Tues Weds Thurs Fri Sat Sun".split() plt.xticks(ticks, labels)#如果不想要顯示xticks信息,可以增添plt.show() plt.show()輸出結(jié)果如下:(直接指定DataFrame繪制圖形,可能x軸的刻度和標(biāo)簽信息不會(huì)全部顯示,此時(shí)可以自行指定刻度數(shù)量和對應(yīng)的標(biāo)簽值。短租房本身大都為了旅游而存在,所以周五周六兩天的價(jià)格都比其他時(shí)間貴出一個(gè)檔次。周末雙休,使得入駐的時(shí)間為周五周六晚兩個(gè)晚上)
3.4 不同社區(qū)的房源數(shù)量
讀取另外一個(gè)數(shù)據(jù)文件,按照每個(gè)房源社區(qū)進(jìn)行分組,統(tǒng)計(jì)房源的數(shù)量(id字段對應(yīng)著房源獨(dú)特的編號(hào))
listings = pd.read_csv('toroto/listings.csv.gz') print('We have', listings.id.nunique(), 'listings in the listing data.')listings.groupby(by='neighbourhood_cleansed').count()[['id']].sort_values(by='id', ascending=False).head(10)輸出結(jié)果如下:(兩個(gè)字段的分組求解過程基本就是最后一行代碼的執(zhí)行過程,最后還可以順帶按照字段進(jìn)行排序和查看數(shù)據(jù)量)
3.5 房源評(píng)分情況
通過對review_scores_rating評(píng)分字段進(jìn)行分布圖繪制,可以查看價(jià)格的分布區(qū)間范圍
#設(shè)置畫布大小尺寸 plt.figure(figsize=(12,6)) #繪制分布圖 sns.distplot(listings.review_scores_rating.dropna(), rug=True) #取消右側(cè)和上側(cè)坐標(biāo)軸 sns.despine()輸出結(jié)果如下:(此處的評(píng)分標(biāo)準(zhǔn)為0-100分制,通過上述表格可以看出總體來看愛彼迎的房屋好評(píng)率非常高)
3.6 房源價(jià)格情況
前面探究了房源價(jià)格和星期之間的關(guān)聯(lián),但是房價(jià)字段自身的信息并沒有探究,可以使用describe查看價(jià)格的情況
listings['price'] = listings['price'].str.replace(',', '') listings['price'] = listings['price'].str.replace('$', '') listings['price'] = listings['price'].astype(float)listings['price'].describe()輸出結(jié)果如下:(多倫多最昂貴的Airbnb房源價(jià)格為$ 12933 /晚(當(dāng)時(shí)的價(jià)錢,現(xiàn)在的價(jià)錢是$ 64818 /晚),以下是房屋的鏈接:https://www.airbnb.ca/rooms/16039481?locale=en。通過鏈接可以發(fā)現(xiàn)之所以比平均價(jià)貴出約100倍,主要是因?yàn)檫@處房屋是多倫多最時(shí)尚的社區(qū)中的藝術(shù)收藏家閣樓。這些藝術(shù)收藏的價(jià)值大幅的拉高了這處房源的價(jià)格,使其和平均值有100倍的差距)
如果需要查看一下最大值或者最小值對應(yīng)的記錄,可以使用argmax或者argmin如下代碼
輸出結(jié)果如下:(通過name信息可以核實(shí),這份房源就是屬于Art Collector藝術(shù)收藏品 )
由于在數(shù)據(jù)分析中,我們需要服從正態(tài)分布的原則,對于這樣極端情況的存在,我們需要進(jìn)行清理,所以把異常的價(jià)格的數(shù)據(jù)進(jìn)行過濾,最終選擇的價(jià)錢是保留0-600之間的數(shù)據(jù)。具體要選取某一數(shù)值,需要看一下當(dāng)前數(shù)值以上對應(yīng)的房源信息數(shù)量占全體的比重,這里選取大于600以上的房源僅有200+套,占總比1w+的比例很小,而且房源免費(fèi)的只有7套
去掉極端值后我們繼續(xù)觀察現(xiàn)在的價(jià)格分布狀態(tài),繪制直方圖
輸出結(jié)果如下:(分箱數(shù)量bins可以自由指定,可以看出價(jià)格主要是在30-200之間)
3.7 不同社區(qū)與房源價(jià)格的關(guān)系
前面探究了不同社區(qū)和房源數(shù)量之間的關(guān)系,這里可以進(jìn)一步探究不同社區(qū)和房源價(jià)錢之間的關(guān)系
plt.figure(figsize=(18,10)) sort_price = listings.loc[(listings.price <= 600) & (listings.price > 0)]\.groupby('neighbourhood_cleansed')['price']\.median()\.sort_values(ascending=False)\.index sns.boxplot(y='price', x='neighbourhood_cleansed', data=listings.loc[(listings.price <= 600) & (listings.price > 0)], order=sort_price) ax = plt.gca()ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right') plt.show()輸出結(jié)果如下:(最好的社區(qū)不僅房源的最高價(jià)高,而且平均價(jià)格也是所有社區(qū)中最高的,很有代表性)
3.8 品質(zhì)房和普通房
在預(yù)定酒店時(shí),瀏覽頁面中常常會(huì)推出品質(zhì)房源和普通房源,在這份數(shù)據(jù)集中也是存在字段記錄這方面的信息,可以對比研究一下兩者的價(jià)錢情況
sns.boxplot(y='price', x='host_is_superhost', data=listings.loc[(listings.price <= 600) & (listings.price > 0)]) plt.show()輸出結(jié)果如下:(品質(zhì)房源要比普通房源的價(jià)格要高)
3.8 配套設(shè)施和房價(jià)的關(guān)系
酒店中的軟裝特性和多少也是和房源的價(jià)錢有著密切的關(guān)系,可以依循探究不同社區(qū)的房源價(jià)格的方式進(jìn)行分析,代碼基本上進(jìn)行字段的修改就可以
plt.figure(figsize=(18,10)) sort_price = listings.loc[(listings.price <= 600) & (listings.price > 0)]\.groupby('property_type')['price']\.median()\.sort_values(ascending=False)\.index sns.boxplot(y='price', x='property_type', data=listings.loc[(listings.price <= 600) & (listings.price > 0)], order=sort_price) ax = plt.gca() ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right') plt.show()輸出結(jié)果如下:(在今后繪制此類圖形時(shí)候,代碼可以直接復(fù)制后修改對應(yīng)的字段和限制的范圍即可。從這個(gè)圖中可以看到在數(shù)據(jù)處理時(shí),如果對于極端值不進(jìn)行處理,則會(huì)顯示出這樣怪異的情況,例如Aparthotel 公寓式酒店 這個(gè)關(guān)鍵詞的價(jià)格最高,但是通過boxplot我們又可以看出,其實(shí)只有一套這樣的房產(chǎn),所以數(shù)據(jù)并不完整。tend(帳篷)和parking space (停車位)這樣的關(guān)鍵詞也是數(shù)量很少的,導(dǎo)致了數(shù)據(jù)結(jié)果顯示不準(zhǔn)確)
根本原因就是分類中的數(shù)據(jù)值太少了,可以通過value_counts()進(jìn)行查看。對于這種數(shù)值偏少的分類也可以設(shè)定一個(gè)數(shù)值作為分界點(diǎn)進(jìn)行提取,或者根據(jù)展示需求直接提取前5、前10、前15的數(shù)據(jù)
3.9 房型和房價(jià)的關(guān)系
在租房時(shí)候,有整租有合租,還存在一些多人共用一間的情況(有點(diǎn)類似青年旅社),可以嘗試性探究不同的房型與房價(jià)之間的關(guān)系
sort_price = listings.loc[(listings.price <= 600) & (listings.price > 0)]\.groupby('room_type')['price']\.median()\.sort_values(ascending=False)\.index sns.boxplot(y='price', x='room_type', data=listings.loc[(listings.price <= 600) & (listings.price > 0)], order=sort_price) ax = plt.gca() ax.set_xticklabels(ax.get_xticklabels(), rotation=45, ha='right') plt.show()輸出結(jié)果如下:(整租價(jià)格最貴,其次是合租,最便宜的就是多人共用)
除了查看字段中各房型的房價(jià)信息,也可以逆向思維,根據(jù)價(jià)格來看不同房型的出租的多少,通過堆疊圖來嘗試探究
輸出結(jié)果如下:(有個(gè)明顯的分界線,就是在100前后整租房的出租的數(shù)量和其它兩種房型存在著較大的差距,100之前合租占據(jù)較大的比例,但是100以后就是整租的絕對優(yōu)勢了)
3.10 配套設(shè)施必備類型
酒店中房間的配套設(shè)施,比如wifi,衛(wèi)生間,開窗,24小時(shí)熱水等條件,嘗試探究出租房中必備的配套設(shè)施都有哪些,首先對amenities字段的數(shù)據(jù)進(jìn)行清洗,提取里面的具體設(shè)施
listings['amenities'].head()listings.amenities = listings.amenities.str.replace("[{}]", "").str.replace('"', "")listings['amenities'].head()輸出結(jié)果如下:(需要對花括號(hào)和引號(hào)進(jìn)行去除,最后就是按照逗號(hào)進(jìn)行分割)
找出前20個(gè)最重要的便利設(shè)施
輸出結(jié)果如下:(Wifi 暖氣 廚房等便利設(shè)施是最重要的部分。這一部分有個(gè)很常用的功能,就是對一個(gè)字段中多項(xiàng)元素進(jìn)行合并后進(jìn)行統(tǒng)計(jì)計(jì)數(shù)后繪制圖像)
配套設(shè)施和房價(jià)之間的關(guān)系。理解下面的前三行代碼將會(huì)有不少的收獲
輸出結(jié)果如下:(前兩行代碼也是很實(shí)用的功能,實(shí)現(xiàn)字段中包含的元素的進(jìn)行統(tǒng)計(jì)求平均的過程,結(jié)果就是可以得到元素和對應(yīng)的價(jià)格均值)
3.11 床位的數(shù)量和房價(jià)的關(guān)系
listings.loc[(listings.price <= 600) & (listings.price > 0)].pivot(columns = 'beds',values = 'price').plot.hist(stacked = True,bins=100) plt.xlabel('Listing price in $')輸出結(jié)果如下:(先查看各出租房匯總不同床位出現(xiàn)的數(shù)量分布,主要集中在1,2,3,價(jià)錢也主要在0-200區(qū)間范圍內(nèi))
然后查看一下每種床位數(shù)量的價(jià)格關(guān)系如下
輸出結(jié)果如下:(在這份數(shù)據(jù)中驚人的發(fā)現(xiàn)居然沒有床的房屋價(jià)格比有2張床的房屋價(jià)格還要貴)
3.12 關(guān)聯(lián)關(guān)系探索
之前的嘗試性探索都是在指定兩個(gè)字段,然后進(jìn)行兩兩分析。可以通過columns查看一下所有的字段名稱,輸出如下
兩兩單獨(dú)挑出來的字段進(jìn)行分析就是基于常識(shí),日常中都已經(jīng)在大腦中潛意識(shí)認(rèn)為這兩個(gè)字段可能有所關(guān)聯(lián),如果一直使用這種方式很難挖掘出潛在的有價(jià)值信息,因此就可以借助pairplot繪制多字段的兩兩對比圖或者h(yuǎn)eatmap熱力圖探究潛在的關(guān)聯(lián)性
輸出結(jié)果如下:(只選取了部分字段)
進(jìn)行熱力圖繪制,需要注意pairplot和heatmap繪制的圖形都是只需要看主對角線上下一側(cè)的圖像即可,因?yàn)樯傻膱D形是關(guān)于主對角線對稱
輸出結(jié)果如下:(數(shù)字越接近1,說明字段之間的相關(guān)性越強(qiáng),主對角線的數(shù)值不用看都是1)
熱力圖除了查看相關(guān)性外,還有一個(gè)重要的用處就是展示三個(gè)字段之間的關(guān)系,比如上面相關(guān)性圖中可以看到價(jià)錢price字段和bathrooms床位以及bedrooms字段都有較強(qiáng)的關(guān)聯(lián)關(guān)系,就可以使用熱力圖將三者的關(guān)系表現(xiàn)出來
輸出結(jié)果如下:(該熱力圖探究的是洗漱間和臥室的數(shù)量與房子數(shù)量的關(guān)系)
那么把count()改成mean(),就變成探究洗漱間和臥室的數(shù)量與房子平均價(jià)格之間的關(guān)系
輸出結(jié)果如下:
4 特征工程
以上的內(nèi)容就是傳統(tǒng)的數(shù)據(jù)分析要完成的內(nèi)容,分析的過程依賴于數(shù)據(jù)分析師本身的經(jīng)驗(yàn),而且結(jié)果都是以圖表的形式進(jìn)行展現(xiàn),有一個(gè)痛點(diǎn)就是字段較多時(shí)候,要進(jìn)行分析時(shí)就需要很多很多的圖像,比如三個(gè)字段的分析,熱力圖就需要很多很多。此時(shí)就可以借助機(jī)器學(xué)習(xí)模型來探究,但是探究之前需要處理字段數(shù)據(jù),進(jìn)行特征工程。為了防止內(nèi)存不足,建議在進(jìn)行特征工程之前重新restart一下kernel,保證后續(xù)程序的正常運(yùn)行,否則會(huì)提醒內(nèi)存不足,程序報(bào)錯(cuò)
import pandas as pd listings = pd.read_csv('toroto/listings.csv/listings.csv')listings['price'] = listings['price'].str.replace(',', '') listings['price'] = listings['price'].str.replace('$', '') listings['price'] = listings['price'].astype(float) listings = listings.loc[(listings.price <= 600) & (listings.price > 0)]listings.amenities = listings.amenities.str.replace("[{}]", "").str.replace('"', "")listings.amenities.head()輸出結(jié)果如下:(數(shù)據(jù)讀取之后將價(jià)格字段和設(shè)施字段還按照之前的處理方式進(jìn)行預(yù)處理,注意這里程序運(yùn)行后的標(biāo)號(hào),是restart之后的再次運(yùn)行)
然后進(jìn)行特征工程,先處理文本數(shù)據(jù),將文本數(shù)據(jù)特征化,導(dǎo)入處理文本數(shù)據(jù)的模塊,進(jìn)行詞向量轉(zhuǎn)化
輸出結(jié)果如下:(這一過程就是將amenities字段中所有的分類進(jìn)行獨(dú)熱編碼,然后形成DataFrame數(shù)據(jù)類型)
接著處理二分類字段,將true和false的分類替換成計(jì)算機(jī)識(shí)別的1和0分類。當(dāng)存在多個(gè)二分類字段時(shí)候可以進(jìn)行for循環(huán)統(tǒng)一進(jìn)行數(shù)據(jù)轉(zhuǎn)化,代碼操作如下
接著對價(jià)錢相關(guān)的字段進(jìn)行缺失值填充和噪音數(shù)據(jù)的清洗,最后不要忘記將數(shù)值的字段轉(zhuǎn)化為浮點(diǎn)數(shù)。代碼操作如下
listings['security_deposit'] = listings['security_deposit'].fillna(value=0) listings['security_deposit'] = listings['security_deposit'].replace( '[\$,)]','', regex=True ).astype(float) listings['cleaning_fee'] = listings['cleaning_fee'].fillna(value=0) listings['cleaning_fee'] = listings['cleaning_fee'].replace( '[\$,)]','', regex=True ).astype(float)并不是讀取數(shù)據(jù)中的所有字段都有作用,比如在進(jìn)行熱力圖判斷字段之間的相關(guān)關(guān)系時(shí),有些字段之間的相關(guān)關(guān)系的都是0,這些字段就可以直接被舍棄,選取有相關(guān)關(guān)系的字段重新組成一個(gè)數(shù)據(jù)集
listings_new = listings[['host_is_superhost', 'host_identity_verified', 'host_has_profile_pic','is_location_exact', 'requires_license', 'instant_bookable', 'require_guest_profile_picture', 'require_guest_phone_verification', 'security_deposit', 'cleaning_fee', 'host_listings_count', 'host_total_listings_count', 'minimum_nights','bathrooms', 'bedrooms', 'guests_included', 'number_of_reviews','review_scores_rating', 'price']]接著就看一下這些字段中是不是還存在缺失值,上面只是進(jìn)行了部分字段的處理,這里重現(xiàn)選取字段后仍然要進(jìn)行缺失值的處理
for col in listings_new.columns[listings_new.isnull().any()]:print(col)輸出結(jié)果如下:(說明還是有字段的缺失值未進(jìn)行處理)
接著處理這部分字段的缺失值,按照中位數(shù)進(jìn)行填充。當(dāng)字段為分類字段時(shí),填充的方式為中位數(shù)填充,前面處理的價(jià)格字段為連續(xù)字段,使用均值進(jìn)行填充
然后對分類字段進(jìn)行獨(dú)熱編碼處理,并將編碼后的結(jié)果與新數(shù)據(jù)進(jìn)行合并
for cat_feature in ['zipcode', 'property_type', 'room_type', 'cancellation_policy', 'neighbourhood_cleansed', 'bed_type']:listings_new = pd.concat([listings_new, pd.get_dummies(listings[cat_feature])], axis=1)此時(shí)不要忘記最開始對文本編碼的DataFrame數(shù)據(jù),也需要進(jìn)行合并,合并的方式為取交集,最終得到特征工程處理后的數(shù)據(jù)
listings_new = pd.concat([listings_new, df_amenities], axis=1, join='inner')listings_new.head()listings_new.shape輸出結(jié)果如下:(數(shù)據(jù)只剩下約1.7w,但是字段數(shù)量增加到了6000+)
5 機(jī)器學(xué)習(xí)
5.1 隨機(jī)森林
特征工程完成后,就該進(jìn)行機(jī)器學(xué)習(xí)模型的創(chuàng)建,首先使用隨機(jī)森林回歸模型進(jìn)行建模,看看最終的效果如何。模型創(chuàng)建的過程以及評(píng)估的流程如下
from sklearn.model_selection import train_test_split from sklearn.metrics import r2_score from sklearn.metrics import mean_squared_error from sklearn.ensemble import RandomForestRegressory = listings_new['price'] x = listings_new.drop('price', axis =1) X_train, X_test, y_train, y_test = train_test_split(x, y, test_size = 0.25, random_state=1) rf = RandomForestRegressor(n_estimators=500, criterion='mse', random_state=3, n_jobs=-1)rf.fit(X_train, y_train)輸出結(jié)果如下:(x是沒有標(biāo)簽的其余字段,y就是標(biāo)簽字段,切分?jǐn)?shù)據(jù)集一般就按照七三開,這里按照訓(xùn)練集75%,測試集25%,隨機(jī)種子狀態(tài)設(shè)定為1。最后決策樹模型設(shè)置500棵樹,評(píng)價(jià)方式為均方差mse,隨機(jī)種子狀態(tài)為3,-1代表選擇處理器性能全開)
訓(xùn)練過程會(huì)和選用的機(jī)器的性能相關(guān),運(yùn)行需要一定的時(shí)間,待運(yùn)行完畢后就可以使用模型進(jìn)行預(yù)測
輸出結(jié)果如下:(注意傳入predict括號(hào)中的變量,傳入X_train就對應(yīng)得到訓(xùn)練集計(jì)算出來的預(yù)測標(biāo)簽,傳入X_test就對應(yīng)著測試集計(jì)算出來的預(yù)測標(biāo)簽,通過比對最終訓(xùn)練集和測試集的結(jié)果可以計(jì)算出最終的預(yù)測結(jié)果)
模型的預(yù)測結(jié)果出來之后,同時(shí)也可以查看模型得到的最重要的影響因素
輸出結(jié)果如下:(影響因素一列就為傳入的字段的名稱,影響的重要性,可以通過訓(xùn)練好的模型下面的feature_importances_屬性獲得)
5.2 LightGBM
只用一個(gè)模型建模獲得結(jié)果沒有對比性,無法判斷最終的預(yù)測結(jié)果是好還是壞,因此在進(jìn)行預(yù)測時(shí)候往往都不是只使用一個(gè)模型進(jìn)行,而是采用至少兩個(gè)模型進(jìn)行對比,接下來就是使用LightGBM模型進(jìn)行預(yù)測
需要先安裝LightGBM模塊,操作如下
然后從模塊中導(dǎo)入回歸模型,劃分?jǐn)?shù)據(jù)集后構(gòu)建模型
輸出結(jié)果如下:
如果顯示上放的輸出結(jié)果說明模型訓(xùn)練成功,但是過程并不一定會(huì)一帆風(fēng)順,可能會(huì)運(yùn)行報(bào)錯(cuò)如下:TypeError: Cannot interpret '<attribute 'dtype' of 'numpy.generic' objects>' as a data type,此時(shí)可以升級(jí)一下pandas和numpy的版本,比如將pandas升級(jí)到1.2.4,numpy升級(jí)到1.20.2。然后重新運(yùn)行當(dāng)前的notebook就可以完美解決這個(gè)問題
接著就可以使用訓(xùn)練好的模型進(jìn)行預(yù)測并查看模型得分,順帶可以將重要的影響因素進(jìn)行可視化
輸出結(jié)果如下:(使用LightGBM模型進(jìn)行預(yù)測的得分要比隨機(jī)森林模型最終的得分要高,說明此數(shù)據(jù)集較適用于LightGBM模型)
最后對比兩個(gè)模型最終給出的重要影響因素,可以發(fā)現(xiàn)前五個(gè)都是一樣的,只是順序上存在著不同。此外關(guān)于模型具體的講解會(huì)在后續(xù)的機(jī)器學(xué)習(xí)部分詳細(xì)介紹,這里就是明確數(shù)據(jù)分析案例的流程,知道如何進(jìn)行模塊的調(diào)用創(chuàng)建模型和預(yù)測
總結(jié)
以上是生活随笔為你收集整理的【数据分析师-数据分析项目案例一】600w+条短租房数据案例分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: qt按钮禁用和激活禁用_为什么试探法只是
- 下一篇: 第二十六期:100 个网络基础知识普及,