天池_二手車價格預測_Task1-2_賽題理解與數(shù)據(jù)分析

  • 1??.1?? 賽題重述
  • 1??.2?? 數(shù)據(jù)集概述
    • 思考????
  • 1??.3?? 預測結果評價指標??
  • 2??.1?? 數(shù)據(jù)總覽
    • 2??.1??.1?? 各種計算包的導入
    • 2??.1??.1?? 數(shù)據(jù)載入
    • 2??.1??.2?? 數(shù)據(jù)的基本形態(tài)
  • 2??.2?? 數(shù)據(jù)的缺失情況??
  • 2??.3?? 數(shù)據(jù)的異常情況??
  • 2??.4?? 待預測的真實值的分布情況??
  • 2??.5?? 數(shù)據(jù)特征相關性的分析??
    • 2??.5??.1?? numric特征的相關性分析
    • 2??.5??.2?? pandas_profiling生成數(shù)據(jù)報告??

驚聞4.13日江蘇省高校將要啟動開學模式,我自巋然不動。山中何事?松花釀酒,春水煎茶,如是而已。

1?? 賽題理解??

1??.1?? 賽題重述

這是一道來自于天池的新手練習題目,用數(shù)據(jù)分析、機器學習等手段進行 二手車售賣價格預測 的回歸問題。賽題本身的思路清晰明了,即對給定的數(shù)據(jù)集進行分析探討,然后設計模型運用數(shù)據(jù)進行訓練,測試模型,最終給出選手的預測結果。

1??.2?? 數(shù)據(jù)集概述

賽題官方給出了來自Ebay Kleinanzeigen的二手車交易記錄,總數(shù)據(jù)量超過40w,包含31列變量信息,其中15列為匿名變量,即v0v15。并從中抽取15萬條作為訓練集,5萬條作為測試集A,5萬條作為測試集B,同時對name、modelbrandregionCode等信息進行脫敏。具體的數(shù)據(jù)表如下圖:

Field Description
SaleID 交易ID,唯一編碼
name 汽車交易名稱,已脫敏
regDate 汽車注冊日期,例如20160101,2016年01月01日
model 車型編碼,已脫敏
brand 汽車品牌,已脫敏
bodyType 車身類型:豪華轎車:0,微型車:1,廂型車:2,大巴車:3,敞篷車:4,雙門汽車:5,商務車:6,攪拌車:7
fuelType 燃油類型:汽油:0,柴油:1,液化石油氣:2,天然氣:3,混合動力:4,其他:5,電動:6
gearbox 變速箱:手動:0,自動:1
power 發(fā)動機功率:范圍 [ 0, 600 ]
kilometer 汽車已行駛公里,單位萬km
notRepairedDamage 汽車有尚未修復的損壞:是:0,否:1
regionCode 地區(qū)編碼,已脫敏
seller 銷售方:個體:0,非個體:1
offerType 報價類型:提供:0,請求:1
creatDate 汽車上線時間,即開始售賣時間
price 二手車交易價格(預測目標)
v系列特征 匿名特征,包含v0-14在內15個匿名特征

思考????

  • 指標重要性

    • 數(shù)據(jù)集里面包含的很多維度的數(shù)據(jù),對于人來說第一眼看上去就會產生直觀的感覺,哪些指標對售價的影響大,哪些指標對售價的影響小,特別是對于一個長期從事二手車交易的人來說,更是如此。例如 kilometer(汽車已行駛公里)肯定是對于成交價格的影響是巨大的。但是如何讓我設計的模型認知到這些先驗知識是個棘手的問題,但我想這應該時一個很舊的問題,只是我還沒有足夠的知識去通曉它解決的肌理。確實,對于機器來說,這些數(shù)據(jù)只是一列列的向量,所以首要解決的就是向量的重要性。
  • 簡單思維

    • 簡單地假設(我相信所有人都會想到的easy思路??),所有的變量跟預測目標成交價格是simple的線性關系,列一個包含31個自變量的線性函數(shù),用批量梯度下降法擬合出31個自變量系數(shù),然后用正則化解決過擬合問題。


      它的假設函數(shù)是這樣的:

      它的帶有正則化的代價函數(shù)是這樣的:


1??.3?? 預測結果評價指標??


賽題的預測評估指標為


