機器學習之預測房價系列:
- 機器學習之:探索資料和資料預處理
探索資料是指研究資料,發現資料的結構。資料集由資料物件構成,一個資料物件代表一個實體,實體由屬性構成,屬性是一個資料欄位,表示資料物件的一個特徵,通常,在資料分析和機器學習中,屬性、維度、特徵和變數這四個術語可以互換。
用來描述一個資料物件的一組屬性,稱作屬性向量或者特徵向量。一個屬性的型別是由該屬性的值決定的,屬性可以是標稱的、二元的、序數的和數值的。
本文使用的資料,使用以下指令碼獲得,案例是預測某個區域的房價,本文重點關注的是如何探索資料和對資料進行預處理。
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()
快速檢視資料的結構,每一行代表一個區域,共有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()實現標準化縮放
參考文件: