機器學習入門系列(2)--如何構建一個完整的機器學習項目(一)

上一篇機器學習入門系列(1)--機器學習概覽簡單介紹了機器學習的一些基本概念,包括定義、優缺點、機器學習任務的劃分等等。前端

接下來計劃經過幾篇文章來介紹下,一個完整的機器學習項目的實現步驟會分爲幾步,最後會結合《hands-on-ml-with-sklearn-and-tf》的例子來介紹下相應代碼的實現。python

這是如何構建一個完整的機器學習項目第一篇!git

這裏先給出一個完整的機器學習項目過程的主要步驟,以下所示:程序員

  1. 項目概述。
  2. 獲取數據。
  3. 發現並可視化數據,發現規律
  4. 爲機器學習算法準備數據。
  5. 選擇模型,進行訓練。
  6. 微調模型。
  7. 給出解決方案。
  8. 部署、監控、維護系統

第一篇文章會介紹下第一節內容,開始一個項目的時候,須要肯定什麼問題,包括選擇合適的損失函數。github


1. 項目概覽

1.1 劃定問題

當咱們開始一個機器學習項目的時候,須要先了解兩個問題:算法

  1. **商業目標是什麼?**公司但願利用算法或者模型收穫什麼,這決定須要採用什麼算法和評估的性能指標?
  2. 當前的解決方案效果如何?

經過上述兩個問題,咱們就能夠開始設計系統,也就是解決方案。shell

但首先,有些問題也須要了解清楚:後端

  • 監督仍是無監督,或者是強化學習?
  • 是分類,迴歸,仍是其餘類型問題?
  • 採用批量學習仍是須要線上學習。

1.2 選擇性能指標

選擇性能指標,一般對於模型,首先就是指模型的準確率,而在機器學習中,算法的準確率是須要經過減小損失來提升的,這就須要選擇一個合適的損失函數來訓練模型。安全

通常,從學習任務類型能夠將損失函數劃分爲兩大類--迴歸損失和分類損失,分別對應迴歸問題和分類問題。bash

迴歸損失
均方偏差 / 平方偏差 / L2 偏差

均方偏差(MSE)度量的是預測值和真實值之間差的平方的均值,它只考慮偏差的平均大小,不考慮其方向。但通過平方後,對於偏離真實值較多的預測值會受到更嚴重的懲罰,而且 MSE 的數學特性很好,也就是特別易於求導,因此計算梯度也會變得更加容易

MSE 的數學公式以下:

代碼實現以下:

def rmse(predictions, targets):
    # 真實值和預測值的偏差
    differences = predictions - targets
    differences_squared = differences ** 2
    mean_of_differences_squared = differences_squared.mean()
    # 取平方根
    rmse_val = np.sqrt(mean_of_differences_squared)
    return rmse_val
複製代碼

固然上述代碼實現的是均方根偏差(RMSE),一個簡單的測試例子以下:

y_hat = np.array([0.000, 0.166, 0.333])
y_true = np.array([0.000, 0.254, 0.998])

print("d is: " + str(["%.8f" % elem for elem in y_hat]))
print("p is: " + str(["%.8f" % elem for elem in y_true]))
rmse_val = rmse(y_hat, y_true)
print("rms error is: " + str(rmse_val))
複製代碼

輸出結果爲:

d is: ['0.00000000', '0.16600000', '0.33300000']
p is: ['0.00000000', '0.25400000', '0.99800000']
rms error is: 0.387284994115
複製代碼
平方絕對偏差 / L1 偏差

平均絕對偏差(MAE)度量的是預測值和實際觀測值之間絕對差之和的平均值。和 MSE 同樣,這種度量方法也是在不考慮方向的狀況下衡量偏差大小。但和 MSE 的不一樣之處在於,MAE 須要像線性規劃這樣更復雜的工具來計算梯度。此外,MAE 對異常值更加穩健,由於它不使用平方。

數學公式以下:

MAE 的代碼實現也不難,以下所示:

def mae(predictions, targets):
    differences = predictions - targets
    absolute_differences = np.absolute(differences)
    mean_absolute_differences = absolute_differences.mean()
    return mean_absolute_differences
複製代碼

測試樣例能夠直接用剛纔的 MSE 的測試代碼,輸出結果以下:

d is: ['0.00000000', '0.16600000', '0.33300000']
p is: ['0.00000000', '0.25400000', '0.99800000']
mae error is: 0.251
複製代碼
平均誤差偏差(mean bias error)

這個損失函數應用得比較少,在機器學習領域太不常見了,我也是第一次看到這個損失函數。它和 MAE 很類似,惟一區別就是它沒有用絕對值。所以,須要注意的是,正負偏差能夠互相抵消。儘管在實際應用中沒那麼準確,但它能夠肯定模型是存在正誤差仍是負誤差。

數學公式以下:

代碼的實現,其實只須要在 MAE 的基礎上刪除加入絕對值的代碼,以下所示:

def mbe(predictions, targets):
    differences = predictions - targets
    mean_absolute_differences = differences.mean()
    return mean_absolute_differences
複製代碼

仍是利用剛剛的測試樣例,結果以下:

d is: ['0.00000000', '0.16600000', '0.33300000']
p is: ['0.00000000', '0.25400000', '0.99800000']
mbe error is: -0.251
複製代碼

能夠看到咱們給的簡單測試樣例,存在一個負誤差。

分類偏差
Hinge Loss / 多分類 SVM 偏差

