- 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ù)報告??
- 2??.5??.1??
驚聞4.13日江蘇省高校將要啟動開學模式,我自巋然不動。山中何事?松花釀酒,春水煎茶,如是而已。
1?? 賽題理解??
1??.1?? 賽題重述
這是一道來自于天池的新手練習題目,用數(shù)據(jù)分析、機器學習等手段進行 二手車售賣價格預測 的回歸問題。賽題本身的思路清晰明了,即對給定的數(shù)據(jù)集進行分析探討,然后設計模型運用數(shù)據(jù)進行訓練,測試模型,最終給出選手的預測結果。
1??.2?? 數(shù)據(jù)集概述
賽題官方給出了來自Ebay Kleinanzeigen的二手車交易記錄,總數(shù)據(jù)量超過40w,包含31列變量信息,其中15列為匿名變量,即v0至v15。并從中抽取15萬條作為訓練集,5萬條作為測試集A,5萬條作為測試集B,同時對name、model、brand和regionCode等信息進行脫敏。具體的數(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ù)只是一列列的向量,所以首要解決的就是向量的重要性。
- 數(shù)據(jù)集里面包含的很多維度的數(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)
- 可以看出,數(shù)據(jù)的分散程度很大,有整型,有浮點,有正數(shù),有負數(shù),還有日期,當然可以當成是字符串。另外如果數(shù)據(jù)都換算成數(shù)值的話,數(shù)據(jù)間差距特別大,有些成千上萬,有些幾分幾厘,這樣在預測時就難以避免地會忽視某些值的作用,所以需要對其進行歸一化。
-
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進行判斷然后返回True或False。
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ù)值主要集中在
bodyType,fuelType,gearbox,這三個特征中。訓練集中model缺失了一個值,但是無傷大雅。至于如何填充,亦或是刪除這些數(shù)據(jù),需要后期在選用模型時再做考慮。-
同時我們也可以通過
missingno庫查看缺省值的其他屬性。- 矩陣圖
matrix - 柱狀圖
bar - 熱力圖
heatmap - 樹狀圖
dendrogram
- 矩陣圖
缺省熱力圖
熱力圖表示兩個特征之間的缺失相關性,即一個變量的存在或不存在如何強烈影響的另一個的存在。如果x和y的熱度值是1,則代表當x缺失時,y也百分之百缺失。如果x和y的熱度相關性為-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是顏色取反。
關于seaborn的heatmap可以看這里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進行分析,使用seaborn的regplot函數(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ù) - 用
seaborn的heatmap畫出相關系數(shù)的熱力圖 - 用
seaborn的FacetGrid和pairplot可以分別畫出各特征內部之間以及預測值與其他特征之間的數(shù)據(jù)分布圖 - 也可以用
seaborn的regplot來對預測值與各特征的關系進行回歸分析
- 用
開始下一步特征工程。