機器學習:探索資料和資料預處理

悅光陰發表於2020-12-13

機器學習之預測房價系列:

 

探索資料是指研究資料,發現資料的結構。資料集由資料物件構成,一個資料物件代表一個實體,實體由屬性構成,屬性是一個資料欄位,表示資料物件的一個特徵,通常,在資料分析和機器學習中,屬性、維度、特徵和變數這四個術語可以互換。

用來描述一個資料物件的一組屬性,稱作屬性向量或者特徵向量。一個屬性的型別是由該屬性的值決定的,屬性可以是標稱的、二元的、序數的和數值的。

本文使用的資料,使用以下指令碼獲得,案例是預測某個區域的房價,本文重點關注的是如何探索資料和對資料進行預處理。

機器學習:探索資料和資料預處理
import os
import tarfile
import urllib
import pandas as pd

DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml2/master/"
HOUSING_PATH = os.path.join("datasets", "housing")
HOUSING_URL = DOWNLOAD_ROOT + "datasets/housing/housing.tgz"

def fetch_housing_data(housing_url=HOUSING_URL, housing_path=HOUSING_PATH):
    if not os.path.isdir(housing_path):
        os.makedirs(housing_path)
    tgz_path = os.path.join(housing_path, "housing.tgz")
    urllib.request.urlretrieve(housing_url, tgz_path)
    housing_tgz = tarfile.open(tgz_path)
    housing_tgz.extractall(path=housing_path)
    housing_tgz.close()


def load_housing_data(housing_path=HOUSING_PATH):
    csv_path = os.path.join(housing_path, "housing.csv")
    return pd.read_csv(csv_path)

#get data
fetch_housing_data()
housing = load_housing_data()
View Code

快速檢視資料的結構,每一行代表一個區域,共有10個屬性,其中median_house_value是需要預測的屬性值。

housing.head()

一,屬性

屬性可以分為兩大類:定性屬性和定量屬性,還可以把屬性分為離散屬性和連續屬性。

1,定性屬性和定量屬性

定性屬性:

  • 標稱屬性:屬性的值代表類別、編碼或狀態,因此標稱屬性被看作是分類屬性。
  • 二元屬性:屬性只有兩個類別或狀態,0和1
  • 序數屬性:屬性值之間存在有意義的順序,比如成績等級可以分為:差、良、優,

定量屬性是定量的,它的值是可度量的,用整數或實數來表示,定量屬性分為標量和比率。

  • 數量屬性:標量數值,比如成績、溫度、銷量等
  • 比率屬性:表示一個值是另一個的倍數(或比率),比如,增長率、佔比等。

2,離散屬性和連續屬性

離散屬性是指存在有限個值,或可數的值

連續屬性:值的個數是不可數的

3,對housing資料按照屬性進行分析

housing資料共有10個屬性,其中9個屬性屬於標量屬性,1個標稱屬性。

標量屬性:

  • longitude 和 latitude:表示區域的經緯度,
  • housing_median_age :表示房齡中位數
  • total_rooms:區域中的總房間數量
  • total_bedrooms:區域中的總臥室數量
  • population:區域中的人口數量
  • households:區域中的家庭數量
  • median_income :區域中的人口收入中位數

標稱屬性:

  • ocean_proximity:近海

預測值是標量值:

  • median_house_value:房屋價值中位數

二,資料的基本統計描述

資料的基本統計描述,是對資料集的整體做一個統計描述,通常是對一個屬性進行統計分析。

1,總體數量統計

值的數量、唯一值的數量

2,缺失值

屬性欄位是否存在缺失值

3,中心趨勢分析

  • 均值
  • 中位數
  • 眾數

4,離中趨勢分析

值域:最小值和最大值之間的差值

方差和標準差:對同一值域的屬性來說,標準差越大,資料的離散程度越大

四分位數:箱線圖分析,特別是四分位數間距(IQR),它是上四分位數QU和下四分位數QL之差,其間包含全部觀察值的一般,其值越大,說明資料的變異程度越大,離中趨勢越明顯。

5,對屬性值進行基本的統計分析

使用DataFrame的describe()函式,對變數屬性進行基本的統計描述分析,行索引是count :表示統計非NaN的行數,mean表示均值,std表示標準差,最大值、最小值、上四分位數(25%),中位數(50%)和下四分位數(75%)。

housing.describe()

三,屬性的直方圖

在Jupyter notebooks中顯示屬性的直方圖,檢視屬性值的分佈情況,通過DataFrame的hist(),可以對標量屬性檢視直方圖。

