找工作時(it行業),除了常見的軟體開發以外,機器學習崗位也可以當作是一個選擇,不少計算機方向的研究所學生都會接觸這個,如果你的研究方向是機器學習/資料挖掘之類,且又對其非常感興趣的話,可以考慮考慮該崗位,畢竟在機器智能沒達到人類水準之前,機器學習可以作為一種重要手段,而随着科技的不斷發展,相信這方面的人才需求也會越來越大。
縱觀it行業的招聘崗位,機器學習之類的崗位還是挺少的,國内大點的公司裡百度,阿裡,騰訊,網易,搜狐,華為(華為的崗位基本都是随機配置設定,機器學習等崗位基本面向的是博士)等會有相關職位,另外一些國内的中小型企業和外企也會招一小部分。當然了,其中大部分還是百度北京要人最多,上百人。阿裡的算法崗位很大一部分也是搞機器學習相關的。
下面是本人在找機器學習崗位工作時,總結的常見機器學習算法(主要是一些正常分類器)大概流程和主要思想,希望對大家找機器學習崗位時有點幫助。實際上在面試過程中,懂這些算法的基本思想和大概流程是遠遠不夠的,那些面試官往往問的都是一些公司内部業務中的課題,往往要求你不僅要懂得這些算法的理論過程,而且要非常熟悉怎樣使用它,什麼場合用它,算法的優缺點,以及調參經驗等等。說白了,就是既要會點理論,也要會點應用,既要有點深度,也要有點廣度,否則運氣不好的話很容易就被刷掉,因為每個面試官愛好不同。
樸素貝葉斯:
有以下幾個地方需要注意:
1. 如果給出的特征向量長度可能不同,這是需要歸一化為通長度的向量(這裡以文本分類為例),比如說是句子單詞的話,則長度為整個詞彙量的長度,對應位置是該單詞出現的次數。
2. 計算公式如下:
其中一項條件機率可以通過樸素貝葉斯條件獨立展開。要注意一點就是
的計算方法,而由樸素貝葉斯的前提假設可知,
=
,是以一般有兩種,一種是在類别為ci的那些樣本集中,找到wj出現次數的總和,然後除以該樣本的總和;第二種方法是類别為ci的那些樣本集中,找到wj出現次數的總和,然後除以該樣本中所有特征出現次數的總和。
3. 如果
中的某一項為0,則其聯合機率的乘積也可能為0,即2中公式的分子為0,為了避免這種現象出現,一般情況下會将這一項初始化為1,當然為了保證機率相等,分母應對應初始化為2(這裡因為是2類,是以加2,如果是k類就需要加k,術語上叫做laplace光滑,
分母加k的原因是使之滿足全機率公式)。
樸素貝葉斯的優點:
對小規模的資料表現很好,适合多分類任務,适合增量式訓練。
缺點:
對輸入資料的表達形式很敏感。
決策樹:
決策樹中很重要的一點就是選擇一個屬性進行分枝,是以要注意一下資訊增益的計算公式,并深入了解它。
資訊熵的計算公式如下:
其中的n代表有n個分類類别(比如假設是2類問題,那麼n=2)。分别計算這2類樣本在總樣本中出現的機率p1和p2,這樣就可以計算出未選中屬性分枝前的資訊熵。
現在選中一個屬性xi用來進行分枝,此時分枝規則是:如果xi=vx的話,将樣本分到樹的一個分支;如果不相等則進入另一個分支。很顯然,分支中的樣本很有可能包括2個類别,分别計算這2個分支的熵h1和h2,計算出分枝後的總資訊熵h’=p1*h1+p2*h2.,則此時的資訊增益Δh=h-h’。以資訊增益為原則,把所有的屬性都測試一邊,選擇一個使增益最大的屬性作為本次分枝屬性。
決策樹的優點:
計算量簡單,可解釋性強,比較适合處理有缺失屬性值的樣本,能夠處理不相關的特征;
容易過拟合(後續出現了随機森林,減小了過拟合現象);
logistic回歸:
logistic是用來分類的,是一種線性分類器,需要注意的地方有:
1. logistic函數表達式為:
其導數形式為:
2. logsitc回歸方法主要是用最大似然估計來學習的,是以單個樣本的後驗機率為:
到整個樣本的後驗機率:
其中:
通過對數進一步化簡為:
3. 其實它的loss function為-l(θ),是以我們需使loss function最小,可采用梯度下降法得到。梯度下降法公式為:
logistic回歸優點:
1、實作簡單;
2、分類時計算量非常小,速度很快,存儲資源低;
1、容易欠拟合,一般準确度不太高
2、隻能處理兩分類問題(在此基礎上衍生出來的softmax可以用于多分類),且必須線性可分;
線性回歸:
線性回歸才是真正用于回歸的,而不像logistic回歸是用于分類,其基本思想是用梯度下降法對最小二乘法形式的誤差函數進行優化,當然也可以用normal equation直接求得參數的解,結果為:
而在lwlr(局部權重線性回歸)中,參數的計算表達式為:
因為此時優化的是:
由此可見lwlr與lr不同,lwlr是一個非參數模型,因為每次進行回歸計算都要周遊訓練樣本至少一次。
線性回歸優點:
實作簡單,計算簡單;
不能拟合非線性資料;
knn算法:
knn即最近鄰算法,其主要過程為:
1. 計算訓練樣本和測試樣本中每個樣本點的距離(常見的距離度量有歐式距離,馬氏距離等);
2. 對上面所有的距離值進行排序;
3. 選前k個最小距離的樣本;
4. 根據這k個樣本的标簽進行投票,得到最後的分類類别;
如何選擇一個最佳的k值,這取決于資料。一般情況下,在分類時較大的k值能夠減小噪聲的影響。但會使類别之間的界限變得模糊。一個較好的k值可通過各種啟發式技術來擷取,比如,交叉驗證。另外噪聲和非相關性特征向量的存在會使k近鄰算法的準确性減小。
近鄰算法具有較強的一緻性結果。随着資料趨于無限,算法保證錯誤率不會超過貝葉斯算法錯誤率的兩倍。對于一些好的k值,k近鄰保證錯誤率不會超過貝葉斯理論誤差率。
注:馬氏距離一定要先給出樣本集的統計性質,比如均值向量,協方差矩陣等。關于馬氏距離的介紹如下:
knn算法的優點:
1. 思想簡單,理論成熟,既可以用來做分類也可以用來做回歸;
2. 可用于非線性分類;
3. 訓練時間複雜度為o(n);
4. 準确度高,對資料沒有假設,對outlier不敏感;
1. 計算量大;
2. 樣本不平衡問題(即有些類别的樣本數量很多,而其它樣本的數量很少);
3. 需要大量的記憶體;
svm:
要學會如何使用libsvm以及一些參數的調節經驗,另外需要理清楚svm算法的一些思路:
1. svm中的最優分類面是對所有樣本的幾何裕量最大(為什麼要選擇最大間隔分類器,請從數學角度上說明?網易深度學習崗位面試過程中有被問到。答案就是幾何間隔與樣本的誤分次數間存在關系:
,其中的分母就是樣本到分類間隔距離,分子中的r是所有樣本中的最長向量值),即:
經過一系列推導可得為優化下面原始目标:
2. 下面來看看拉格朗日理論:
可以将1中的優化目标轉換為拉格朗日的形式(通過各種對偶優化,kkd條件),最後目标函數為:
我們隻需要最小化上述目标函數,其中的α為原始優化問題中的不等式限制拉格朗日系數。
3. 對2中最後的式子分别w和b求導可得:
由上面第1式子可以知道,如果我們優化出了α,則直接可以求出w了,即模型的參數搞定。而上面第2個式子可以作為後續優化的一個限制條件。
4. 對2中最後一個目标函數用對偶優化理論可以轉換為優化下面的目标函數:
而這個函數可以用常用的優化方法求得α,進而求得w和b。
5. 按照道理,svm簡單理論應該到此結束。不過還是要補充一點,即在預測時有:
那個尖括号我們可以用核函數代替,這也是svm經常和核函數扯在一起的原因。
6. 最後是關于松弛變量的引入,是以原始的目标優化公式為:
此時對應的對偶優化公式為:
與前面的相比隻是α多了個上界。
svm算法優點:
可用于線性/非線性分類,也可以用于回歸;
低泛化誤差;
容易解釋;
計算複雜度較低;
對參數和核函數的選擇比較敏感;
原始的svm隻比較擅長處理二分類問題;
boosting:
主要以adaboost為例,首先來看看adaboost的流程圖,如下:
從圖中可以看到,在訓練過程中我們需要訓練出多個弱分類器(圖中為3個),每個弱分類器是由不同權重的樣本(圖中為5個訓練樣本)訓練得到(其中第一個弱分類器對應輸入樣本的權值是一樣的),而每個弱分類器對最終分類結果的作用也不同,是通過權重平均輸出的,權值見上圖中三角形裡面的數值。那麼這些弱分類器和其對應的權值是怎樣訓練出來的呢?
下面通過一個例子來簡單說明。
書中(machine learning in action)假設的是5個訓練樣本,每個訓練樣本的次元為2,在訓練第一個分類器時5個樣本的權重各為0.2.注意這裡樣本的權值和最終訓練的弱分類器組對應的權值α是不同的,樣本的權重隻在訓練過程中用到,而α在訓練過程和測試過程都有用到。
現在假設弱分類器是帶一個節點的簡單決策樹,該決策樹會選擇2個屬性(假設隻有2個屬性)的一個,然後計算出這個屬性中的最佳值用來分類。
adaboost的簡單版本訓練過程如下:
1. 訓練第一個分類器,樣本的權值d為相同的均值。通過一個弱分類器,得到這5個樣本(請對應書中的例子來看,依舊是machine learning in action)的分類預測标簽。與給出的樣本真實标簽對比,就可能出現誤差(即錯誤)。如果某個樣本預測錯誤,則它對應的錯誤值為該樣本的權重,如果分類正确,則錯誤值為0. 最後累加5個樣本的錯誤率之和,記為ε。
2. 通過ε來計算該弱分類器的權重α,公式如下:
3. 通過α來計算訓練下一個弱分類器樣本的權重d,如果對應樣本分類正确,則減小該樣本的權重,公式為:
如果樣本分類錯誤,則增加該樣本的權重,公式為:
4. 循環步驟1,2,3來繼續訓練多個分類器,隻是其d值不同而已。
測試過程如下:
輸入一個樣本到訓練好的每個弱分類中,則每個弱分類都對應一個輸出标簽,然後該标簽乘以對應的α,最後求和得到值的符号即為預測标簽值。
boosting算法的優點:
容易實作,分類準确率較高,沒有太多參數可以調;
對outlier比較敏感;
聚類:
根據聚類思想劃分:
1. 基于劃分的聚類:
k-means, k-medoids(每一個類别中找一個樣本點來代表),clarans.
k-means是使下面的表達式值最小:
k-means算法的優點:
(1)k-means算法是解決聚類問題的一種經典算法,算法簡單、快速。
(2)對處理大資料集,該算法是相對可伸縮的和高效率的,因為它的複雜度大約是o(nkt),其中n是所有對象的數目,k是簇的數目,t是疊代的次數。通常k<<n。這個算法通常局部收斂。
(3)算法嘗試找出使平方誤差函數值最小的k個劃分。當簇是密集的、球狀或團狀的,且簇與簇之間差別明顯時,聚類效果較好。
缺點:
(1)k-平均方法隻有在簇的平均值被定義的情況下才能使用,且對有些分類屬性的資料不适合。
(2)要求使用者必須事先給出要生成的簇的數目k。
(3)對初值敏感,對于不同的初始值,可能會導緻不同的聚類結果。
(4)不适合于發現非凸面形狀的簇,或者大小差别很大的簇。
(5)對于"噪聲"和孤立點資料敏感,少量的該類資料能夠對平均值産生極大影響。
2. 基于層次的聚類:
自底向上的凝聚方法,比如agnes。
自上向下的分裂方法,比如diana。
3. 基于密度的聚類:
dbsacn,optics,birch(cf-tree),cure.
4. 基于網格的方法:
sting, wavecluster.
5. 基于模型的聚類:
em,som,cobweb.
以上這些算法的簡介可參考聚類(百度百科)。
推薦系統:
推薦系統的實作主要分為兩個方面:基于内容的實作和協同濾波的實作。
基于内容的實作:
不同人對不同電影的評分這個例子,可以看做是一個普通的回歸問題,是以每部電影都需要提前提取出一個特征向量(即x值),然後針對每個使用者模組化,即每個使用者打的分值作為y值,利用這些已有的分值y和電影特征值x就可以訓練回歸模型了(最常見的就是線性回歸)。這樣就可以預測那些使用者沒有評分的電影的分數。(值得注意的是需對每個使用者都建立他自己的回歸模型)
從另一個角度來看,也可以是先給定每個使用者對某種電影的喜好程度(即權值),然後學出每部電影的特征,最後采用回歸來預測那些沒有被評分的電影。
當然還可以是同時優化得到每個使用者對不同類型電影的熱愛程度以及每部電影的特征。具體可以參考ng在coursera上的ml教程:https://www.coursera.org/course/ml
基于協同濾波的實作:
協同濾波(cf)可以看做是一個分類問題,也可以看做是矩陣分解問題。協同濾波主要是基于每個人自己的喜好都類似這一特征,它不依賴于個人的基本資訊。比如剛剛那個電影評分的例子中,預測那些沒有被評分的電影的分數隻依賴于已經打分的那些分數,并不需要去學習那些電影的特征。
svd将矩陣分解為三個矩陣的乘積,公式如下所示:
中間的矩陣sigma為對角矩陣,對角元素的值為data矩陣的奇異值(注意奇異值和特征值是不同的),且已經從大到小排列好了。即使去掉特征值小的那些特征,依然可以很好的重構出原始矩陣。如下圖所示:
其中更深的顔色代表去掉小特征值重構時的三個矩陣。
果m代表商品的個數,n代表使用者的個數,則u矩陣的每一行代表商品的屬性,現在通過降維u矩陣(取深色部分)後,每一個商品的屬性可以用更低的次元表示(假設為k維)。這樣當新來一個使用者的商品推薦向量x,則可以根據公式x'*u1*inv(s1)得到一個k維的向量,然後在v’中尋找最相似的那一個使用者(相似度測量可用餘弦公式等),根據這個使用者的評分來推薦(主要是推薦新使用者未打分的那些商品)。具體例子可以參考網頁:svd在推薦系統中的應用。
另外關于svd分解後每個矩陣的實際含義可以參考google吳軍的《數學之美》一書(不過個人感覺吳軍解釋uv兩個矩陣時好像弄反了,不知道大家怎樣認為)。或者參考machine learning in action其中的svd章節。
plsa:
plsa由lsa發展過來,而早期lsa的實作主要是通過svd分解。plsa的模型圖如下:
公式中的意義如下:
具體可以參考2010龍星計劃:機器學習中對應的主題模型那一講
lda:
主題模型,機率圖如下:
和plsa不同的是lda中假設了很多先驗分布,且一般參數的先驗分布都假設為dirichlet分布,其原因是共轭分布時先驗機率和後驗機率的形式相同。
gdbt:
gbdt(gradient boosting decision tree) 又叫 mart(multiple additive regression tree),好像在阿裡内部用得比較多(是以阿裡算法崗位面試時可能會問到),它是一種疊代的決策樹算法,該算法由多棵決策樹組成,所有樹的輸出結果累加起來就是最終答案。它在被提出之初就和svm一起被認為是泛化能力(generalization)較強的算法。近些年更因為被用于搜尋排序的機器學習模型而引起大家關注。
gbdt是回歸樹,不是分類樹。其核心就在于,每一棵樹是從之前所有樹的殘差中來學習的。為了防止過拟合,和adaboosting一樣,也加入了boosting這一項。
關于gdbt的介紹可以可以參考:gbdt(mart) 疊代決策樹入門教程 | 簡介。
regularization:
作用是(網易電話面試時有問到):
1. 數值上更容易求解;
2. 特征數目太大時更穩定;
3. 控制模型的複雜度,光滑性。複雜性越小且越光滑的目标函數泛化能力越強。而加入規則項能使目标函數複雜度減小,且更光滑。
4. 減小參數空間;參數空間越小,複雜度越低。
5. 系數越小,模型越簡單,而模型越簡單則泛化能力越強(ng宏觀上給出的解釋)。
6. 可以看出是權值的高斯先驗。
異常檢測:
可以估計樣本的密度函數,對于新樣本直接計算其密度,如果密度值小于某一門檻值,則表示該樣本異常。而密度函數一般采用多元的高斯分布。如果樣本有n維,則每一維的特征都可以看作是符合高斯分布的,即使這些特征可視化出來不太符合高斯分布,也可以對該特征進行數學轉換讓其看起來像高斯分布,比如說x=log(x+c), x=x^(1/c)等。異常檢測的算法流程如下:
其中的ε也是通過交叉驗證得到的,也就是說在進行異常檢測時,前面的p(x)的學習是用的無監督,後面的參數ε學習是用的有監督。那麼為什麼不全部使用普通有監督的方法來學習呢(即把它看做是一個普通的二分類問題)?主要是因為在異常檢測中,異常的樣本數量非常少而正常樣本數量非常多,是以不足以學習到好的異常行為模型的參數,因為後面新來的異常樣本可能完全是與訓練樣本中的模式不同。
另外,上面是将特征的每一維看成是互相獨立的高斯分布,其實這樣的近似并不是最好的,但是它的計算量較小,是以也常被使用。更好的方法應該是将特征拟合成多元高斯分布,這時有特征之間的相關性,但随之計算量會變複雜,且樣本的協方差矩陣還可能出現不可逆的情況(主要在樣本數比特征數小,或者樣本特征維數之間有線性關系時)。
上面的内容可以參考ng的https://www.coursera.org/course/ml
em算法:
有時候因為樣本的産生和隐含變量有關(隐含變量是不能觀察的),而求模型的參數時一般采用最大似然估計,由于含有了隐含變量,是以對似然函數參數求導是求不出來的,這時可以采用em算法來求模型的參數的(對應模型參數個數可能有多個),em算法一般分為2步:
e步:選取一組參數,求出在該參數下隐含變量的條件機率值;
m步:結合e步求出的隐含變量條件機率,求出似然函數下界函數(本質上是某個期望函數)的最大值。
重複上面2步直至收斂。
公式如下所示:
m步公式中下界函數的推導過程:
em算法一個常見的例子就是gmm模型,每個樣本都有可能由k個高斯産生,隻不過由每個高斯産生的機率不同而已,是以每個樣本都有對應的高斯分布(k個中的某一個),此時的隐含變量就是每個樣本對應的某個高斯分布。
gmm的e步公式如下(計算每個樣本對應每個高斯的機率):
更具體的計算公式為:
m步公式如下(計算每個高斯的比重,均值,方差這3個參數):
關于em算法可以參考ng的cs229課程資料 或者網易公開課:斯坦福大學公開課 :機器學習課程。
apriori:
apriori是關聯分析中比較早的一種方法,主要用來挖掘那些頻繁項集合。其思想是:
1. 如果一個項目集合不是頻繁集合,那麼任何包含它的項目集合也一定不是頻繁集合;
2. 如果一個項目集合是頻繁集合,那麼它的任何非空子集也是頻繁集合;
aprioir需要掃描項目表多遍,從一個項目開始掃描,舍去掉那些不是頻繁的項目,得到的集合稱為l,然後對l中的每個元素進行自組合,生成比上次掃描多一個項目的集合,該集合稱為c,接着又掃描去掉那些非頻繁的項目,重複…
看下面這個例子:
元素項目表格:
如果每個步驟不去掉非頻繁項目集,則其掃描過程的樹形結構如下:
在其中某個過程中,可能出現非頻繁的項目集,将其去掉(用陰影表示)為:
上面的内容主要參考的是machine learning in action這本書。
fp growth:
fp growth是一種比apriori更高效的頻繁項挖掘方法,它隻需要掃描項目表2次。其中第1次掃描獲得當個項目的頻率,去掉不符合支援度要求的項,并對剩下的項排序。第2遍掃描是建立一顆fp-tree(frequent-patten tree)。
接下來的工作就是在fp-tree上進行挖掘。
比如說有下表:
它所對應的fp_tree如下:
然後從頻率最小的單項p開始,找出p的條件模式基,用構造fp_tree同樣的方法來構造p的條件模式基的fp_tree,在這棵樹上找出包含p的頻繁項集。
依次從m,b,a,c,f的條件模式基上挖掘頻繁項集,有些項需要遞歸的去挖掘,比較麻煩,比如m節點,具體的過程可以參考部落格:frequent pattern 挖掘之二(fp growth算法),裡面講得很詳細。