可以看出,指標就一個,沒有很多維度的評價框架,不那么勸退。??

2?? 數(shù)據(jù)分析EDA??

  • EDA的價值主要在于熟悉數(shù)據(jù)集,了解數(shù)據(jù)集,對數(shù)據(jù)集進行驗證來確定所獲得數(shù)據(jù)集可以用于接下來的機器學習或者深度學習使用。
  • 當了解了數(shù)據(jù)集之后我們下一步就是要去了解變量間的相互關系以及變量與預測值之間的存在關系。
  • 引導數(shù)據(jù)科學從業(yè)者進行數(shù)據(jù)處理以及特征工程的步驟,使數(shù)據(jù)集的結構和特征集讓接下來的預測問題更加可靠。
  • 完成對于數(shù)據(jù)的探索性分析,并對于數(shù)據(jù)進行一些圖表或者文字總結并打卡。

當然這一步也要就解決我在 1??.2?? 中提出的第一個思考,能否通過探索性分析,發(fā)掘指標之間的關系,從而為模型內聯(lián)性地定義出各指標的對成交價格的強弱相關性。但是EDA分析涉及的范圍太大,可視化的東西很多,但是如果在后續(xù)的分析中不進行運用就是多余的工作,所以只需要挑選最重要的幾個因素進行分析,具體如下:

  • 數(shù)據(jù)總覽,即describe()統(tǒng)計量以及info()數(shù)據(jù)類型
  • 缺失值以及異常值檢測
  • 分析待預測的真實值的分布
  • 特征之間的相關性分析

2??.1?? 數(shù)據(jù)總覽

2??.1??.1?? 各種計算包的導入

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns # seabon是一個做可視化非常nice的包,它的別名sns是約定俗成的的東西,還有一段很有意思的故事import missingno as msno # 用來檢測缺失值

2??.1??.1?? 數(shù)據(jù)載入

Train_data = pd.read_csv('used_car_train_20200313.csv', sep=' ')Test_data = pd.read_csv('used_car_testA_20200313.csv', sep=' ')

2??.1??.2?? 數(shù)據(jù)的基本形態(tài)

  • 訓練集的長相
Train_data.head()Train_data.tail()

<style scoped="">.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre></style>

SaleID name regDate model brand bodyType fuelType gearbox power kilometer ... v_5 v_6 v_7 v_8 v_9 v_10 v_11 v_12 v_13 v_14
149995 149995 163978 20000607 121.0 10 4.0 0.0 1.0 163 15.0 ... 0.280264 0.000310 0.048441 0.071158 0.019174 1.988114 -2.983973 0.589167 -1.304370 -0.302592
149996 149996 184535 20091102 116.0 11 0.0 0.0 0.0 125 10.0 ... 0.253217 0.000777 0.084079 0.099681 0.079371 1.839166 -2.774615 2.553994 0.924196 -0.272160
149997 149997 147587 20101003 60.0 11 1.0 1.0 0.0 90 6.0 ... 0.233353 0.000705 0.118872 0.100118 0.097914 2.439812 -1.630677 2.290197 1.891922 0.414931
149998 149998 45907 20060312 34.0 10 3.0 1.0 0.0 156 15.0 ... 0.256369 0.000252 0.081479 0.083558 0.081498 2.075380 -2.633719 1.414937 0.431981 -1.659014
149999 149999 177672 19990204 19.0 28 6.0 0.0 1.0 193 12.5 ... 0.284475 0.000000 0.040072 0.062543 0.025819 1.978453 -3.179913 0.031724 -1.483350 -0.342674

5 rows × 31 columns

Train_data.shape
(150000, 31)

  • 測試集的長相
Test_data.head()Test_data.tail()

<style scoped="">.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre></style>

