--------點選螢幕右側或者螢幕底部“+訂閱”,關注我,随時分享機器智能最新行業動态及技術幹貨----------

一 是什麼是機器學習,為什麼我們要機器學習
什麼是機器學習
先看兩個例子:
我們是如何習得“貓”這個動物的?
想象一下一個從來沒有見過貓的人(比如一個小嬰兒),他的詞彙裡面甚至沒有貓這個詞。有一天他看到了一個毛茸茸的動物:
這時候他不知道這是什麼東西,你告訴他這是 ”貓“。這時候可能小嬰兒記住了,這個就是貓。
又過了段時間他又看見了這樣一個動物:
你又告訴他這也是貓。他記住了這也是貓。
後來又過了段時間,他又看見了一個動物:
這時他直接告訴你他看見了一隻“貓”。
以上就是我們認識世界的基本方法,模式識别:人們通過大量的經驗,得到結論,進而判斷它就是貓。
在這個過程中我們通過接觸樣本(各種貓)學習到了貓的特征(人們通過閱讀進行學習,觀察它會叫、兩隻耳朵、四條腿、一條尾巴、有胡須,得到結論),進而知道什麼是貓。
我們如何知道 npm 包判斷一個 npm 包是測試 npm 包呢?
我貼一段小夥伴的代碼:
SELECT * FROM
tianma.module_xx
WHERE
pt = TO_CHAR(DATEADD(GETDATE(), - 1, ‘dd’), ‘yyyymmdd’)
AND name NOT LIKE ‘%test%’
AND name NOT LIKE ‘%demo%’
AND name NOT LIKE ‘%測試%’
AND keywords NOT LIKE ‘%test%’
AND keywords NOT LIKE ‘%測試%’
AND keywords NOT LIKE ‘%demo%’
很明顯我們判斷的方式是這個子產品的名稱和關鍵字中是否包含:test、demo、測試這三個字元。如果有那麼我們就認為他是測試子產品。我們把規則告訴了資料庫,然後資料庫就幫我們篩選了非測試子產品。
識别是否是貓或者識别一個子產品是否是測試子產品本質上是一樣的,都是在找特征:
- 貓的特征:會叫、兩隻耳朵、四條腿、一條尾巴、有胡須
- 測試子產品的特征:test、demo、測試
再進一步将特征程式化表述:
- 貓的特征: 叫、true、耳朵:2、腿:4、尾巴:1、胡須:10
- 測試子產品的特征:test:count>0、demo:count >0、測試:count > 0
有了這些特征無論是人還是機器都能正确的識别貓或者測試子產品了。
簡單的了解機器學習就是通過特征和特征的權重來實作資料的分類。(此處為了便于了解,更準确說法請參考:AiLearning/1.機器學習基礎.md at master · apachecn/AiLearning · GitHub)
為什麼要用機器識别呢?
原因是當某種分類任務的特征數量巨大之後我們就很難用 if else 的方法去做簡單的分類了。比如我們常見的商品推薦算法,要确定某個商品是否适合推薦給某人可能的特征數量會達到上百上千個。
二 如何訓練機器,并獲得模型?
準備資料
資料的準備在整個機器學習的任務中時間占比可能超過 75%,是最重要的一部分,也是最困難的一部分。主要是:
- 采集基本的資料
- 清理異常值
- 挑選可能的特征:特征工程
- 資料打标
準備算法
讓你的資料進行拟合的一個函數:y=f(x)
比如線性函數也就是一進制一次函數:y=ax+b
評估算法
如何确定找到的 a、b 值是否合适,那就需要一個評估函數。
評估函數描述訓練得到的參數和實際的值之前的差距(損失值)。比如下圖:
右邊的藍色線條更加貼近真實的資料點。
最常見的損失評估函數就是均方誤差函數了。通過計算預測的值和真實值的差的平方和來判斷預測值的優劣程度。
如上圖:樣本黃色的小圓圈坐标為:
[
[x1, y1],
[x2, y2],
[x3, y3],
[x4, y4],
[x5, y5],
[x6, y6]
],
藍色的線預測的坐标為:
[x1, y’1],
[x2, y‘2],
[x3, y’3],
[x4, y‘4],
[x5, y’5],
[x6, y‘6]
],
那麼損失值為:
const cost = ((y’1-y1)^2 + (y’2-y2)^2 + (y’3-y3)^2 + (y’4-y4)^2 + (y’5-y5)^2 + (y’6-y6)^2 ) / 6
訓練算法
如何找到合适的 a、b 值:抛物線的最低端
以上述的線性函數為例,訓練算法實際上就是在尋找合适的 a,b 值。如果我們在茫茫的數字海洋中随機尋找 a,b 的值那應該是永遠找不到的了。這時候我們就需要用到梯度下降算法來尋找 a,b 值了。
再明确一下目标,将上述的損失值計算公式替換為:y=ax+b
// 函數 2
const cost = (((a*x1+b)-y1)^2 + ((a*x2+b)-y2)^2 + ((a*x3+b)-y3)^2 + ((a*x4+b)-y4)^2 + ((a*x5+b)-y5)^2 + ((a*x6+b)-y6)^2 )/ 6
标是找到一組 a、b 的值使得 cost 最小。有了這個目标就好辦多了。
不知道你還記不記得國中的抛物線函數,也就是一進制二次方程:y = ax^2+bx+c
而我們上述的 cost 函數雖然看起來很長,但是正好也是一個二次函數。它的圖大概是這樣的:
隻要我們找到最低點的 a,b 值就完成我們的目标了。
怎麼知道到達抛物線的低端:抛物線的低端斜率為 0
假設我們随機初始化一個 a 值為 1, 這時我們的點就在抛物線的左上方位置,距離最低點(cost 最小)的位置還距離很遠呢。
看圖可知我們隻要增加 a 的值就可以靠近最低點了。那看圖機器可不會,這時候我們要祭出本篇文章中最複雜的數學知識了:導數。在這個點上的切線斜率值即為這個抛物線的導數,如上圖最低點(斜率為 0 處)。
通過這個導數可以計算出這個位置的切線(紅色的斜線)斜率。如果這個斜線的斜率為負數就意味着 a 太小了,需要增加才能更靠近底部。反之如果斜率為正意味着過了最低點了,需要減少才能更靠近底部。
如何求 cost 函數的導數呢?
不展開了,直接看代碼吧。關鍵字:偏導數、複合求導
// 函數 3
// a參數的偏導數
const costDaoA = (((ax1+b)-y1)2x1 + ((ax2+b)-y2)2x1 + ((ax3+b)-y3)2x1 + ((ax4+b)-y4)2x1 + ((ax5+b)-y5)2x1 + ((ax6+b)-y6)2x1 )/ 6
// b參數的偏導數
const costDaoB = (((ax1+b)-y1)2 + ((ax2+b)-y2)2 + ((ax3+b)-y3)2 + ((ax4+b)-y4)2 + ((ax5+b)-y5)2 + ((ax6+b)-y6)2 )/ 6
也就是隻要将 a,b 值帶入 costDaoA 函數就可以得到一個斜率,這個斜率指導參數 a 該如何調整以便更靠近底部。
同理 costDaoB 指導參數 b 改如何靠近底部。
循環 500 次吧
就這樣循環 500 次,基本上就能非常靠近底部了,進而獲得合适的 a,b 值。
獲得模型
當你獲得了 a,b 值之後,那麼我們就獲得了 y=ax+b 這樣一個模型,這個模型就可以幫助我們做預測了。
三 實踐一下先從簡單的開始:線性回歸
什麼是線性回歸
人們早就知曉 ,相比涼爽的天氣,蟋蟀在較為炎熱的天氣裡鳴叫更為頻繁。我們記錄了氣溫和每分鐘叫聲的一個表格,并且在 Excel 中繪制了下圖(案例來自 google tf 的官方教程):
是不是很清晰,這些小紅點幾乎排在了一條直線上:
那麼我們就認為這些資料的分布是線性的,繪制的這條直線的過程就是線性回歸。有了這條曲線我們就能準确的預測任何問題下鳴叫的次數了。
用浏覽器做一個線性回歸示範
位址:測試梯度下降
https://jshare.com.cn/feeqi/CtGy0a/share?spm=ata.13261165.0.0.6d8c3ebfIOhvAq為了可視化采用了 highcharts 做資料可視化,同時為了省下 75% 的時間直接用了 highcharts 的預設資料點:
https://www.highcharts.com.cn/demo/highcharts/scatter當訓練完成後繪制了一條藍色的線疊加在了圖上,同時增加了每次訓練的 a,b 值的損失率曲線。
代碼介紹
/**
* 代價函數 均方差計算
*/
function cost(a, b) {
let sum = data.reduce((pre, current) = >{
return pre + ((a + current[0] * b) - current[1]) * ((a + current[0] * b) - current[1]);
},
0);
return sum / 2 / data.length;
}
/**
* 計算梯度
* @param a
* @param b
*/
function gradientA(a, b) {
let sum = data.reduce((pre, current) = >{
return pre + ((a + current[0] * b) - current[1]) * (a + current[0] * b);
},
0);
return sum / data.length;
}
function gradientB(a, b) {
let sum = data.reduce((pre, current) = >{
return pre + ((a + current[0] * b) - current[1]);
},
0);
return sum / data.length;}
// 訓練次數
let batch = 200;
// 每次的靠近底部的速度,也就是學習速率。過高會導緻在底部彈跳遲遲不能到到底部,過低會導緻學習效率降低。
let alpha = 0.001;
let args = [0, 0]; // 初始化 a b 值
function step()
{
let costNumber = (cost(args[0], args[1]));
console.log(‘cost’, costNumber);
chartLoss.series[0].addPoint(costNumber, true, false, false);
args[0] -= alpha * gradientA(args[0], args[1]);
args[1] -= alpha * gradientB(args[0], args[1]);
if ((—batch > 0)) {
window.requestAnimationFrame(() = >{
step()
});
} else {
drawLine(args[0], args[1]);
}
}
step();
四 接下來要做的
當特征更多的時候,我們需要更多的計算、更長時間的訓練來獲得訓練模型。
上述描述都比較簡單,但是相信機器學習對你已經不再神秘,那麼可以參考更專業的入門文章。
參考
[1] GitHub - apachecn/AiLearning: AiLearning: 機器學習 - MachineLearning - ML、深度學習 - DeepLearning - DL、自然語言處理 NLP
[2]
https://developers.google.com/machine-learning/crash-course/descending-into-ml/video-lecture?hl=zh-cn [3] 從 0 開始機器學習 - 手把手用 Python 實作梯度下降法!- 掘金
原文連結:
https://mp.weixin.qq.com/s/7yP4EINI0KZZBUGBKbO08Q