datawhale 學習筆記——數據分析入門

寫在前面(這部分是廢話)

這是參加 datawhale 數據挖掘的第一次打卡,打卡內容是數據分析,希望自己能堅持做下去。開始的時候,第一天看了一下題目背景,運行了一下 baseline,剛好中期報告要改,就放下了。今天在這裏做一下數據分析這部分的筆記。

介紹

本文主要是根據天池上的教程進行學習的,一些不理解地方做了筆記,內容沒有教程全,附上教程鏈接:Datawhale 零基礎入門數據挖掘-Task2 數據分析

數據分析主要的三個工具: pandas、numpy、scipy。(以前只用過 numpy)
可視化的兩個主要工具: matplotlib、seabon。(以前只用過 matplotib)

接下來通過代碼加個人理解記錄一下數據分析的過程。

數據分析過程

環境配置就不記錄了,很無聊。首先需要導入一下包:

#coding:utf-8
#導入warnings包,利用過濾器來實現忽略警告語句。
import warnings
warnings.filterwarnings('ignore')

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno

後續代碼默認使用如上導入的包。

載入數據

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=' ')
print(Train_data.shape)
print(Test_data.shape)

輸出:

(150000, 31)
(50000, 30)

使用 pands 庫可以很方便地讀取數據。這裏的 pd.read_csv() 函數有很多參數,這裏只設置了兩個: filepath_or_buffer 參數表示文件的路徑; sep 表示數據使用什麼符號分隔的,默認 sep = ','。還有很多其他參數,如 index_col 指定讀取哪寫列數據、shkiprows=n 跳過前 n 行數據…

查看數據

pd.read_csv() 函數返回的數據類型是 DataFrame,是 pandas 中特有的數據類型,相當於高級版的二維數組,可以通過它實現很多操作,封裝了很多處理數據的函數。

關於 DataFrame 更多方法介紹,建議參考 python下的Pandas中DataFrame基本操作(一),基本函數整理

head(n=5)

可以通過 head(n) 函數展示數據的前 n 行數據,默認 n=5

print(Train_data.head())

運行結果:

Train_data的前五行數據可視化

tail(n=5)

head() 函數相反,tail(n) 函數返回的是數據後 n 行數據,默認 n=5

print(Train_data.tail())

運行結果:
Train_data的後五行數據可視化

總覽數據

在查看了數據之後,對數據的樣子就會有個大概的認識。但更多時候,只是查看數據長什麼樣子是不夠的,還需要查看數據的性質,包括數據方差、個數等等。下面是幾個常用的總覽數據的方法。

describe(percentiles=None, include=None, exclude=None)

describe() 是針對 pandasSeriesDataFrame 所有的列進行數據統計的一種方法。函數是用來查看數值特徵的一些信息,返回特徵的總數、均值、標準差、最小值、分位數、最大值。

這裏解釋下函數的三個參數,具體理解,還請參考官網 pandas-dataframe-describe

  • percentiles:數組類型,表示分位線。所有值應該是(0,1)之間的小數,默認是 [.25, .5, .75],返回 25%, 50%和75%

  • include, exclude : 列表類型,指定輸出結果的形式。分三種情況,當二者都爲 None 時,結果只包含數值類型的統計信息;如果是一組 dtypesstrings,所有數值類型使用 numpy.number,類別屬性使用 type;如果 include='all',則輸出的列與輸入相同。

示例:

print(Train_data.describe())

運行結果:
describe()函數總覽數據
其中,百分數 25%, 50%和75% 表示分位數,表示在把所有數值由小到大排序,並分成四等份,處於三個分割點位置的數值。

info(verbose=None, buf=None, max_cols=None, memory_usage=None, null_counts=None)

info() 函數可以用來查看 DataFrame 信息, 能夠簡要看到對應一些數據列名,瞭解數據每列的 type,以及 NAN 缺失信息。

參數介紹:

  • verbose:如果爲True,則顯示所有列;如果爲False,則會省略一部分。
  • buf:結果輸出到的位置。
  • max_cols:輸出列的最大數目,超過則進行縮減輸出。
  • memory_usage:是否顯示 DataFrame 的內存使用情況,缺省(None)時,默認爲 True。
  • null_counts:是否顯示非空計數。

示例:

print(Train_data.info())

運行結果:

info() 的輸出信息

數據缺失和異常

統計數據信息查看完後,還要進一步查看數據是否異常,如 nan 或 null。

isnull()

isnull() 函數,以布爾的方式返回所有數據是否爲 null 的信息,返回值的類型也是 DataFrame

示例:

Train_data.isnull().sum()

運行結果:

在這裏插入圖片描述

其中,sum() 函數按列進行求和,返回一個 Series 類型的值。

缺失數據的可視化

示例:

missing = Train_data.isnull().sum()
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()  # 垂直條形圖
plt.show()

運行結果:

空數據可視化

示例:

msno.matrix(Train_data.sample(250))
plt.show()

sample() 函數表示隨機選取若干行。

運行結果:

缺省信息

示例:

msno.bar(Train_data.sample(1000))
plt.show()

直方圖

統計信息

查看類型爲 object 特徵:

print(Train_data['notRepairedDamage'].value_counts())

輸出:

0.0 111361
- 24324
1.0 14315 Name: notRepairedDamage, dtype: int64

將值替換成 nan:

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

輸出:

0.0 111361
1.0 14315
Name: notRepairedDamage, dtype: int64

去掉傾斜嚴重的特徵

查看以下兩個特徵(按照教程做的,事先肯定不知道哪個特徵嚴重傾斜)

print(Train_data["seller"].value_counts())
print(Train_data["offerType"].value_counts())

輸出:

0 149999
1 1
Name: seller, dtype: int64
0 150000
Name: offerType, dtype: int64

分析數據分佈

查看要預測數據(price)的分佈信息:

import scipy.stats as st
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)
plt.show()

就不展示圖像了。

查看偏度和峯度

簡單理解一下偏度和峯度的概念,參考:數據的偏度和峯度——df.skew()、df.kurt()

  • 偏度: 表示數據總體取值分佈的對稱性。

  • 峯度: 表示數據分佈頂的尖銳程度。

sns.distplot(Train_data['price']);
print("Skewness: %f" % Train_data['price'].skew())
print("Kurtosis: %f" % Train_data['price'].kurt())
plt.show()

運行結果:
預測的數據分佈

Skewness: 3.346487
Kurtosis: 18.995183

查看幀數,更具體地查看數據分佈

plt.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
# log 變換後的分佈
plt.hist(np.log(Train_data['price']), orientation = 'vertical',histtype = 'bar', color ='red') 
plt.show()

在這裏插入圖片描述

會發現大於 20000 的數據很少。

做 log 之後的數據分佈圖:

做log之後的數據分佈圖

會發現數據分佈不像之前那樣集中了。

特徵分類

select_dtypes()

特徵分爲類別特徵和數字特徵。可以使用 select_dtypes() 函數查看兩種特徵各包含哪些列:

# 數字特徵
numeric_features = Train_data.select_dtypes(include=[np.number])
print(numeric_features.columns)
# 類別特徵
categorical_features = Train_data.select_dtypes(include=[np.object])
print(categorical_features.columns)

運行結果:

Index([‘SaleID’, ‘name’, ‘regDate’, ‘model’, ‘brand’, ‘bodyType’, ‘fuelType’,
‘gearbox’, ‘power’, ‘kilometer’, ‘regionCode’, ‘creatDate’, ‘price’,
‘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’],
dtype=‘object’)
Index([‘notRepairedDamage’], dtype=‘object’)

注意:這個區別方式適用於沒有直接label coding的數據,這裏把很多類別特徵用數字表示了,因此該方法在該比賽中不適用,需要人爲根據實際含義來區分

unique() 和 nunique()

unique() 函數返回的是特徵的所有唯一值;nunique() 函數返回的是特徵中所有唯一值的個數。

示例,查看每個分類特徵的分佈:

# 特徵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())

接下來詳細介紹一下數字特徵和類別特徵。

數字特徵分析

好多啊,,,後面兩部分簡寫一下。。。

1. 使用 corr() 分析相關性

corr() 函數返回的是各個特徵之間的相關係數,是 DataFrame 類型。

示例:

# 數字特徵
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' ]
numeric_features.append('price')
## 1) 相關性分析
price_numeric = Train_data[numeric_features]
correlation = price_numeric.corr()
print(correlation['price'].sort_values(ascending = False),'\n')

運行結果:
在這裏插入圖片描述

以熱力圖的形式畫出各個數字特徵之間的相關係數:

# 畫相關係數圖
plt.title('Correlation of Numeric Features with Price',y=1,size=16)
sns.heatmap(correlation, square=True, vmax=0.8)
plt.show()

運行結果:

熱力圖表示各個特徵之間的相關係數

關於熱力圖的畫法,參考:sns.heatmap的用法簡介

2. 查看各個特徵的偏度和峯度

示例:

## 2) 查看幾個特徵的 偏度和峯值
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())  
         )

運行結果:
各個特徵的偏度和峯度

3. 每個數字特徵得分佈可視化

示例:

## 3) 每個數字特徵的分佈可視化
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")
plt.show()

melt() 函數是一個逆轉操作,其中的 value_vars 參數表示需要轉換的列名。

運行結果:
在這裏插入圖片描述

4. 數字特徵相互之間的關係可視化

## 4) 數字特徵相互之間的關係可視化
sns.set()
columns = ['price', 'v_12', 'v_8' , 'v_0', 'power', 'v_5',  'v_2', 'v_6', 'v_1', 'v_14']
sns.pairplot(Train_data[columns],size = 2 ,kind ='scatter',diag_kind='kde')
plt.show()

數字特徵關係的可視化

5. 多變量互相迴歸關係可視化

參考:Seaborn-05-Pairplot多變量圖

分類特徵

好多畫圖的,不想記錄了,這部分簡寫一下。

  1. unique分佈(前面記錄了)

  2. 類別特徵箱形圖可視化

  3. 類別特徵的小提琴圖可視化

  4. 類別特徵的柱形圖可視化

  5. 類別特徵的每個類別頻數可視化(count_plot)

pandas_profiling

最後,可以用 pandas_profiling 生成一個較爲全面的可視化和數據報告。

最後

後面的內容就簡單寫了一下過程,後續還會補充點東西,主要是瞭解整個數據分析的過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章