SaleID name regDate model brand bodyType fuelType gearbox power kilometer ... v_5 v_6 v_7 v_8 v_9 v_10 v_11 v_12 v_13 v_14
49995 199995 20903 19960503 4.0 4 4.0 0.0 0.0 116 15.0 ... 0.284664 0.130044 0.049833 0.028807 0.004616 -5.978511 1.303174 -1.207191 -1.981240 -0.357695
49996 199996 708 19991011 0.0 0 0.0 0.0 0.0 75 15.0 ... 0.268101 0.108095 0.066039 0.025468 0.025971 -3.913825 1.759524 -2.075658 -1.154847 0.169073
49997 199997 6693 20040412 49.0 1 0.0 1.0 1.0 224 15.0 ... 0.269432 0.105724 0.117652 0.057479 0.015669 -4.639065 0.654713 1.137756 -1.390531 0.254420
49998 199998 96900 20020008 27.0 1 0.0 0.0 1.0 334 15.0 ... 0.261152 0.000490 0.137366 0.086216 0.051383 1.833504 -2.828687 2.465630 -0.911682 -2.057353
49999 199999 193384 20041109 166.0 6 1.0 NaN 1.0 68 9.0 ... 0.228730 0.000300 0.103534 0.080625 0.124264 2.914571 -1.135270 0.547628 2.094057 -1.552150

5 rows × 30 columns

Test_data.shape
(50000, 30)

  1. 可以看出,數(shù)據(jù)的分散程度很大,有整型,有浮點,有正數(shù),有負數(shù),還有日期,當然可以當成是字符串。另外如果數(shù)據(jù)都換算成數(shù)值的話,數(shù)據(jù)間差距特別大,有些成千上萬,有些幾分幾厘,這樣在預測時就難以避免地會忽視某些值的作用,所以需要對其進行歸一化。
  2. shape的運用是也十分重要,對數(shù)據(jù)的大小要心中有數(shù)
  • describe()來對數(shù)據(jù)進行基本統(tǒng)計量的分析,關于describe()的基本參數(shù)如下(且其默認只對數(shù)值型數(shù)據(jù)進行分析,如果有字符串,時間序列等的數(shù)據(jù),會減少統(tǒng)計的項目):

    • count:一列的元素個數(shù);
    • mean:一列數(shù)據(jù)的平均值;
    • std:一列數(shù)據(jù)的均方差;(方差的算術平方根,反映一個數(shù)據(jù)集的離散程度:越大,數(shù)據(jù)間的差異越大,數(shù)據(jù)集中數(shù)據(jù)的離散程度越高;越小,數(shù)據(jù)間的大小差異越小,數(shù)據(jù)集中的數(shù)據(jù)離散程度越低)
    • min:一列數(shù)據(jù)中的最小值;
    • max:一列數(shù)中的最大值;
    • 25%:一列數(shù)據(jù)中,前 25% 的數(shù)據(jù)的平均值;
    • 50%:一列數(shù)據(jù)中,前 50% 的數(shù)據(jù)的平均值;
    • 75%:一列數(shù)據(jù)中,前 75% 的數(shù)據(jù)的平均值;
  • info()來查看數(shù)據(jù)類型,并主要查看是否有異常數(shù)據(jù)

Train_data.describe()

<style scoped="">.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre></style>

SaleID name regDate model brand bodyType fuelType gearbox power kilometer ... v_5 v_6 v_7 v_8 v_9 v_10 v_11 v_12 v_13 v_14
count 150000.000000 150000.000000 1.500000e+05 149999.000000 150000.000000 145494.000000 141320.000000 144019.000000 150000.000000 150000.000000 ... 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000 150000.000000
mean 74999.500000 68349.172873 2.003417e+07 47.129021 8.052733 1.792369 0.375842 0.224943 119.316547 12.597160 ... 0.248204 0.044923 0.124692 0.058144 0.061996 -0.001000 0.009035 0.004813 0.000313 -0.000688
std 43301.414527 61103.875095 5.364988e+04 49.536040 7.864956 1.760640 0.548677 0.417546 177.168419 3.919576 ... 0.045804 0.051743 0.201410 0.029186 0.035692 3.772386 3.286071 2.517478 1.288988 1.038685
min 0.000000 0.000000 1.991000e+07 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.500000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 -9.168192 -5.558207 -9.639552 -4.153899 -6.546556
25% 37499.750000 11156.000000 1.999091e+07 10.000000 1.000000 0.000000 0.000000 0.000000 75.000000 12.500000 ... 0.243615 0.000038 0.062474 0.035334 0.033930 -3.722303 -1.951543 -1.871846 -1.057789 -0.437034
50% 74999.500000 51638.000000 2.003091e+07 30.000000 6.000000 1.000000 0.000000 0.000000 110.000000 15.000000 ... 0.257798 0.000812 0.095866 0.057014 0.058484 1.624076 -0.358053 -0.130753 -0.036245 0.141246
75% 112499.250000 118841.250000 2.007111e+07 66.000000 13.000000 3.000000 1.000000 0.000000 150.000000 15.000000 ... 0.265297 0.102009 0.125243 0.079382 0.087491 2.844357 1.255022 1.776933 0.942813 0.680378
max 149999.000000 196812.000000 2.015121e+07 247.000000 39.000000 7.000000 6.000000 1.000000 19312.000000 15.000000 ... 0.291838 0.151420 1.404936 0.160791 0.222787 12.357011 18.819042 13.847792 11.147669 8.658418