%matplotlib inline
import matplotlib.pyplot as plt
housing.hist(bins=50, figsize=(20,15))
plt.show()

從直方圖中可以看出,除了經緯度latitude 和 longitude之外,有5個屬性households、population、total_bedrooms、total_rooms和meidan_income的直方圖中出現重尾現象,呈現出左偏分佈,中位數右側的延伸比左側要遠的多,餘下的2個屬性 housing_median_age 和 median_house_value的直方圖,最右側都呈現出一個異常的值。

對於屬性直方圖中出現的重尾分佈,有時需要對資料進行轉換,比如計算其對數。

四,屬性之間的相關性

利用相關係數檢視各個屬性之間的相關性,用於發現不同變數之間的關聯性,關聯是指資料之間變化的相似性,這可以通過相關係數來描述。發現相關性可以幫助你預測未來,而發現因果關係意味著你可以改變世界。 

由於housing的資料集不大,可以使用DataFrame.corr()方法計算出每隊屬性之間的標準相關係數(也稱作皮爾遜r),檢視median_house_value和其他屬性的相關係數:

corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)

從相關係數中可以看出:median_house_value 和 median_income的相關係數是最高的,這也符合“房價和收入呈現正相”的常識。

median_house_value 1.000000
median_income 0.687160
total_rooms 0.135097
housing_median_age 0.114110
households 0.064506
total_bedrooms 0.047689
population -0.026920
longitude -0.047432
latitude -0.142724
Name: median_house_value, dtype: float64

還有一種方法用於檢測屬性之間的相關性,就是使用pandas的scatter_matrix函式,它會繪製出每個數值屬性相對於其他數值屬性的相關性。

from pandas.plotting import scatter_matrix

attributes = ["median_house_value", "median_income", "total_rooms", "housing_median_age"]
scatter_matrix(housing[attributes], figsize=(12, 8))

由於篇幅無法完全展示9個屬性的散點圖矩陣,下面的散點圖矩陣僅僅繪製出四個屬性的相關性,主對角線位置(從左上到右下)是每個屬性的直方圖,其他網格是都是兩個屬性之間的相關性。

五,屬性的組合

對變數屬性進行組合,通常是跟標量屬性推匯出比率屬性,比如,根據房間總數(total_rooms)和家庭總數(household)計算每個家庭的房間的數量,或者根據房間總數計算臥室的佔比,或者根據人口和家庭來計算每個家庭的人口數量:

housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]
housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]
housing["population_per_household"]=housing["population"]/housing["households"]

corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)

計算新加的屬性跟median_house_value的相關性:

median_house_value 1.000000
median_income 0.687160
rooms_per_household 0.146285
total_rooms 0.135097
housing_median_age 0.114110
households 0.064506
total_bedrooms 0.047689
population_per_household -0.021985
population -0.026920
longitude -0.047432
latitude -0.142724
bedrooms_per_room -0.259984
Name: median_house_value, dtype: float64

六,缺失值

 對於缺失值,有多種處理方式,本文只簡單介紹一下:

  • 刪除缺失的資料行
  • 刪除缺失的屬性
  • 把缺失值設定為某個常量值,通常是均值
  • 插補法,插入的值是不固定的,

七,分類屬性的編碼

 對於文字屬性,如果是標稱屬性,那麼該屬性用於對資料物件進行分類,可能只有有限多個取值,每個值代表一個類別。機器學習演算法無法直接處理文字屬性,通常把文字屬性轉換為數值來處理,這就需要把文字編碼為數值。

1,有序編碼

使用Scikit-Learn 的 OrdinalEncoder類把屬性編碼為有序的:

from sklearn.preprocessing import OrdinalEncoder

ordinal_encoder = OrdinalEncoder()
housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)

2,One-Hot編碼

獨熱(One-Hot)編碼把分類屬性的各個屬性值轉換為資料集的新屬性,在由分類屬性派生的屬性組中,對於同一個資料行,只有一個屬性是1,其他屬性都是0,使用Scikit-Learn 的OneHotEncoder編碼器可以把分類屬性轉換為獨熱向量:

from sklearn.preprocessing import OneHotEncoder

cat_encoder = OneHotEncoder()
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)

八,特徵縮放

如果輸入的數值屬性具有非常大的比例差異,往往會導致機器學習演算法的效能表現不佳。

1,最小-最大縮放(歸一化)

使用Scikit-Learn 的MinMaxScaler()實現標準化縮放

2,標準化

使用Scikit-Learn 的StandardScaler()實現標準化縮放

 

參考文件:

 

相關文章