1. 程式人生 > 實用技巧 >12-機器學習-資料探索性分析EDA應用實踐

12-機器學習-資料探索性分析EDA應用實踐

  • 資料集背景介紹
    • 2009年的《紐約市基準法律》要求對建築的能源和水的使用資訊進行說明和評分。 涵蓋的建築包括具有單個建築物的總建築面積超過50,000平方英尺(平方英尺),和群建築面積超過100,000平方英尺。指標是由環境保護署的工具ENERGY STAR Portfolio Manager計算的,並且資料由建築物所有者自行報告。(迴歸問題)
  • 欄位說明
    • 目標資料:
      • ENERGY STAR Score:指定建築物型別的1到100百分位排名,在投資組合管理器中根據自我報告計算報告年度的能源使用情況。

資料匯入

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns from sklearn.model_selection import train_test_split data = pd.read_csv('data/Energy_and_Water_Data_Disclosure_for_Local_Law_84_2017__Data_for_Calendar_Year_2016_.csv') data.head(1)

檢視資料形狀

# 檢視資料形狀
data.shape   # (11746, 60)

檢視資料欄位型別和是否存在缺失值

# 檢視資料欄位型別和是否存在缺失值
data.info()

資料集中的欄位中存有Not Available值,該值表示無效值可以視為缺失值被處理

# 首先將"Not Available"替換為 np.nan 
data = data.replace({'Not Available': np.nan})

資料集有的欄位顯示為數值型資料,但是實際型別為str,再將部分數值型資料轉換成float

# 資料集有的欄位顯示為數值型資料,但是實際型別為str,再將部分數值型資料轉換成float
for col in list(data.columns):
    if ('ft²'
in col or 'kBtu' in col or 'Metric Tons CO2e' in col or 'kWh' in col or 'therms' in col or 'gal' in col or 'Score' in col): data[col] = data[col].astype(float)

通過 describe 和 matplotlib 視覺化檢視資料的相關統計量(柱狀圖)3

data.describe()
# 通過 describe 和 matplotlib 視覺化檢視資料的相關統計量(柱狀圖)
data_desc = data.describe() # 檢視資料描述
cols = data_desc.columns # 取得列縮影
index = data_desc.index[1:] # 去除count行
plt.figure(figsize=(30, 30))  # 控制畫布大小
for i in range(len(cols)):
    ax = plt.subplot(10,6,i+1) # 繪製10x6的表格,當前資料特徵維度為60
    ax.set_title(cols[i]) # 設定標題
    for j in range(len(index)):
        plt.bar(index[j], data_desc.loc[index[j], cols[i]]) # 對每個特徵繪製describe柱狀圖
plt.show()
# Order的圖形比較正常,因為最小值,中位數,最大值是錯落分佈,正常分佈的,且均值和標準差分佈也正常
# DOF Gross Floor Area圖形可能有問題,顯示最大值比其他的值都大很多(離均點,異常值),如果最大值的資料數量較少,則考慮將其刪除
# 發現:經度,維度特徵的std極低,且數值分佈特別均勻,說明這倆列特徵對結果影響幾乎為0,適當考慮過濾該特徵

檢視每列的缺失值比例

封裝檢視每列缺失值比例函式

  檢視每列的缺失值比例,估計大家有很多種方法可以做,可以給大家提供一個函式,聰明的同學把他當做自己的工具吧,以後你會常用到的

# 檢視缺失值
def missing_values_table(df):
        # 計算每一列缺失值的個數
        mis_val = df.isnull().sum(axis=0)
        
        # 計算每列缺失值佔該列總資料的百分比
        mis_val_percent = 100 * df.isnull().sum(axis=0) / data.shape[0]
        
        # 將每一列缺失值的數量和缺失值的百分比級聯到一起,形成一個新的表格
        mis_val_table = pd.concat([mis_val, mis_val_percent], axis=1)
        
        # 重新給上步表格的列命名
        mis_val_table_ren_columns = mis_val_table.rename(
        columns = {0 : 'Missing Values', 1 : '% of Total Values'})
        
        # 將百分比不為0的行資料根據百分比進行降序排序
        mis_val_table_ren_columns = mis_val_table_ren_columns[
            mis_val_table_ren_columns.iloc[:,1] != 0].sort_values(
        '% of Total Values', ascending=False).round(1)
        
        # 列印概述
        print ("Your selected dataframe has " + str(df.shape[1]) + " columns.\n"      
            "There are " + str(mis_val_table_ren_columns.shape[0]) +
              " columns that have missing values.")
        
        # Return the dataframe with missing information
        return mis_val_table_ren_columns

呼叫函式檢視缺失值及比例

missing_df = missing_values_table(data);
missing_df.head(3)

Your selected dataframe has 60 columns.
There are 46 columns that have missing values.

# 下面缺失比例比較大

設定閾值將缺失比例超過百分之50的列刪除

# 設定閾值將缺失比例超過百分之50的列刪除
# 找出超過閾值的列
missing_df = missing_values_table(data);
missing_columns = list(missing_df.loc[missing_df['% of Total Values'] > 50].index)
print('We will remove %d columns.' % len(missing_columns))
data = data.drop(columns = list(missing_columns))

Your selected dataframe has 60 columns.
There are 46 columns that have missing values.
We will remove 11 columns. 

中位數填充剩下的空值

# 中位數填充剩下的空值 np.median獲取中位數,如果原始資料存在空值就會返回空nan
for x in data.columns:
    # 去除object型別的列(object列不存在中位數)
    if str(data[x].dtypes) == 'object':
        continue
    if data[x].isnull().sum() > 0:
        # 取出每列非空元素求得中位數進行填充
        data[x] = data[x].fillna(value=np.median(data.loc[~data[x].isnull(),x]))      

檢視目標資料的分佈情況

# 檢視目標資料的分佈情況
data['ENERGY STAR Score'].hist(bins=20)
plt.figure(figsize=(40,20))
plt.scatter(data['ENERGY STAR Score'].index,data['ENERGY STAR Score'].values)
# 由圖看到集中到60多出現一條線,說明資料集中在60多,沒有找到離群資料
 
data['ENERGY STAR Score'].value_counts().sort_values().tail(1)

65.0    2216
Name: ENERGY STAR Score, dtype: int64

發現分佈在65的資料量是最多的,沒有發現離群資料

什麼是離群點資料?

存在著一些特別大或者特別小的值,這些可能是離群點或記錄錯誤點,對我們結果會有一些影響的。那我們是需要將離群點資料進行過濾的。

  • 離群點:離群點是指一個數據序列中,遠離序列的一般水平的極端大值和極端小值,且這些值會對整個資料的分析產生異常的影響。
  • 傳統的過濾方式:
    • Q1 - 3 * IQ:Q1為序列中25%的中位數,IQ為Q3-Q1
    • Q3 + 3 * IQ:Q3為序列中75%的中位數,IQ為Q3-Q1
  • 離群點判定:
    • 極小的離群點資料:x < (q1 - 3 * iq)
    • 極大的離群點資料:x > (q3 + 3 * iq)

    

假設我們的目標資料為Site EUI (kBtu/ft²)

尋找離群點

data['Site EUI (kBtu/ft²)'].hist(bins=20)
plt.figure(figsize=(15,8))
plt.scatter(data['Site EUI (kBtu/ft²)'].index,data['Site EUI (kBtu/ft²)'].values)