8 rows × 30 columns

Test_data.describe()

<style scoped="">.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre></style>

SaleID name regDate model brand bodyType fuelType gearbox power kilometer ... v_5 v_6 v_7 v_8 v_9 v_10 v_11 v_12 v_13 v_14
count 50000.000000 50000.000000 5.000000e+04 50000.000000 50000.000000 48587.000000 47107.000000 48090.000000 50000.000000 50000.000000 ... 50000.000000 50000.000000 50000.000000 50000.000000 50000.000000 50000.000000 50000.000000 50000.000000 50000.000000 50000.000000
mean 174999.500000 68542.223280 2.003393e+07 46.844520 8.056240 1.782185 0.373405 0.224350 119.883620 12.595580 ... 0.248669 0.045021 0.122744 0.057997 0.062000 -0.017855 -0.013742 -0.013554 -0.003147 0.001516
std 14433.901067 61052.808133 5.368870e+04 49.469548 7.819477 1.760736 0.546442 0.417158 185.097387 3.908979 ... 0.044601 0.051766 0.195972 0.029211 0.035653 3.747985 3.231258 2.515962 1.286597 1.027360
min 150000.000000 0.000000 1.991000e+07 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.500000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 -9.160049 -5.411964 -8.916949 -4.123333 -6.112667
25% 162499.750000 11203.500000 1.999091e+07 10.000000 1.000000 0.000000 0.000000 0.000000 75.000000 12.500000 ... 0.243762 0.000044 0.062644 0.035084 0.033714 -3.700121 -1.971325 -1.876703 -1.060428 -0.437920
50% 174999.500000 52248.500000 2.003091e+07 29.000000 6.000000 1.000000 0.000000 0.000000 109.000000 15.000000 ... 0.257877 0.000815 0.095828 0.057084 0.058764 1.613212 -0.355843 -0.142779 -0.035956 0.138799
75% 187499.250000 118856.500000 2.007110e+07 65.000000 13.000000 3.000000 1.000000 0.000000 150.000000 15.000000 ... 0.265328 0.102025 0.125438 0.079077 0.087489 2.832708 1.262914 1.764335 0.941469 0.681163
max 199999.000000 196805.000000 2.015121e+07 246.000000 39.000000 7.000000 6.000000 1.000000 20000.000000 15.000000 ... 0.291618 0.153265 1.358813 0.156355 0.214775 12.338872 18.856218 12.950498 5.913273 2.624622

8 rows × 29 columns

Train_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 31 columns):
SaleID               150000 non-null int64
name                 150000 non-null int64
regDate              150000 non-null int64
model                149999 non-null float64
brand                150000 non-null int64
bodyType             145494 non-null float64
fuelType             141320 non-null float64
gearbox              144019 non-null float64
power                150000 non-null int64
kilometer            150000 non-null float64
notRepairedDamage    150000 non-null object
regionCode           150000 non-null int64
seller               150000 non-null int64
offerType            150000 non-null int64
creatDate            150000 non-null int64
price                150000 non-null int64
v_0                  150000 non-null float64
v_1                  150000 non-null float64
v_2                  150000 non-null float64
v_3                  150000 non-null float64
v_4                  150000 non-null float64
v_5                  150000 non-null float64
v_6                  150000 non-null float64
v_7                  150000 non-null float64
v_8                  150000 non-null float64
v_9                  150000 non-null float64
v_10                 150000 non-null float64
v_11                 150000 non-null float64
v_12                 150000 non-null float64
v_13                 150000 non-null float64
v_14                 150000 non-null float64
dtypes: float64(20), int64(10), object(1)
memory usage: 35.5+ MB

