1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        數(shù)據(jù)項(xiàng)目總結(jié) -- 深圳租房數(shù)據(jù)分析!

        共 8158字,需瀏覽 17分鐘

         ·

        2022-03-26 15:11

        ?Datawhale干貨?
        作者:皮錢超,廈門大學(xué),Datawhale成員

        大家好,《上篇》根據(jù)深圳的租房數(shù)據(jù),并從統(tǒng)計(jì)分析和可視化的角度進(jìn)行了分析,受到讀者的歡迎。今天將使用之前的數(shù)據(jù)進(jìn)行數(shù)據(jù)分析和建模,以及模型的可解釋性探索。本文的主要內(nèi)容包含:

        ceaa9a66ac9bd03e03cb78397c86b8ff.webp

        導(dǎo)入庫(kù)

        導(dǎo)入主要的庫(kù)用于:數(shù)據(jù)處理、可視化、建模、特征可解釋性等。

        b3929c549d52d749a637cd36a0c10c8a.webp

        1、數(shù)據(jù)探索

        1)導(dǎo)入數(shù)據(jù)

        e1fbdf3d0a67a8f65b8a1ced2d438ab0.webp

        數(shù)據(jù)在Datawhale后臺(tái)回復(fù) 深圳 下載

        2)數(shù)據(jù)形狀和字段類型

        46e7a68ebec73fd104da7758c4d4a3be.webp

        下面是具體的特征解釋:

        #?下面是特征屬性
        name:小區(qū)名字
        layout:幾室?guī)讖d幾衛(wèi)
        location:朝向
        size:建筑面積
        sizeInside:套內(nèi)面積
        zhuangxiu:裝修方式
        time:小區(qū)建成時(shí)間
        zone:行政區(qū)
        position:行政區(qū)的具體位置;比如寶安壹方中心,龍華民治等
        way:出租方式,整租或者合租
        #?最終的目標(biāo)變量y?
        money:價(jià)格??

        3)查看數(shù)據(jù)的缺失值情況

        使用的是df.isnull().sum()來(lái)查看:在time字段中存在6個(gè)缺失值

        83ab79f67a200ca56aa875b14a845b6d.webp

        4)缺失值填充

        由于缺失量比較少,直接在網(wǎng)上搜索到相應(yīng)的時(shí)間進(jìn)行了人工填充:先定位缺失值的位置,再進(jìn)行填充。

        4be779cd41ecf57e305ab811317a8743.webp

        2、字段預(yù)處理

        2.1 name

        小區(qū)的姓名name直接刪除

        df.drop("name",axis=1,inplace=True)

        2.2 layout

        layout分成3個(gè)具體的屬性:室、廳、衛(wèi)

        特殊情況:當(dāng)layout為"商鋪"時(shí),直接刪除~

        7965f04c758a43b499c611d97a454578.webp

        使用正則解析出室廳衛(wèi):

        df1?=?df["layout"].str.extract(r'(?P\d)室(?P\d)廳(?P\d)衛(wèi)')

        #?合并到原數(shù)據(jù)
        df?=?pd.concat([df1,df],axis=1)
        #?刪除layout
        df.drop("layout",axis=1,inplace=True)
        #?layout=商鋪正則解析為NaN,直接刪除
        df.dropna(subset=["shi","ting","wei"],inplace=True)

        df.head()
        771b233732d984ae234a988600def73e.webp

        2.3 location

        不同朝向的房子數(shù)量:

        df["location"].value_counts()

        朝南?????552
        朝南北????284
        朝北?????241
        朝東南????241
        朝西南????174
        朝西北????142
        朝東北????140
        朝東?????132
        朝西??????92
        朝東西??????2
        Name:?location,?dtype:?int64
        ????
        #?小提琴圖
        fig?=?px.violin(df,y="money",color="location")
        fig.show()
        927aa8499fc7214625389b98586e9b66.webp

        小結(jié):可以看到,在朝南北、朝南、朝北的房子數(shù)量比較多,而且整體的價(jià)格分布更為廣泛。

        對(duì)不同朝向的房子實(shí)施硬編碼:

        #?自定義的順序:根據(jù)朝向和價(jià)格的關(guān)系圖(上面)
        location?=?["朝東西","朝東北","朝西","朝西北","朝東","朝西南","朝東南","朝南","朝北","朝南北"]

        location_dict?=?{}
        for?n,?i?in?enumerate(location):
        ????location_dict[i]?=?n+1?#?保證序號(hào)從1開始
        ????
        df["location"]?=?df["location"].map(location_dict)

        df.head()
        db077d03b6c2247700bb9ea7af974dbc.webp

        2.4 size和sizeInside

        建筑面積套內(nèi)面積提取出數(shù)值部分,提供兩種方法:

        #?1、通過(guò)切割的方式來(lái)提取
        df["size"]?=?df["size"].apply(lambda?x:?x.split("面積")[1].split("㎡")[0])
        #?2、使用正則的方式提取
        df["sizeInside"]?=?df["sizeInside"].str.extract(r'面積(?P[\d.]+)')
        df.head()
        18c59a1367b52ffbab98d0ee6422d051.webp

        2.5 zhuangxiu

        df["zhuangxiu"].value_counts()

        精裝????1172
        普裝?????747
        豪裝??????62
        毛坯??????19
        Name:?zhuangxiu,?dtype:?int64

        主觀意義上的思路:毛坯的等級(jí)最低,豪裝最高。下面實(shí)施硬編碼過(guò)程:

        #?硬編碼
        zhuangxiu?=?{"毛坯":1,"普裝":2,?"精裝":3,?"豪裝":4}
        zhuangxiu

        {'毛坯':?1,?'普裝':?2,?'精裝':?3,?'豪裝':?4}
        df["zhuangxiu"]?=?df["zhuangxiu"].map(zhuangxiu)
        df.head()
        84f6d62b1294528a8b2d3902d4c61395.webp

        2.6 numberFloor

        中低高樓層和價(jià)格money之間的關(guān)系

        #?提取中低高樓層

        df["numberFloor"]?=?df["numberFloor"].apply(lambda?x:?x.split("(")[0])
        df.head()
        6c90e2b78b0028c1696036d60af98ce3.webp69adcd8a3adab362421e9a533c73f49a.webp

        小結(jié):中低高3個(gè)樓層在房租上面的影響稍小。直接考慮獨(dú)熱編碼的方式:

        6d179b49c61bae6bc201f97b7e55fa01.webp
        df?=?(df.join(pd.get_dummies(df["numberFloor"]))
        ????.rename(columns={"中樓層":"middleFloor",
        ????????????????????"低樓層":"lowFloor",
        ????????????????????"高樓層":"highFloor"}))

        df.head()
        390267c0c18b5850cbda49abebeee085.webp
        df.drop("numberFloor",axis=1,inplace=True)??#?刪除原字段

        2.7 time

        房子的建成時(shí)間處理:

        df["time"].value_counts()

        #?部分結(jié)果
        2003年建成????133
        2005年建成????120
        2006年建成????114
        2004年建成????111
        2010年建成????104
        ......
        2019年????????3???#?人工填充的時(shí)間
        2022年建成??????2
        1983年建成??????1
        2003年????????1
        2020年????????1
        2004年????????1
        Name:?time,?dtype:?int64

        提取時(shí)間年份:

        df["time"]?=?df["time"].str.extract(r'(?P)

        #?time轉(zhuǎn)成數(shù)值型
        df["time"]?=?df["time"].astype("float")

        #?建成時(shí)間和當(dāng)前的差距
        df["time"]?=?2022?-?df["time"]
        df.head()
        c91def82d4800de418e2c0ff44ef7977.webp

        2.8 zone+position

        行政區(qū)域和地理位置的合并處理

        df["zone"].value_counts()

        龍崗??????548
        福田??????532
        龍華??????293
        南山??????218
        寶安??????173
        羅湖??????167
        光明???????32
        坪山???????31
        鹽田????????5
        大鵬新區(qū)??????1
        Name:?zone,?dtype:?int64

        #?行政區(qū)和價(jià)格的關(guān)系
        fig?=?px.violin(df,y="money",color="zone")
        fig.show()
        f1de036929a1d1d1d22efaabf99f5378.webp
        #?合并字段
        df["zone_position"]?=?df["zone"]?+?"_"?+?df["position"]
        df.head()
        74a6b647504e48dce76358c8e112d269.webp

        不同行政區(qū)域不同地理位置下的價(jià)格均值統(tǒng)計(jì):

        zone_position_mean?=?
        (df.groupby("zone_position")["money"].mean()
        .reset_index()
        .sort_values("money",ascending=False,ignore_index=True))

        zone_position_mean
        c316baa9e0653a81933dfeb71727edcc.webp

        根據(jù)合并的zone_position_mean數(shù)據(jù)框中的money 來(lái)進(jìn)行硬編碼:福田_車公廟 是最高位

        zone_position?=?zone_position_mean["zone_position"].tolist()[::-1]
        zone_position_dict?=?{}

        for?n,?i?in?enumerate(zone_position):
        ????zone_position_dict[i]?=?n+1?
        ????
        df["zone_position"]?=?df["zone_position"].map(zone_position_dict)
        #?刪除原字段
        df.drop(["zone","position"],axis=1,inplace=True)
        df.head()
        2b1e8114be9de8d39480f84ec81f2a46.webp

        2.9 way

        出租方式和價(jià)格的關(guān)系探索:

        fig?=?px.violin(df,y="money",color="way")
        fig.show()
        65b2026c0eea73280483439734745c13.webp

        從way的取值來(lái)看:大部分的房子是愿意整租的,而且押一付一和押二付一最為普遍。提取出“整租”和“合租”兩種方式:

        df["way"]?=?df["way"].apply(lambda?x:?x.split("?")[0])
        #?編碼
        df["way"]?=?df["way"].map({"整租":1,"合租":0})
        df

        終于:算是得到一份比較符合建模的數(shù)據(jù)

        c3d0c4253e5e4849d4f38efa81eb1019.webp

        3、樣本不均衡

        我們查看way字段下的數(shù)據(jù)情況:明顯way=1的取值情況是遠(yuǎn)遠(yuǎn)大于way=0。

        e3d6cce8a7e04000b0d8b0bb5491d4a7.webp

        解決方法:使用SMOTE算法來(lái)解決解決way=0過(guò)少的問(wèn)題。

        96bbe82cc31652727320560df9e4761e.webp

        解決之后的way=1和way=0的樣本相同:

        8ee7840c31aa20d9eb7c7b461b6f3c3b.webp

        字段異常處理

        1、填充樣本后發(fā)現(xiàn)某些應(yīng)該是整數(shù),卻出現(xiàn)了小數(shù),比如:wei和time等

        27ef372a4ca7ded605df3489bcd6ed93.webp
        cols?=?["shi","ting","wei","time"]
        for?i?in?cols:
        ????smote_df[i]?=?smote_df[i].apply(lambda?x:?round(x))

        2、類型轉(zhuǎn)化

        c5d6542553e897780ecb22ca17b97458.webp
        #?轉(zhuǎn)變數(shù)據(jù)類型
        smote_df["size"]?=?smote_df["size"].astype(float)??
        smote_df["sizeInside"]?=?smote_df["sizeInside"].astype(float)

        4、相關(guān)性分析

        4.1 相關(guān)系數(shù)

        針對(duì)上面得到的smote_df數(shù)據(jù)進(jìn)行下面的相關(guān)性分析:

        #?保存了再讀取
        #?smote_df.to_csv("data_new.csv",index=False)
        df?=?pd.read_csv("data_new.csv")

        1、相關(guān)性

        能夠直觀看到money因變量和size與sizeInside相關(guān)性很強(qiáng)

        corr?=?df.corr()
        f,ax=plt.subplots(figsize=(12,6))
        sns.heatmap(corr,vmax=0.8,square=True,fmt='.2f',?cmap='PuBu_r')
        plt.show()
        15fa58e069a0347de30903e8c5dfe4e2.webp

        4.2 相關(guān)系數(shù)排序

        單個(gè)屬性和money之間的相關(guān)性大小排序,可以看到:size(房子面積)、sizeInsize(套內(nèi)面積)和wei(衛(wèi))的相關(guān)型比較強(qiáng)。

        單純地從相關(guān)系數(shù)得到的結(jié)論,還是有待考證~

        a760b94e47c4ce138a5ef7aa8effa139.webp

        4.3 自變量和因變量關(guān)系

        6bca32015cfea19d847a3978abc1cf58.webp

        上面舉出3個(gè)字段和money之間的相關(guān)性,在最右側(cè):

        • size和sizeInside相對(duì)集中的時(shí)候,money高頻出現(xiàn)0-25000之間
        • 在不同的money取值情況,wei字段的取值集中在1-4之間

        5、回歸建模

        5.1 特征歸一化

        下面是針對(duì)數(shù)據(jù)的歸一化過(guò)程,采用的MinMaxScaler方法:

        X?=?df.drop("money",axis=1)
        y?=?df[["money"]]

        #?實(shí)例化
        mm?=?MinMaxScaler()
        data?=?mm.fit_transform(X)

        #?歸一化后的數(shù)據(jù)
        X?=?pd.DataFrame(data,columns=X.columns.tolist())
        X.head()
        b5dcfd9611f0bd254a2142346a09add6.webp

        5.2 數(shù)據(jù)集切分

        按照訓(xùn)練集:測(cè)試集 = 8:2的比例進(jìn)行數(shù)據(jù)集的劃分:

        from?sklearn.model_selection?import?train_test_split

        X_train,?X_test,?y_train,?y_test?=?train_test_split(
        ??X,?y,?
        ??test_size=0.2,??#?比例
        ??random_state=4??#?隨機(jī)狀態(tài)
        )?????????????????????????????????????????????????

        5.3 特征選擇

        在前面的工作我們從相關(guān)系數(shù)和因變量的相關(guān)性大小進(jìn)行了比較,發(fā)現(xiàn):Size、sizeInside和wei是比較相關(guān)的系數(shù)。

        下面是從使用mutual_info_classif來(lái)查看每個(gè)特征的重要性:

        from?sklearn.feature_selection?import?mutual_info_classif
        imp?=?pd.DataFrame(mutual_info_classif(X,y),
        ??????????????????index=X.columns)

        imp.columns=['importance']
        imp.sort_values(by='importance',ascending=False)
        054d676a2c4d44ab01fb5fa9f4fd0700.webp

        我們發(fā)現(xiàn):shi、wei、zhuangxiu、size都是比較重要的特征

        5.4 評(píng)價(jià)指標(biāo)

        fe0fd583ab7af9bf1c252df6c7cad364.webp

        引入多種回歸模型:

        #?線性回歸
        from?sklearn.linear_model?import?LinearRegression
        #?決策樹回歸
        from?sklearn.tree?import?DecisionTreeRegressor
        #?梯度提升回歸,隨機(jī)森林回歸
        from?sklearn.ensemble?import?GradientBoostingRegressor,RandomForestRegressor

        5.5 不同模型效果

        重點(diǎn)關(guān)注模型的r2值

        1、線性回歸-LinearRegression

        c43050003d16b39bc7241abf4d032022.webp

        2、決策樹回歸-DecisionTreeRegressor

        2e594c085fc3a847c7aea01b91c819b6.webp

        3、隨機(jī)森林回歸-RandomForestRegressor

        142dbc8b9a8ee70a850f343ee94afef1.webp

        4、梯度提升回歸-GradientBoostingRegressor

        c33f35b3a3fa8c84461f2b1e7d8a2b4e.webp

        通過(guò)3種回歸模型的r2得分比較:GradientBoostingRegressor > DecisionTreeRegressor > RandomForestRegressor > LinearRegression

        6、模型可解釋分析

        為了更好理解機(jī)器學(xué)習(xí)模型的輸出,下面使用SHAP庫(kù)來(lái)探索調(diào)參后隨機(jī)森林模型的可解釋性。通過(guò)pip install shap即可安裝

        96d16a1e5c7cfbba2a2c7e98806076c9.webp

        6.1 隨機(jī)森林調(diào)參

        f3f2c9667f4d1fdd02f9205d0d61a1e0.webp

        進(jìn)行fit擬合之后便得到了最優(yōu)的參數(shù)組合:

        rf_random.best_params_
        #?結(jié)果
        {'n_estimators':?120,?'max_features':?'auto',?'max_depth':?20}

        調(diào)參后隨機(jī)森林模型的r2系數(shù)略優(yōu)于調(diào)參前:

        20d6961282caa23e24c1b655c004fb1c.webp

        建立最佳參數(shù)下的模型:

        rf_random?=?RandomForestRegressor(
        ??n_estimators=180,
        ??max_features="auto",
        ??max_depth=10)

        rf_random.fit(X_train,?y_train)

        6.2 計(jì)算shap_values

        SHAP value最大的優(yōu)勢(shì)是SHAP能對(duì)于反映出每一個(gè)樣本中的特征的影響力,而且還能夠表現(xiàn)出影響的正負(fù)性。

        在SHAP中進(jìn)行模型解釋需要先創(chuàng)建一個(gè)explainer,SHAP支持很多類型的explainer

        #?1、傳入調(diào)優(yōu)模型rf_random創(chuàng)建explainer
        explainer?=?shap.TreeExplainer(rf_random)
        #?2、計(jì)算shap值
        shap_values?=?explainer.shap_values(X_test)
        shap_values
        7318505d0277eb6389cea3bb829f40d6.webp

        6.3 均值對(duì)比

        1、通過(guò)模型預(yù)測(cè)得到的均值求解

        #?y的預(yù)測(cè)值和真實(shí)值比較
        y_pred?=?rf_random.predict(X_test)

        #?預(yù)測(cè)值
        y_test["pred"]?=?y_pred??
        #?money部分是真實(shí)值
        y_test.head()
        fad88e6dca2519551b48bbb09088f2dd.webp

        其中:money-真實(shí)值,pred-隨機(jī)森林模型的預(yù)測(cè)值。得到的均值為:

        #?真實(shí)的平均值
        y_test["pred"].mean()

        5614.137953764154

        2、通過(guò)SHAP得到的基準(zhǔn)值base_value

        #?shap得到的基準(zhǔn)值
        y_base?=?explainer.expected_value
        y_base

        array([5487.93357763])

        6.4 整體特征重要性

        取出每個(gè)特征的shap值的絕對(duì)值的平均值作為該特征的重要性,得到水平的條形圖:

        shap.summary_plot(shap_values,?
        ??????????????????X_test,?
        ??????????????????plot_type="bar")
        2915f3b4b95184e4949c9fe3f98144a3.webp
        shap.summary_plot(shap_values,?X_test)
        54add62223f70c82930a70a517496297.webp

        可以看到,通過(guò)shap值來(lái)看:

        • size面積、zone_position區(qū)域位置、shi房間數(shù) 的重要性才是最靠前的,這個(gè)結(jié)果可以和相關(guān)系數(shù)的大小進(jìn)行對(duì)比
        • 前5個(gè)特征中,藍(lán)點(diǎn)主要還是集中在SHAP值小于0的區(qū)域

        6.5 單個(gè)樣本的SHAP值

        從數(shù)據(jù)中隨機(jī)抽查一條樣本查看shap值:

        i=18

        df0?=?pd.DataFrame()
        df0['feature']?=?X_test.columns.tolist()

        df0['feature_value']?=?X_test.iloc[i].values
        df0['shap_value']?=?shap_values[i]
        df0.head(10)
        8aca24136b448693f52bf9754f7fd9f0.webp
        • 第一列是特征名稱
        • 第二列是特征的具體數(shù)值
        • 第三列是各個(gè)特征在該樣本中對(duì)應(yīng)的SHAP值

        注意:一個(gè)樣本中各特征 SHAP 值的和加上基線值應(yīng)該等于該樣本的預(yù)測(cè)值

        09eda6bfdd99027838bdab06bc2930e9.webp

        單條樣本的特征可視化:

        #?可視化
        shap.initjs()

        shap.force_plot(
        ??explainer.expected_value,?
        ??shap_values[i],
        ??X_test.iloc[i])
        e871fd0d3a897199f26313d27e57fe12.webp

        紅色表示higher部分:表明針對(duì)這條數(shù)據(jù),zone_position和size是重要的特征。下面是換了另一個(gè)樣本的結(jié)果:

        96f9d65aa79cc3cea9893d46adc3e43d.webp

        不同的樣本具有不同的重要屬性

        6.6 部分依賴圖-Partial Dependence Plot

        1、單個(gè)變量的影響

        shap.dependence_plot('size',?
        ?????????????????????shap_values,?
        ?????????????????????X_test,?
        ?????????????????????interaction_index=None,?
        ?????????????????????show=False)
        65441e8762aadf7292d3706b0863b3fe.webp

        通過(guò)圖形我們觀察到:size的取值在0.4以下,size的shap都是相對(duì)平和。一旦size達(dá)到一定值,對(duì)房租價(jià)格的拉升作用相當(dāng)明顯。

        2、兩個(gè)變量的交互式影響

        SHAP同樣能夠查看兩個(gè)變量的交互式影響,比如size和zone_position。

        shap.dependence_plot(
        ????'size',?
        ????shap_values,?
        ????X_test,
        ????interaction_index='zone_position',??#?指定
        ????show=False)
        7ede2bb2383c875fb132d63103c3efeb.webp

        當(dāng)指定了interaction_index 的取值情況,我們不僅能夠觀察到size和房租的關(guān)系,還可以看到size和zone_position之間存在的關(guān)系:size在分界點(diǎn)(大致在0.4)前后,one_position的相應(yīng)都比較大(紅色),這同時(shí)表明zone_position是一個(gè)重要性高的特征~


        整理不易,點(diǎn)三連

        瀏覽 65
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            我被在教室强了好爽在线观看 | 韩日一区 | 成人天天在线 | 成人免费视频 国产免费麻豆下载 | 爱爱爱免费视频 | 国产av无毛 | 91鲁| 五月天欧美啪啪色综合 | 久久久精品一品道久久 | 护士巨好爽好大乳aapp |