1. 程式人生 > >機器學習實戰筆記(一)- 使用SciKit-Learn做回歸分析

機器學習實戰筆記(一)- 使用SciKit-Learn做回歸分析

err 皮爾遜 練習 using flow 相關 一個數 ocean 針對

一、簡介

這次學習的書籍主要是Hands-on Machine Learning with Scikit-Learn and TensorFlow(豆瓣:https://book.douban.com/subject/26840215/), 這本偏向實戰,閱讀前需要對機器學習和python有一定的認知。

二、安裝Jupyter

本書代碼主要都是在Jupyter上運行,安裝方法也很簡單,直接在shell上輸入pip3 install --upgrade juyter安裝(需事先安裝pip),再輸入jupyter notebook,就會在瀏覽器自動打開。

三、 Scikit-Learn 和 TensorFlow的比較

兩個都是機器學習很好用的工具,我的感覺是sklearn在數據處理,數據展示,數據預處理真的很強很好用,比較適合像我這基礎應用的使用者,目前市面上大部分的人工智能產品都可以透過sklearn來完成。tf強項應該是在深度學習,對那些準確率要求特別高的應用來說(例如人臉識別、語音識別),tf應該會比較適合。

四、導入數據

首先我們的目標是要利用房地產的一些數據來預測某一區的房價中位數,數據來源是加州的房地產數據,其中包含了經緯度、房齡、房間總數、臥室數量、人口等。首先在jupyter裏面新建一個項目(右上角有個‘new’,按下去就可以創建),然後再導入數據,數據在一個housing.tgz裏的housing.cvs裏,屬於excel的格式,可以利用下面的代碼導入。

import os
import tarfile
from six.moves import urllib

DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml/master/"
HOUSING_PATH = "datasets/housing"
HOUSING_URL = DOWNLOAD_ROOT + HOUSING_PATH + "/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() fetch_housing_data()

可以在jupyter裏面用head()查看前五項數據

技術分享圖片

可以看到數據已經成功導入,再使用info()可以查看總數據量

技術分享圖片

五、數據清洗

上面可以看到總共有20640筆數據,數據量不大,很適合用來練習,但是可以看到第五項數據total_bedrooms的數據只有20433筆,比其他的少了207筆,這些少的數據會影響到時候的計算,需要先做處理,針對缺失數據,主要有三種修復方式:1、將缺失數據的行刪了,也就是我們會犧牲207筆數據;2、將列給刪了,也就是我們會少了total_bedroom這個數據;3、補上數據,通常是補上中位數或是平均數,讓影響降到最低。這三種方法sklearn都有支持,這邊我們選擇的是用第三種方法來修補,sklearn裏面可以使用imputer這個功能來實現。

from sklearn.preprocessing import Imputer
imputer = Imputer(strategy = "median")

另外我們可以看其中一個數據項ocean_proximity,裏面有下面四個值

技術分享圖片

由於他們都是文字,我們必須將他們轉換成數字才可以進行計算,假如分別給他們一個數字, 這個時候會有個問題,因為文字之間是沒關聯的,但是一旦賦予他們一個數字,他們之間就會產生了關聯,例如1H OCEAN跟NEAR OCEAN的平均不等於ISLAND, 但是1跟5的平均是3, 所以需要轉換成陣列的形式,這樣才可以保持這種獨立性,sklearn有個很好用的指令LabelBinarizer可以直接幫我們實現這個需求,代碼如下圖

技術分享圖片

可以看到第一行到第三行的[0, 0, 0, 1, 0]代表了NEAR BAY。

六、特征縮放

特征縮放也是數據預處理的一環,目的是怕有些波動範圍大的參數影響力會遠大於那些波動小的,比如總房間數分布範圍是6-39320,但收入的中位數只有0-15。處理的方法有兩種,一個是線性函數歸一化,就是將所有的參數範圍都縮小到0-1。另外一個是標準化,就是減去平均值後除以方差。

七、創建測試集

在機器學習上,為了驗證學習的結果,一般都會講數據拆分成訓練集和測試集,訓練集用來訓練機器,而測試集用來測試訓練的結果,拆分的方法有很多種,包含了隨機拆分。但是隨機拆分有個問題,就拆分出來的訓練數據不一定可以代表全部的數據,測試數據也一樣,比如我訓練數據都是一些中產或是富有的區域的數據,然後測試都是貧民區的數據,執行出來的效果當然會不好,所以需要用分層采樣的方式進行數據拆分,也就是要對每種區域都均衡的采集。分層采集第一部要先決定對哪個數據進行分層,我們這邊選擇的是房價進行分層,因為房價是我們這次分析的重要因素下面為分層取樣的代碼。

from sklearn.model_selection import StratifiedShuffleSplit
housing["income_cat"] = np.ceil(housing["median_income"]/1.5)
housing["income_cat"].where(housing["income_cat"]<5,5.0, inplace=True)

split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)

for train_index, test_index in split.split(housing, housing["income_cat"]):
    strat_train_set = housing.loc[train_index]
    strat_test_set = housing.loc[test_index]

八、數據可視化

數據可視化也是jupyter非常方便的功能之一,主要是透過matplotlib這個庫來實現的。數據可視化的好處是可以讓我們對整個數據集有個比較直觀的了解,像是可以利用將左邊打印出來可以看到整個房地產數據來源的分布位置就是加州的形狀。

技術分享圖片

下面我們將房價的因素導入可以看到房價高的地區集中在南加和北加兩個區域。

技術分享圖片

九、查找關聯

由於我們要預測房價,需要先找出一些跟房價相關的數據,sklearn提供了一個非常方便的方式corr(),可以用皮爾遜公式快速的計算各參數之間的相關性,現在我們來看看跟房價中位數相關的參數是什麽,第一個就是收入,有0.68,接下來是總房間數,但是不高,只有0.135。

技術分享圖片

除了上面的數據外,我們可以透過將原本兩個數據進行組合,生成第三種數據,可能原本兩個關聯性不高,可是新生成的數據關聯性就很高。

十、訓練機器

接著就是要訓練機器,sklearn裏面有LinearRegression()這個函數,可以自動的做回歸分析,我們只需要準備兩個數,一個是X軸(輸入),一個是Y軸(實際結果),下面為代碼

from sklearn.linear_model import LinearRegression

lin_reg = LinearRegression()
lin_reg.fit(housing_prepared, housing_labels)

接著可以看看訓練的結果如何,我們可以觀察預測值與實際值就可以了解機器的學習成果

技術分享圖片

可以看到除了第二個,其他都還算是有點接近,畢竟訓練的量小,無法要求準確度要很高,接著,我們要用比較客觀的數字來代表整體的學習情況,sklearn提供了一個mean_sqaured_error的函數,是用來計算預測值與實際值的平均“距離”,以此代表誤差

技術分享圖片

可以看到誤差大約是68628,這誤差算是非常大了,以下是誤差產生的原因

1、數據訓練量不足:對於這種多維度的回歸分析,兩萬多筆的數據確實是很少,也是這次準確率低的主要原因

2、數據太過分散:由於數據是遍布整個加州,假如數據是集中在某個區域,比如說洛杉磯,預測出的結果相對會準一點

3、不相關特征:從相關分析中可以發現,除了平均收入外,其他的參數跟房價的相關度都過低,導致這些參數是沒有幫助的

4、沒有代表性數據:跟上述類似,影響房價的其中一個因素是社區環境,但是光從經緯度無法判定社區的好壞

機器學習實戰筆記(一)- 使用SciKit-Learn做回歸分析