Test_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50000 entries, 0 to 49999
Data columns (total 30 columns):
SaleID               50000 non-null int64
name                 50000 non-null int64
regDate              50000 non-null int64
model                50000 non-null float64
brand                50000 non-null int64
bodyType             48587 non-null float64
fuelType             47107 non-null float64
gearbox              48090 non-null float64
power                50000 non-null int64
kilometer            50000 non-null float64
notRepairedDamage    50000 non-null object
regionCode           50000 non-null int64
seller               50000 non-null int64
offerType            50000 non-null int64
creatDate            50000 non-null int64
v_0                  50000 non-null float64
v_1                  50000 non-null float64
v_2                  50000 non-null float64
v_3                  50000 non-null float64
v_4                  50000 non-null float64
v_5                  50000 non-null float64
v_6                  50000 non-null float64
v_7                  50000 non-null float64
v_8                  50000 non-null float64
v_9                  50000 non-null float64
v_10                 50000 non-null float64
v_11                 50000 non-null float64
v_12                 50000 non-null float64
v_13                 50000 non-null float64
v_14                 50000 non-null float64
dtypes: float64(20), int64(9), object(1)
memory usage: 11.4+ MB

從上面的統(tǒng)計量與信息來看,沒有什么特別之處,就數(shù)據(jù)類型來說notRepairedDamage的類型是object是個另類,后續(xù)要進行特殊處理。

2??.2?? 數(shù)據(jù)的缺失情況??

pandas內置了isnull()可以用來判斷是否有缺失值,它會對空值和NA進行判斷然后返回TrueFalse。

Train_data.isnull().sum()
SaleID                  0
name                    0
regDate                 0
model                   1
brand                   0
bodyType             4506
fuelType             8680
gearbox              5981
power                   0
kilometer               0
notRepairedDamage       0
regionCode              0
seller                  0
offerType               0
creatDate               0
price                   0
v_0                     0
v_1                     0
v_2                     0
v_3                     0
v_4                     0
v_5                     0
v_6                     0
v_7                     0
v_8                     0
v_9                     0
v_10                    0
v_11                    0
v_12                    0
v_13                    0
v_14                    0
dtype: int64

Test_data.isnull().sum()
SaleID                  0
name                    0
regDate                 0
model                   0
brand                   0
bodyType             1413
fuelType             2893
gearbox              1910
power                   0
kilometer               0
notRepairedDamage       0
regionCode              0
seller                  0
offerType               0
creatDate               0
v_0                     0
v_1                     0
v_2                     0
v_3                     0
v_4                     0
v_5                     0
v_6                     0
v_7                     0
v_8                     0
v_9                     0
v_10                    0
v_11                    0
v_12                    0
v_13                    0
v_14                    0
dtype: int64

  • 可以看出缺失的數(shù)據(jù)值主要集中在bodyTypefuelType,gearbox,這三個特征中。訓練集中model缺失了一個值,但是無傷大雅。至于如何填充,亦或是刪除這些數(shù)據(jù),需要后期在選用模型時再做考慮。

  • 同時我們也可以通過missingno庫查看缺省值的其他屬性。

    • 矩陣圖matrix
    • 柱狀圖bar
    • 熱力圖heatmap
    • 樹狀圖dendrogram

缺省熱力圖

熱力圖表示兩個特征之間的缺失相關性,即一個變量的存在或不存在如何強烈影響的另一個的存在。如果xy的熱度值是1,則代表當x缺失時,y也百分之百缺失。如果xy的熱度相關性為-1,說明x缺失的值,那么y沒有缺失;而x沒有缺失時,y為缺失。至于 矩陣圖,與柱狀圖沒有查看的必要,我們可以用缺省熱力圖觀察一下情況:

msno.heatmap(Train_data.sample(10000))
<matplotlib.axes._subplots.AxesSubplot at 0x1c62d5c07f0>

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

msno.heatmap(Test_data.sample(10000))
<matplotlib.axes._subplots.AxesSubplot at 0x1c62de62d30>

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

樹狀圖

樹形圖使用層次聚類算法通過它們的無效性相關性(根據(jù)二進制距離測量)將變量彼此相加。在樹的每個步驟,基于哪個組合最小化剩余簇的距離來分割變量。變量集越單調,它們的總距離越接近零,并且它們的平均距離(y軸)越接近零。

