【零基础入门数据挖掘】-数据分析
?Datawhale?
作者:王瑞楠,Datawhale優秀學習者
摘要:對于數據挖掘項目,本文將學習應該從哪些角度分析數據?如何對數據進行整體把握,如何處理異常值與缺失值,從哪些維度進行特征及預測值分析?
探索性數據分析(Exploratory Data Analysis,EDA)是指對已有數據在盡量少的先驗假設下通過作圖、制表、方程擬合、計算特征量等手段探索數據的結構和規律的一種數據分析方法。
數據及背景
https://tianchi.aliyun.com/competition/entrance/231784/information(阿里天池-零基礎入門數據挖掘)
EDA的目標
熟悉數據集,了解數據集,對數據集進行驗證來確定所獲得數據集可以用于接下來的機器學習或者深度學習使用。
了解變量間的相互關系以及變量與預測值之間的存在關系。
引導數據科學從業者進行數據處理以及特征工程的步驟,使數據集的結構和特征集讓接下來的預測問題更加可靠。
數據載入及總覽
載入各種數據科學以及可視化庫
missingno庫用于可視化缺失值分布,是基于matplotlib的,接受pandas數據源
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import missingno as msno # 用于可視化缺失值分布 import?scipy.stats?as?st載入數據
path = './data/' Train_data = pd.read_csv(path+'used_car_train_20200313.csv', sep=' ') Test_data?=?pd.read_csv(path+'used_car_testA_20200313.csv',?sep='?')所有特征集均脫敏處理,脫敏處理后均為label encoding形式,即數字形式
總覽數據
簡略觀察數據head()+shape
Train_data.head().append(Train_data.tail()) Test_data.head().append(Test_data.tail()) Train_data.shape Test_data.shapedescribe()熟悉相關統計量
describe()中包含每列的統計量,個數(count)、平均值(mean)、方差(std)、最小值(min)、中位數(25% 50% 75%)、最大值(max)等。通過觀察以上指標,可以瞬間掌握數據的大概范圍和每個值的異常值的判斷 ,例如有時候會發現999 9999、 -1 等值這些其實都是nan的另外一種表達方式。
Train_data.describe()info()熟悉數據類型
通過info()來了解數據每列的type,有助于了解是否存在除了nan以外的特殊符號異常。
Train_data.info()缺失值和異常值
缺失值
查看每列的存在nan情況
排序函數sort_values()
可以將數據集依照某個字段中的數據進行排序,該函數即可根據指定列數據也可根據指定行的
通過以下兩句可以很直觀的了解哪些列存在 “nan”, 并可以把nan的個數打印。主要的目的在于 nan存在的個數是否真的很大,如果很小一般選擇填充,如果使用lgb等樹模型可以直接空缺,讓樹自己去優化,但如果nan存在的過多、可以考慮刪掉。
# nan可視化 missing = Train_data.isnull().sum() missing = missing[missing > 0] missing.sort_values(inplace=True) missing.plot.bar() # 可視化缺省值 msno.matrix(Train_data.sample(250)) msno.bar(Train_data.sample(1000)) msno.matrix(Test_data.sample(250)) msno.bar(Test_data.sample(1000))從上文Train_data.info()的統計信息可以發現,除了notRepairedDamage 為object類型其他都為數字。接下來將notRepairedDamage中幾個不同的值都進行顯示如下:
Train_data['notRepairedDamage'].value_counts()可以看出‘ - ’也為空缺值,因為很多模型對nan有直接的處理,這里我們先不做處理,先替換成nan。
Train_data['notRepairedDamage'].replace('-', np.nan, inplace=True) Train_data['notRepairedDamage'].value_counts() Train_data.isnull().sum()異常值
以下兩個類別特征:seller和offerType嚴重傾斜,一般不會對預測有什么幫助,故這邊先刪掉,當然你也可以繼續挖掘,但是一般意義不大
Train_data["seller"].value_counts() Train_data["offerType"].value_counts() del Train_data["seller"] del Train_data["offerType"] del Test_data["seller"] del Test_data["offerType"]預測值分布
總體分布概況
數據整體服從正態分布,樣本均值和方差則相互獨立,正態分布具有很多好的性質,很多模型也假設數據服從正態分布。
例如線性回歸(linear regression),它假設誤差服從正態分布,從而每個樣本點出現的概率就可以表示為正態分布形式,將多個樣本點連乘再取對數,就是所有訓練集樣本出現的條件概率,最大化該條件概率就是LR最終求解的問題。這個條件概率的最終表達式的形式就是我們熟悉的誤差平方和。
總之, 機器學習中很多model都假設數據或參數服從正態分布。當樣本不服從正態分布時,可以做如下轉換:
線性變化z-scores
使用Boxcox變換
使用yeo-johnson變換
盲目假設變量服從正態分布可能導致不準確的結果,要結合分析。例如:不能假設股票價格服從正態分布,因為價格不能為負,故我們可以將股票價格假設為服從對數正態分布,以確保其值≥0;而股票收益可能是負數,因此收益可以假設服從正態分布。
當樣本數據表明質量特征的分布為非正態時,應用基于正態分布的方法會作出不正確的判決。約翰遜分布族即為經約翰(yeo-johnson)變換后服從正態分布的隨機變量的概率分布,約翰遜分布體系建立了三族分布,分別為有界SB 、對數正態SL和無界SU。
本案例的預測值為價格,顯然不符合正態分布,故分別采用無界約翰遜分布Johnson SU、正態分布normal、對數正態分布lognormal,綜合來看無界約翰遜分布對price的擬合效果更好。
y = Train_data['price'] plt.figure(1); plt.title('Johnson SU') sns.distplot(y, kde=False, fit=st.johnsonsu) plt.figure(2); plt.title('Normal') sns.distplot(y, kde=False, fit=st.norm) plt.figure(3); plt.title('Log Normal') sns.distplot(y,?kde=False,?fit=st.lognorm)偏度和峰度
sns.distplot(Train_data['price']); print("Skewness: %f" % Train_data['price'].skew()) print("Kurtosis: %f" % Train_data['price'].kurt()) sns.distplot(Train_data.skew(),color='blue',axlabel ='Skewness') sns.distplot(Train_data.kurt(),color='orange',axlabel?='Kurtness') Train_data.skew(), Train_data.kurt()
預測值頻數
大于20000的值很少,其實該處可將其當作異常值處理填充或刪除,本文中經過log變換之后,分布較均勻,可據此進行預測,這也是預測問題常用的技巧
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()特征分析
數字特征
‘seller’和‘offerType’已被刪除,其他特征均經過了label coding。若需要處理的數據未label coding,則可通過如下代碼對特征進行區分:
# 數字特征 numeric_features = Train_data.select_dtypes(include=[np.number]) numeric_features.columns # 類型特征 categorical_features = Train_data.select_dtypes(include=[np.object]) categorical_features.columns本文數據已經label coding,故采用人工區分方法:
numeric_features?=?['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'?] categorical_features?=?['name',?'model',?'brand',?'bodyType',?'fuelType',?'gearbox',?'notRepairedDamage',?'regionCode']總覽
相關性分析
price_numeric = Train_data[numeric_features] correlation = price_numeric.corr() print(correlation['price'].sort_values(ascending=False),'\n') f, ax = plt.subplots(figsize = (7, 7)) plt.title('Correlation of Numeric Features with Price',y=1,size=16) sns.heatmap(correlation,square = True, vmax=0.8) del?price_numeric['price']特征偏度和峰值
for col in numeric_features:print('{:15}'.format(col), 'Skewness: {:05.2f}'.format(Train_data[col].skew()) , ' ' ,'Kurtosis: {:06.2f}'.format(Train_data[col].kurt()) )每個數字特征的分布可視化
pd.melt():處理數據,透視表格,可將寬數據轉化為長數據,以便于后續分析。形成的數據即為,鍵:各特征名稱,值:特征對應的值
sns.FacetGrid() :先sns.FacetGrid()畫出輪廓,再map()填充內容
f = pd.melt(Train_data, value_vars=numeric_features) g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False) g = g.map(sns.distplot, "value")匿名特征分布情況
sns.pairplot():展示變量兩兩之間的關系(線性或非線性,有無較為明顯的相關關系):
對角線:各個屬性的直方圖,用diag_kind屬性控制圖類型,可選"scatter"與"reg"
非對角線:兩個不同屬性之間的相關圖,用kind屬性控制圖類型,可選"scatter"與"reg"
hue :針對某一字段進行分類
多變量與price的回歸關系
類別特征
查看nunique分布
for cat_fea in categorical_features:print(cat_fea + '特征分布如下:')print('{}特征有{}個不同的值'.format(cat_fea, Train_data[cat_fea].nunique()))print(Train_data[cat_fea].value_counts())查看箱型圖
直觀識別數據中的離群點
直觀判斷數據離散分布情況,了解數據分布狀態
查看小提琴圖
用于顯示數據分布及概率密度
這種圖表結合了箱形圖和密度圖的特征,主要用來顯示數據的分布形狀
查看柱形圖
def bar_plot(x, y, **kwargs):sns.barplot(x=x, y=y)x=plt.xticks(rotation=90)f = pd.melt(Train_data, id_vars=['price'], value_vars=categorical_features) g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False, size=5) g?=?g.map(bar_plot,?"value",?"price")類別頻數可視化
def count_plot(x, **kwargs):sns.countplot(x=x)x=plt.xticks(rotation=90)f = pd.melt(Train_data, value_vars=categorical_features) g = sns.FacetGrid(f, col="variable", col_wrap=2, sharex=False, sharey=False, size=5) g?=?g.map(count_plot,?"value")生成數據報告
用pandas_profiling生成一個較為全面的可視化和數據報告(較為簡單、方便) 最終打開html文件即可
import pandas_profiling pfr = pandas_profiling.ProfileReport(Train_data) pfr.to_file("./example.html")參考
【1】構建模型時為什么要盡量將偏態數據轉換為正態分布數據?
【2】張維銘,施雪忠,樓龍翔.非正態數據變換為正態數據的方法[J].浙江工程學院學報,2000(03):56-59.
【3】偏度與峰度的正態性分布判斷
【4】數據的偏度和峰度——df.skew()、df.kurt()
【5】Melt函數處理數據,透視表格,寬數據變成長數據
【6】seaborn可視化之FacetGrid()
【7】Seaborn5分鐘入門(七)——pairplot
【8】箱型圖和小提琴圖分析
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習在線手冊深度學習在線手冊AI基礎下載(pdf更新到25集)本站qq群1003271085,加入微信群請回復“加群”獲取一折本站知識星球優惠券,請回復“知識星球”喜歡文章,點個在看
總結
以上是生活随笔為你收集整理的【零基础入门数据挖掘】-数据分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【零基础入门数据挖掘】-建模调参
- 下一篇: 备战2020腾讯广告算法大赛:(2017