金錢能讓人更快樂嗎?手把手教你用機器學習找到答案
一種對機器學習系統進行分類的方法是看它們如何泛化。大多數機器學習任務是要做出預測。這意味著系統需要通過給定的訓練示例,在它此前并未見過的示例上進行預測(泛化)。在訓練數據上實現良好的性能指標固然重要,但是還不夠充分。真正的目的是要在新的對象實例上表現出色。
泛化的主要方法有兩種:基于實例的學習和基于模型的學習。
1. 基于實例的學習
我們最司空見慣的學習方法就是簡單地死記硬背。如果以這種方式創建一個垃圾郵件過濾器,那么它可能只會標記那些與已被用戶標記為垃圾郵件完全相同的郵件—這雖然不是最差的解決方案,但肯定也不是最好的。
除了完全相同的,你還可以通過編程讓系統標記與已知的垃圾郵件非常相似的郵件。這里需要兩封郵件之間的相似度度量。一種(基本的)相似度度量方式是計算它們之間相同的單詞數目。如果一封新郵件與一封已知的垃圾郵件有許多單詞相同,系統就可以將其標記為垃圾郵件。
這被稱為基于實例的學習:系統用心學習這些示例,然后通過使用相似度度量來比較新實例和已經學習的實例(或它們的子集),從而泛化新實例。例如,圖1-15中的新實例會歸為三角形,因為大多數最相似的實例屬于那一類。
▲圖1-15:基于實例的學習
2. 基于模型的學習
從一組示例集中實現泛化的另一種方法是構建這些示例的模型,然后使用該模型進行預測。這稱為基于模型的學習(見圖1-16)。
▲圖1-16:基于模型的學習
舉例來說,假設你想知道金錢是否讓人感到快樂,你可以從經合組織(OECD)的網站上下載“幸福指數”的數據,再從國際貨幣基金組織(IMF)的網站上找到人均GDP的統計數據,將數據并入表格,按照人均GDP排序,你會得到如表1-1所示的摘要。
表1-1:金錢能讓人更快樂嗎?
讓我們繪制這些國家的數據(見圖1-17)。
▲圖1-17:趨勢圖
這里似乎有一個趨勢!雖然數據包含噪聲(即部分隨機),但是仍然可以看出隨著該國人均GDP的增加,生活滿意度或多或少呈線性上升的趨勢。所以你可以把生活滿意度建模成一個關于人均GDP的線性函數。這個過程叫作模型選擇。你為生活滿意度選擇了一個線性模型,該模型只有一個屬性,就是人均GDP(見公式1-1)。
公式1-1:一個簡單的線性模型
生活滿意度= θ0 + θ1×人均GDP
這個模型有兩個模型參數:θ0和θ1。通過調整這兩個參數,可以用這個模型來代表任意線性函數,如圖1-18所示。
▲圖1-18:一些可能的線性模型
在使用模型之前,需要先定義參數θ0和θ1的值。怎么才能知道什么值可以使模型表現最佳呢?要回答這個問題,需要先確定怎么衡量模型的性能表現。要么定義一個效用函數(或適應度函數)來衡量模型有多好,要么定義一個成本函數來衡量模型有多差。
對于線性回歸問題,通常的選擇是使用成本函數來衡量線性模型的預測與訓練實例之間的差距,目的在于盡量使這個差距最小化。
這正是線性回歸算法的意義所在:通過你提供的訓練樣本,找出最符合提供數據的線性模型的參數,這稱為訓練模型。在這個案例中,算法找到的最優參數值為θ0 = 4.85和θ1 = 4.91×10^(-5)。
注意:令人困惑的是,同一個詞“模型”可以指模型的一種類型(例如,線性回歸),到一個完全特定的模型架構(例如,有一個輸入和一個輸出的線性回歸),或者到最后可用于預測的訓練模型(例如,有一個輸入和一個輸出的線性回歸,使用參數θ0 = 4.85和θ1 = 4.91×10^(-5))。模型選擇包括選擇模型的類型和完全指定它的架構。訓練一個模型意味著運行一種尋找模型參數的算法,使其最適合訓練數據(希望能對新的數據做出好的預測)。
現在,(對于線性模型而言)模型基本接近訓練數據,如圖1-19所示。
▲圖1-19:最擬合訓練數據的線性模型
現在終于可以運行模型來進行預測了。例如,你想知道塞浦路斯人有多幸福,但是經合組織的數據沒有提供答案。幸好你有這個模型可以做出預測:先查查塞浦路斯的人均GDP是多少,發現是22 587美元,然后應用到模型中,發現生活滿意度大約是4.85 + 22 587×4.91×10^(-5) = 5.96。
為了激發你的興趣,示例1-1是一段加載數據的Python代碼,包括準備數據,創建一個可視化的散點圖,然后訓練線性模型并做出預測。
示例1-1:使用Scikit-Learn訓練并運行一個線性模型
- import matplotlib.pyplot as plt
- import numpy as np
- import pandas as pd
- import sklearn.linear_model
- # Load the data
- oecd_bli = pd.read_csv("oecd_bli_2015.csv", thousands=',')
- gdp_per_capita = pd.read_csv("gdp_per_capita.csv",thousands=',',delimiter='\t',
- encoding='latin1', na_values="n/a")
- # Prepare the data
- country_stats = prepare_country_stats(oecd_bli, gdp_per_capita)
- X = np.c_[country_stats["GDP per capita"]]
- y = np.c_[country_stats["Life satisfaction"]]
- # Visualize the data
- country_stats.plot(kind='scatter', x="GDP per capita", y='Life satisfaction')
- plt.show()
- # Select a linear model
- model = sklearn.linear_model.LinearRegression()
- # Train the model
- model.fit(X, y)
- # Make a prediction for Cyprus
- X_new = [[22587]] # Cyprus's GDP per capita
- print(model.predict(X_new)) # outputs [[ 5.96242338]]
如果使用基于實例的學習算法,你會發現斯洛文尼亞的人均GDP最接近塞浦路斯(20 732美元),而經合組織的數據告訴我們,斯洛文尼亞人的生活滿意度是5.7,因此你很可能會預測塞浦路斯的生活滿意度為5.7。
如果稍微拉遠一些,看看兩個與之最接近的國家——葡萄牙和西班牙的生活滿意度分別為5.1和6.5。取這三個數值的平均值,得到5.77,這也非常接近基于模型預測所得的值。這個簡單的算法被稱為k-近鄰回歸(在本例中,k = 3)。
要將前面代碼中的線性回歸模型替換為k-近鄰回歸模型非常簡單,只需要將下面這行代碼:
- import sklearn.linear_model
- model = sklearn.linear_model.LinearRegression()
替換為:
- import sklearn.neighbors
- model = sklearn.neighbors.KNeighborsRegressor(
- n_neighbors=3)
如果一切順利,你的模型將會做出很棒的預測。如果不行,則需要使用更多的屬性(例如就業率、健康、空氣污染等),獲得更多或更高質量的訓練數據,或者選擇一個更強大的模型(例如,多項式回歸模型)。
簡而言之:
- 研究數據。
- 選擇模型。
- 使用訓練數據進行訓練(即前面學習算法搜索模型參數值,從而使成本函數最小化的過程)。
- 最后,應用模型對新示例進行預測(稱為推斷),希望模型的泛化結果不錯。
以上就是一個典型的機器學習項目。