msno.dendrogram(Train_data.sample(10000))
<matplotlib.axes._subplots.AxesSubplot at 0x1c62de92390>

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

msno.dendrogram(Test_data.sample(10000))
<matplotlib.axes._subplots.AxesSubplot at 0x1c62d7df400>

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

由上面的熱力圖以及聚類圖可以看出,各個缺失值之間的相關性并不明顯。

2??.3?? 數(shù)據(jù)的異常情況??

因為之前發(fā)現(xiàn)notRepairedDamage的類型是object是個另類,所以看一下它的具體情況。

Train_data['notRepairedDamage'].value_counts()
0.0    111361
-       24324
1.0     14315
Name: notRepairedDamage, dtype: int64

Test_data['notRepairedDamage'].value_counts()
0.0    37249
-       8031
1.0     4720
Name: notRepairedDamage, dtype: int64

發(fā)現(xiàn)有'-'的存在,這可以算是NaN的一種,所以可以將其替換為NaN

Train_data['notRepairedDamage'].replace('-', np.nan, inplace=True)Test_data['notRepairedDamage'].replace('-', np.nan, inplace=True)

2??.4?? 待預測的真實值的分布情況??

我們先來看看價格預測值的分布情況

Train_data['price']
0         1850
1         3600
2         6222
3         2400
4         5200
          ... 
149995    5900
149996    9500
149997    7500
149998    4999
149999    4700
Name: price, Length: 150000, dtype: int64

Train_data['price'].value_counts()
500      2337
1500     2158
1200     1922
1000     1850
2500     1821
         ... 
25321       1
8886        1
8801        1
37920       1
8188        1
Name: price, Length: 3763, dtype: int64

嗯哼,平淡無奇,接下來最重要的是要看一下歷史成交價格的偏度(Skewness)峰度(Kurtosis),此外自然界最優(yōu)美的分布式正態(tài)分布,所以也要看一下待預測的價格分布是否滿足正態(tài)分布。 再解釋一下偏度峰度,一般會拿偏度和峰度來看數(shù)據(jù)的分布形態(tài),而且一般會跟正態(tài)分布做比較,我們把正態(tài)分布的偏度和峰度都看做零。如果算到偏度峰度不為0,即表明變量存在左偏右偏,或者是高頂平頂。

  • 偏度(Skewness) 是描述數(shù)據(jù)分布形態(tài)的統(tǒng)計量,其描述的是某總體取值分布的對稱性,簡單來說就是數(shù)據(jù)的不對稱程度。

    • Skewness = 0 ,分布形態(tài)與正態(tài)分布偏度相同。
    • Skewness > 0 ,正偏差數(shù)值較大,為正偏或右偏。長尾巴拖在右邊,數(shù)據(jù)右端有較多的極端值。
    • Skewness < 0 ,負偏差數(shù)值較大,為負偏或左偏。長尾巴拖在左邊,數(shù)據(jù)左端有較多的極端值。
    • 數(shù)值的絕對值越大,表明數(shù)據(jù)分布越不對稱,偏斜程度大。
    • 計算公式
  • 峰度(Kurtosis) 偏度是描述某變量所有取值分布形態(tài)陡緩程度的統(tǒng)計量,簡單來說就是數(shù)據(jù)分布頂?shù)募怃J程度。

    • Kurtosis = 0 與正態(tài)分布的陡緩程度相同。
    • Kurtosis > 0 比正態(tài)分布的高峰更加陡峭——尖頂峰。
    • urtosis<0 比正態(tài)分布的高峰來得平臺——平頂峰。
    • 計算公式:
sns.distplot(Train_data['price']);print("Skewness: %f" % Train_data['price'].skew())print("Kurtosis: %f" % Train_data['price'].kurt())
Skewness: 3.346487
Kurtosis: 18.995183

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

很明顯,預測值的數(shù)據(jù)分布不服從正態(tài)分布,偏度與峰度的值都很大,也很符合他們的定義,從圖中可以看出,長尾巴拖在右邊印證了峰度值很大,峰頂很尖對應了偏度值很大。以我模糊的概率統(tǒng)計知識,這更加像是接近于卡方或者是F分布。所以要對數(shù)據(jù)本身進行變換。

