机器学习入门系列(2)--如何构建一个完整的机器学习项目(一)
上一篇機器學習入門系列(1)–機器學習概覽簡單介紹了機器學習的一些基本概念,包括定義、優缺點、機器學習任務的劃分等等。
接下來計劃通過幾篇文章來介紹下,一個完整的機器學習項目的實現步驟會分為幾步,最后會結合《hands-on-ml-with-sklearn-and-tf》的例子來介紹下相應代碼的實現。
這是如何構建一個完整的機器學習項目第一篇!
這里先給出一個完整的機器學習項目過程的主要步驟,如下所示:
第一篇文章會介紹下第一節內容,開始一個項目的時候,需要確定什么問題,包括選擇合適的損失函數。
1. 項目概覽
1.1 劃定問題
當我們開始一個機器學習項目的時候,需要先了解兩個問題:
通過上述兩個問題,我們就可以開始設計系統,也就是解決方案。
但首先,有些問題也需要了解清楚:
- 監督還是無監督,或者是強化學習?
- 是分類,回歸,還是其他類型問題?
- 采用批量學習還是需要線上學習。
1.2 選擇性能指標
選擇性能指標,通常對于模型,首先就是指模型的準確率,而在機器學習中,算法的準確率是需要通過減少損失來提高的,這就需要選擇一個合適的損失函數來訓練模型。
一般,從學習任務類型可以將損失函數劃分為兩大類–回歸損失和分類損失,分別對應回歸問題和分類問題。
回歸損失
均方誤差 / 平方誤差 / L2 誤差
均方誤差(MSE)度量的是預測值和真實值之間差的平方的均值,它只考慮誤差的平均大小,不考慮其方向。但經過平方后,對于偏離真實值較多的預測值會受到更嚴重的懲罰,并且 MSE 的數學特性很好,也就是特別易于求導,所以計算梯度也會變得更加容易。
MSE 的數學公式如下:
代碼實現如下:
def rmse(predictions, targets):# 真實值和預測值的誤差differences = predictions - targetsdifferences_squared = differences ** 2mean_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 - targetsabsolute_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 - targetsmean_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.0pred_value = predictions[label]for i, val in enumerate(predictions):if i == label:continuetmp = val - pred_value + 1result += 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))) / Nreturn 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上述代碼例子,源代碼地址:
https://github.com/ccc013/CodesNotes/blob/master/hands_on_ml_with_tf_and_sklearn/Loss_functions_practise.py
1.3 核實假設
核實假設其實也可以說是確定你設計的系統的輸入輸出,我們的機器學習項目是需要商用的話,肯定就不只是一個算法模型,通常還會有前端展示頁面效果,后端的服務等等,你需要和前后端的負責人進行溝通,核實接口的問題。
比如,《hands-on-ml-with-sklearn-and-tf》書中給出的例子是設計一個預測房價的系統,其輸出是房價的數值,但是如果前端需要展示的是類別,即房價是便宜、中等還是昂貴,那么我們的系統輸出的房價就沒有意義了,這時候我們要解決的就是分類問題,而不是回歸問題。
因此,當你在做一個機器學習項目的時候,你需要和有工作交接的同事保持良好的溝通,隨時進行交流,確認接口的問題。
小結
第一篇簡單介紹了開始一個機器學習項目,首先需要明確商業目標,已有的解決方案,設計的機器學習系統屬于什么類型任務,并以此為基礎,選擇合適的性能指標,即損失函數。
參考:
- 《hands-on-ml-with-sklearn-and-tf》第二節
- https://www.jiqizhixin.com/articles/091202
- https://blog.csdn.net/fendegao/article/details/79968994
- https://blog.csdn.net/xg123321123/article/details/80781611
歡迎關注我的微信公眾號–機器學習與計算機視覺,或者掃描下方的二維碼,大家一起交流,學習和進步!
往期精彩推薦
學習筆記
- 機器學習入門系列(1)–機器學習概覽
- [GAN學習系列] 初識GAN
- [GAN學習系列2] GAN的起源
- [GAN學習系列3]采用深度學習和 TensorFlow 實現圖片修復(上)
數學學習筆記
- 程序員的數學筆記1–進制轉換
- 程序員的數學筆記2–余數
- 程序員的數學筆記3–迭代法
Github項目 & 資源教程推薦
- [Github 項目推薦] 一個更好閱讀和查找論文的網站
- [資源分享] TensorFlow 官方中文版教程來了
- 必讀的AI和深度學習博客
- [教程]一份簡單易懂的 TensorFlow 教程
- [資源]推薦一些Python書籍和教程,入門和進階的都有!
總結
以上是生活随笔為你收集整理的机器学习入门系列(2)--如何构建一个完整的机器学习项目(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL这三道常见的面试题,你有被问过
- 下一篇: 小程序