hinge loss 經常使用於最大間隔分類(maximum-margin classification),它是在必定的安全間隔內(一般是 1),正確類別的分數應高於全部錯誤類別的分數之和。最經常使用的就是支持向量機(SVM)。儘管不可微,但它是一個凸函數,能夠採用機器學習領域中經常使用的凸優化器。

其數學公式以下:

公式中 sj 表示的是預測值,而 s_yi 是真實值,也能夠說是正確預測的數值,而 1 表示的就是間隔 margin,這裏咱們但願經過真實值和預測值之間的差來表示兩種預測結果之間的類似關係,而 margin 是人爲設置的一個安全係數,咱們是但願正確分類的得分要高於錯誤預測的得分,而且是高於一個 margin 的數值,也就是s_yi越高越好,s_j 越低越好。這樣計算獲得的 Loss 會趨向於 0.

用一個簡單的例子說明,假設如今有以下三個訓練樣本,咱們須要預測三個類別,下面表格中的數值就是通過算法獲得的每一個類別的數值:

每一列就每張圖片每一個類別的數值,咱們也能夠知道每一列的真實值分別是狗、貓、馬。簡單的代碼實現以下:

def hinge_loss(predictions, label):
    ''' hinge_loss = max(0, s_j - s_yi +1) :param predictions: :param label: :return: '''
    result = 0.0
    pred_value = predictions[label]
    for i, val in enumerate(predictions):
        if i == label:
            continue
        tmp = val - pred_value + 1
        result += max(0, tmp)
    return result
複製代碼

測試例子以下:

image1 = np.array([-0.39, 1.49, 4.21])
image2 = np.array([-4.61, 3.28, 1.46])
image3 = np.array([1.03, -2.37, -2.27])
result1 = hinge_loss(image1, 0)
result2 = hinge_loss(image2, 1)
result3 = hinge_loss(image3, 2)
print('image1,hinge loss={}'.format(result1))
print('image2,hinge loss={}'.format(result2))
print('image3,hinge loss={}'.format(result3))

# 輸出結果
# image1,hinge loss=8.48
# image2,hinge loss=0.0
# image3,hinge loss=5.199999999999999

複製代碼

這個計算過程更加形象的說明:

## 1st training example
max(0, (1.49) - (-0.39) + 1) + max(0, (4.21) - (-0.39) + 1)
max(0, 2.88) + max(0, 5.6)
2.88 + 5.6
8.48 (High loss as very wrong prediction)
## 2nd training example
max(0, (-4.61) - (3.28)+ 1) + max(0, (1.46) - (3.28)+ 1)
max(0, -6.89) + max(0, -0.82)
0 + 0
0 (Zero loss as correct prediction)
## 3rd training example
max(0, (1.03) - (-2.27)+ 1) + max(0, (-2.37) - (-2.27)+ 1)
max(0, 4.3) + max(0, 0.9)
4.3 + 0.9
5.2 (High loss as very wrong prediction)
複製代碼

經過計算,hinge loss 數值越高,就表明預測越不許確。

交叉熵損失 / 負對數似然

交叉熵損失(cross entroy loss)是分類算法最經常使用的損失函數。

數學公式:

根據公式,若是實際標籤y_i是 1, 那麼公式只有前半部分;若是是 0, 則只有後半部分。簡單說,交叉熵是將對真實類別預測的機率的對數相乘,而且,它會重重懲罰那些置信度很高但預測錯誤的數值。

代碼實現以下:

def cross_entropy(predictions, targets, epsilon=1e-10):
    predictions = np.clip(predictions, epsilon, 1. - epsilon)
    N = predictions.shape[0]
    ce_loss = -np.sum(np.sum(targets * np.log(predictions + 1e-5))) / N
    return ce_loss
複製代碼

測試樣例以下:

predictions = np.array([[0.25, 0.25, 0.25, 0.25],
                            [0.01, 0.01, 0.01, 0.96]])
targets = np.array([[0, 0, 0, 1],
                    [0, 0, 0, 1]])
cross_entropy_loss = cross_entropy(predictions, targets)
print("Cross entropy loss is: " + str(cross_entropy_loss))

# 輸出結果
# Cross entropy loss is: 0.713532969914
複製代碼

上述代碼例子,源代碼地址:

github.com/ccc013/Code…

1.3 覈實假設

覈實假設其實也能夠說是肯定你設計的系統的輸入輸出,咱們的機器學習項目是須要商用的話,確定就不僅是一個算法模型,一般還會有前端展現頁面效果,後端的服務等等,你須要和先後端的負責人進行溝通,覈實接口的問題。

好比,《hands-on-ml-with-sklearn-and-tf》書中給出的例子是設計一個預測房價的系統,其輸出是房價的數值,可是若是前端須要展現的是類別,即房價是便宜、中等仍是昂貴,那麼咱們的系統輸出的房價就沒有意義了,這時候咱們要解決的就是分類問題,而不是迴歸問題。

所以,當你在作一個機器學習項目的時候,你須要和有工做交接的同事保持良好的溝通,隨時進行交流,確認接口的問題。


小結

第一篇簡單介紹了開始一個機器學習項目,首先須要明確商業目標,已有的解決方案,設計的機器學習系統屬於什麼類型任務,並以此爲基礎,選擇合適的性能指標,即損失函數。


參考:


歡迎關注個人微信公衆號--機器學習與計算機視覺,或者掃描下方的二維碼,你們一塊兒交流,學習和進步!

往期精彩推薦

學習筆記
數學學習筆記
Github項目 & 資源教程推薦
相關文章
相關標籤/搜索