plt.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')plt.show()plt.hist(np.log(Train_data['price']), orientation = 'vertical',histtype = 'bar', color ='red') plt.show()
在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

由于數(shù)據(jù)較為集中,這就給預測模型的預測帶來比較大的困難,所以可以進行一次log運算改善一下分布,有利于后續(xù)的預測。

2??.5?? 數(shù)據(jù)特征相關性的分析??

2??.5??.1?? numric特征的相關性分析

這里主要是為了解決我之前提出的疑問,「如何確定每個指標的重要性」,所以研究每個特征之間的相關性就顯得尤為重要。在分析之前需要確定哪些特征是numeric型數(shù)據(jù),哪些特征是object型數(shù)據(jù)。自動化的方法是 這樣的:

# num_feas = Train_data.select_dtypes(include=[np.number])# obj_feas = Train_data.select_dtypes(include=[np.object])

但本題的數(shù)據(jù)集的label已經標好名稱了,而且label是有限的,每個種類是可以理解的,所以還是需要人為標注,例如車型bodyType雖然是數(shù)值型數(shù)據(jù),但其實我們知道它應該是object型數(shù)據(jù)。所以可以這樣:

num_feas = ['power', 'kilometer', 'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10', 'v_11', 'v_12', 'v_13','v_14' ]obj_feas = ['name', 'model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'notRepairedDamage', 'regionCode',]

下面我們將price加入num_feas,并用pandas籠統(tǒng)地分析一下特征之間的相關性,并進行可視化。

num_feas.append('price')price_numeric = Train_data[num_feas]correlation = price_numeric.corr()print(correlation['price'].sort_values(ascending = False),'\n')
price        1.000000
v_12         0.692823
v_8          0.685798
v_0          0.628397
power        0.219834
v_5          0.164317
v_2          0.085322
v_6          0.068970
v_1          0.060914
v_14         0.035911
v_13        -0.013993
v_7         -0.053024
v_4         -0.147085
v_9         -0.206205
v_10        -0.246175
v_11        -0.275320
kilometer   -0.440519
v_3         -0.730946
Name: price, dtype: float64 

f , ax = plt.subplots(figsize = (8, 8))plt.title('Correlation of Numeric Features with Price', y = 1, size = 16)sns.heatmap(correlation, square = True, annot=True, cmap='RdPu', vmax = 0.8) # 參數(shù)annot為True時,為每個單元格寫入數(shù)據(jù)值。如果數(shù)組具有與數(shù)據(jù)相同的形狀,則使用它來注釋熱力圖而不是原始數(shù)據(jù)。
<matplotlib.axes._subplots.AxesSubplot at 0x1c63234b400>

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

作為一個色彩控,cmap的可選參數(shù)有Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, Purples_r, RdBu, RdBu_r, RdGy, RdGy_r, RdPu, RdPu_r, RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral, Spectral_r, Wistia, Wistia_r, YlGn, YlGnBu, YlGnBu_r, YlGn_r, YlOrBr, YlOrBr_r, YlOrRd, YlOrRd_r...其中末尾加r是顏色取反。

關于seabornheatmap可以看這里seaborn.heatmap的初步學習

言歸正傳,從熱度圖中可以看出跟price相關性高的幾個特征主要包括:kilometer,v3。與我們的現(xiàn)實經驗還是比較吻合的,那個v3可能是發(fā)動機等汽車重要部件相關的某個參數(shù)。

  • 峰度與偏度

查看各個特征的偏度與峰度,以及數(shù)據(jù)的分布狀況

del price_numeric['price']#  輸出數(shù)據(jù)的峰度與偏度,這里pandas可以直接調用for col in num_feas:    print('{:15}'.format(col),           'Skewness: {:05.2f}'.format(Train_data[col].skew()) ,           '   ' ,          'Kurtosis: {:06.2f}'.format(Train_data[col].kurt())           )f = pd.melt(Train_data, value_vars = num_feas) # 利用pandas的melt函數(shù)將測試集中的num_feas所對應的數(shù)據(jù)取出來# FacetGrid是sns庫中用來畫網格圖的函數(shù),其中col_wrap用來控制一行顯示圖的個數(shù),sharex或者sharey是否共享x,y軸,意味著每個子圖是否有自己的橫縱坐標。g = sns.FacetGrid(f, col = "variable",  col_wrap = 6, sharex = False, sharey = False, hue = 'variable', palette = "GnBu_d") # palette的可選參數(shù)與上文的cmap類似g = g.map(sns.distplot, "value")
power           Skewness: 65.86     Kurtosis: 5733.45
kilometer       Skewness: -1.53     Kurtosis: 001.14
v_0             Skewness: -1.32     Kurtosis: 003.99
v_1             Skewness: 00.36     Kurtosis: -01.75
v_2             Skewness: 04.84     Kurtosis: 023.86
v_3             Skewness: 00.11     Kurtosis: -00.42
v_4             Skewness: 00.37     Kurtosis: -00.20
v_5             Skewness: -4.74     Kurtosis: 022.93
v_6             Skewness: 00.37     Kurtosis: -01.74
v_7             Skewness: 05.13     Kurtosis: 025.85
v_8             Skewness: 00.20     Kurtosis: -00.64
v_9             Skewness: 00.42     Kurtosis: -00.32
v_10            Skewness: 00.03     Kurtosis: -00.58
v_11            Skewness: 03.03     Kurtosis: 012.57
v_12            Skewness: 00.37     Kurtosis: 000.27
v_13            Skewness: 00.27     Kurtosis: -00.44
v_14            Skewness: -1.19     Kurtosis: 002.39
price           Skewness: 03.35     Kurtosis: 019.00

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

各個數(shù)值特征之間的相關性

sns.set()columns = num_feassns.pairplot(Train_data[columns], size = 2 , kind = 'scatter', diag_kind ='kde', palette = "PuBu")plt.show()
D:\Software\Anaconda\lib\site-packages\seaborn\axisgrid.py:2065: UserWarning: The `size` parameter has been renamed to `height`; pleaes update your code.
  warnings.warn(msg, UserWarning)

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

可以看出成閉團狀的相關圖還是很多的,說明相應特征的相關度比較大。

  • price與其他變量相關性可視化

這里用匿名變量v0~v13進行分析,使用seabornregplot函數(shù)進行相關度回歸分析。

Y_train = Train_data['price']fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8), (ax9, ax10),(ax11, ax12),(ax13,ax14)) = plt.subplots(nrows = 7, ncols=2, figsize=(24, 20))ax = [ax1, ax2, ax3, ax4, ax5, ax6, ax7, ax8, ax9, ax10, ax11, ax12, ax13, ax14]for num in range(0,14):    sns.regplot(x = 'v_' + str(num), y = 'price', data = pd.concat([Y_train, Train_data['v_' + str(num)]],axis = 1), scatter = True, fit_reg = True, ax = ax[num])
在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

可以看出大部分匿名變量的分布還是比較集中的,當然線性回歸的性能確實太弱了。

至于類別特征的回歸分析,本身可以參考的意義不大,就暫時省略了。

2??.5??.2?? pandas_profiling生成數(shù)據(jù)報告??

pandas_profiling生成一個較為全面的可視化和數(shù)據(jù)報告(較為簡單、方便)最終打開html文件即可

import pandas_profilingfile = pandas_profiling.ProfileReport(Train_data)pfr.to_file("pandas_analysis.html")

長這個樣子:

在這里插入圖片描述

在這里插入圖片描述

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">在這里插入圖片描述</figcaption>

在這里插入圖片描述

具體文件在這里我的天池

3?? 結語??

至此賽題的賽題理解以及數(shù)據(jù)分析工作告一段落,總結一下:

  • 運用describe()info()進行數(shù)據(jù)基本統(tǒng)計量的描述

  • 運用missingno庫和pandas.isnull()來對異常值和缺失值進行可視化察覺以及處理

  • 熟悉偏度(Skewness)與峰度(Kurtosis)的概念,可以用skeu()kurt()計算其值

  • 在確定預測值的范圍與分布后,可以做一些取對數(shù)或者開根號的方式緩解數(shù)據(jù)集中的問題

  • 相關性分析時

    • corr()計算各特征的相關系數(shù)
    • seabornheatmap畫出相關系數(shù)的熱力圖
    • seabornFacetGridpairplot可以分別畫出各特征內部之間以及預測值與其他特征之間的數(shù)據(jù)分布圖
    • 也可以用seabornregplot來對預測值與各特征的關系進行回歸分析

開始下一步特征工程。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容