機器學習(常見面試之機器學習算法思想簡單梳理)

  前言: 
  找工作時(IT行業),除了常見的軟件開發以外,機器學習崗位也可以當作是一個選擇,不少計算機的研究生都會接觸這個,如果你的研究方向是機器學習/數據挖掘之類,且又對其非常感興趣的話,可以考慮該崗位,畢竟在機器智能沒有達到人類水平之前,機器學習可以作爲一種重要的手段,而隨着科技的不斷髮展,相信這方面的人才需求也會越來越大。

監督(supervised)

分類(classification)

1.knn(k Nearest Neighbors)算法:

  關鍵公式d=((xixtest)2)12 
  僞代碼(pseudo_code) 
  計算訓練集中到該點的距離 
  選擇距離最小的k個點 
  返回k個點出現頻率最高的類別作爲當前點的預測分類

def knn(in_x, data_set, labels, k):
  diff_mat = tile(in_x, (data_size,1)) - data_set
  sq_diff_mat = diff_mat**2
  distances = sq_diff_mat.sum(axis=1)**0.5
  sorted_dist_indicies = distances.argsort()
  for i in xrange(k):
    vote_label = labels[sorted_dist_indicies[i]]
    class_count[vote_label] = class_count.get(vote_label, 0) + 1
  sortedClassCount = sorted(classCount.iteritems(),
    key=operator.itemgetter(1), reverse=True)
  return sortedClassCount[0][0]12345678910111234567891011

2.決策樹:

  關鍵公式H(x)=P(xi)log2(P(xi)) 
  決策樹中很重要的一點就是根據信息熵的大小選擇一個屬性進行分枝,因此要注意一下信息熵的計算公式,並深入理解它。 
  僞代碼(pseudo_code) 
  檢測數據集中的每個子項是否屬於同一分類: 
    If so return 類標籤; 
    Else 
      尋找劃分數據集的最好特徵 
      創建分支節點 
      for 每個劃分的子集 
        調用函數createBranch並增加返回結果到分支節點中 
    return 分支節點 
  原則只有一個,儘量使得每個節點的樣本標籤儘可能少,注意上面僞代碼中一句說:find the best feature to split the data,那麼如何find thebest feature?一般有個準則就是儘量使得分支之後節點的類別純一些,也就是分的準確一些。如(圖一)中所示,從海洋中撈取的5個動物,我們要判斷他們是否是魚,先用哪個特徵? 

圖一 
(圖一)


  爲了提高識別精度,我們是先用“離開陸地能否存活”還是“是否有蹼”來判斷?我們必須要有一個衡量準則,常用的有信息論、基尼純度等,這裏使用前者。我們的目標就是選擇使得分割後數據集的標籤信息增益最大的那個特徵,信息增益就是原始數據集標籤基熵減去分割後的數據集標籤熵,換句話說,信息增益大就是熵變小,使得數據集更有序。熵(偉大的人物)計算如(公式一)所示: 


H=ni=1p(xi)log2p(xi) 
(公式一)


  其中n代表有n個分類類別(比如假設是二類問題,那麼n=2)。分別計算這2類樣本在總樣本中出現的概率p1p2,這樣就可以計算出未選中屬性分枝前的信息熵。


3. 樸素貝葉斯(Naive Bayes)

  關鍵公式:P(A|B)=P(AB)P(B) 
  爲什麼 
  機器學習的一個重要應用就是文檔的自動分類。在文檔分類中,整個文檔(如一封電子郵件)是實例,而電子郵件中的某些元素則構成特徵。我們可以觀察文檔中出現的詞,並把每個詞的出現或者不出現作爲一個特徵,這樣得到的特徵數目一樣多。假設詞彙表中有1000個單詞。要得到好的概率分佈,就需要足夠的數據樣本,假定樣本數爲N。由統計學知,如果每個特徵需要N個樣本,那麼對於10個特徵將需要N10,對於包含1000個特徵的詞彙表將需要N1000個樣本。可以看到,所需要的樣本數會隨着特徵樹木增大而迅速增長。 
  如果特徵之間相互獨立,那麼樣本樹就可以從N1000減少到1000N。所謂獨立(independence)指的是統計意義上的獨立,即一個特徵或者單詞出現的可能性與它和其他單詞相鄰沒有關係。舉個例子講,假設單詞bacon出現在unhealthy後面與出現在delicious附近,而很少出現在unhealthy附近,這個假設正是樸素貝葉斯分類其中樸素(naive)一詞的含義。樸素貝葉斯分類其中的另一個假設是,每個特徵同等重要。其實這個假設也有問題。如果要判斷留言板的留言是否得當,那麼可能不需要看完所有的1000個單詞,而只需要看10~20個特徵就足以作出判斷了。儘管上述假設存在一些瑕疵,但樸素貝葉斯的實際效果卻很好。 
  是什麼 
  樸素貝葉斯在概率圖模型中被劃爲判別模型(Discriminative model),經典貝葉斯公式,如(公式一)所示: 

p(c|x)=p(xc)p(x) 
(公式一)


  根據後驗概率來判斷,選擇p(ci|x)最大值作爲x的類別ci。 
  僞代碼(pseudo_code) 
  計算每個類別中的文檔數目 
  對每篇訓練文檔: 
    對每個類別: 
      如果詞條出現在文檔中增加該詞條的計數值 
      增加所有詞條的計數值 
    對每個類別: 
      對每個詞條: 
        將該詞條的數目除以總詞條數目得到條件概率 
    返回每個類別的條件概率 
    比較每個類別的條件概率和的大小 
    返回條件概率和大的類別



  下面進入“正規”的機器學習,之所以“正規”是因爲它開始要建立損失函數(cost function),接着優化價值函數求出權重,然後測試驗證。這整套流程是機器學習必經環節。

4.Logistic迴歸

  關鍵公式11+ez

5.支持向量機(SVM)

  理論參考機器學習理論與實戰(五)支持向量機 
  僞代碼(pseudo_code) 
  創建一個α向量並將其初始化爲0向量 
  當迭代次數小於最大迭代次數時(外循環) 
    對數據集中的每個數據向量(內循環): 
      如果該數據向量可以被優化: 
        隨機選擇另外一個數據向量 
        同時優化這兩個向量 
        如果兩個向量都不能被優化,退出內循環 
    如果所有向量都沒被優化,增加迭代數目,繼續下一次循環

6.利用AdaBoost元算法提高分類性能

  關鍵公式α=12ln(1) D(i+1)i=D(i)ieαDi 
  AdaBoost意爲adaptive(自適應) boosting原理: 

圖一 
(圖一)


  (圖一)是Adaboost的原理示意圖,左邊矩形表示數據集,中間表示根據特徵閾值來做分類,這樣每一個弱分類器都類似於一個單節點的決策樹,其實就是閾值判斷而已,右邊的三角形對每個弱分類器賦予一個權重,最後根據每個弱分類器的加權組合來判斷總體類別。要注意一下數據集從上到下三個矩形內的直方圖不一樣,這表示每個樣本的權重也發生了變化,樣本權重的一開始初始化成相等的權重,然後根據弱分類器的錯誤率來調整每個弱分類器的全總alpha,如(圖一)中的三角形所示,alpha 的計算如(公式一)所示 

公式一 
(公式一)


  從(公式一)中也能感覺出來,弱分類器權重alpha和弱分類器分類錯誤率epsilon成反比,如果不能看出反比關係,分子分母同時除以epsilon就可以了,而ln是單調函數。這很make sense,當然分類器的錯誤率越高,越不能器重它,它的權重就應該低。同樣的道理,樣本也要區分對待,樣本的權重要用弱分類器權重來計算,其實也是間接靠分類錯誤率,如(公式二)所示: 

圖一 
(公式二)


  計算單層決策樹僞代碼(pseudo_code) 
  將最小錯誤率minError設爲+ 
  對數據集中的每一個特徵(第一層循環): 
    對每個步長(第二層循環): 
      對每個不等號(第三層循環): 
        建立一棵單層決策樹並利用加權數據集對它進行測試 
        如果錯誤率低於minError,則將當前單層樹設爲最佳單層決策樹 
  返回最佳單層決策樹


迴歸(regression)

7.迴歸:預測數值型數據

  關鍵公式: 
  J(θ)=12mmi=1(hθ(x(i))y(i))2  w^=(XTX)1XTy

  迴歸意爲數據進行曲線擬合。 
  損失函數:J(θ)=12mmi=1(hθ(x(i))y(i))2

  • 線性迴歸 
      即經典最小二乘法,說到最小二乘法就不得說下線性代數,因爲一般說線性迴歸只通過計算一個公式就可以得到答案,如(公式一)所示,其中“w帽”爲當y投影到X的列空間後的估計參數: 


    w^=(XTX)1XTy 
    (公式一)


      其中X是表示樣本特徵組成的矩陣,y表示對應的值,比如房價,股票走勢等。如何記憶公式一呢?


      Xw=y maybe no solution 
      (XT)Xw^=(XT)y  w^=(XTX)1XTy

      如何解得公式一呢,這裏給出投影解法,後續幾個迴歸類推。首先,咱們先來了解誤差函數(公式二) 

    e=i=1m(yixTiw)2



    公式二


      要使公式二最小是不是尋找(圖一)中的e,即垂直於WX的垂線,因爲只有垂直時e才最小。 

    圖一 
    (圖一)


    ae and e=bp and p=Xa 
    aTe=0aT(bXa)=0X=(aTa)1aTb ()


      這下(公式三)和(公式一)完全一樣了圖中a相當於公式一中X,b相當於式中的y,X相當於式中的w^,基於最小二乘法的線性迴歸也就推導完成了

  • 邏輯迴歸 
      邏輯迴歸一般用來做預測,也可以用來做分類,即預測是某個類別!線性迴歸想比大家都不陌生了,y=kx+b,給定一堆數據點,擬合出k和b的值就行了,下次給定X時,就可以計算出y,這就是迴歸。而邏輯迴歸跟這個有點區別,它是一種非線性函數,擬合功能頗爲強大,而且它是連續函數,可以對其求導,這點很重要,如果一個函數不可求導,那它在機器學習用起來很麻煩,早期的海維賽德(Heaviside)階梯函數就因此被sigmoid函數取代,因爲可導意味着我們可以很快找到其極值點,這就是優化方法的重要思想之一:利用求導,得到梯度,然後用梯度下降法更新參數。 
      下面來看看邏輯迴歸的sigmoid函數,如(圖一)所示: 

    圖一 
    (圖一)


      (圖一)中上圖是sigmoid函數在定義域[-5,5] 上的形狀,而下圖是在定義域[-60,60]上的形狀,由這兩個圖可以看出,它比較適合做二類的迴歸,因爲嚴重兩級分化。Sigmoid函數的如(公式一)所示: 

    σ(z)=11+ez 
    sigmoid的由來 
    (公式一)


      隨機梯度下降 僞代碼(pseudo_code): 
      每個迴歸係數初始化爲1 
      重複R次: 
        計算整個數據集的梯度 
        使用αgradient更新迴歸係數的向量 
      返回迴歸係數值

  • 局部加權線性迴歸 
      局部加權迴歸其實只是相當於對不同樣本之間的關係給出了一個權重,所以叫局部加權,如(公式七)所示:

  • 嶺迴歸 

    w^=(XTX+λI)1XTy 
    公式七


      嶺迴歸主要是解決的問題就是當XX’無法求逆時,比如當特徵很多,樣本很少,矩陣X不是滿秩矩陣,此時求逆會出錯,但是通過加上一個對角爲常量lambda的矩陣,就可以很巧妙的避免這個計算問題,因此會多一個參數lambda,lambda的最優選擇由交叉驗證(cross-validation)來決定,加上一個對角不爲0的矩陣很形象的在對角上擡高了,因此稱爲嶺。不同的lambda會使得係數縮減,如(圖六)所示: 

    圖六 
    (圖六)


      說到係數縮減大家可能會覺得有奇怪,感覺有點類似於正則,但是這裏只是相當於在(公式六)中增大分母,進而縮小系數,另外還有一些係數縮減的方法,比如直接增加一些約束,如(公式十)和(公式十一)所示: 


    nk=1w2kλ 
    公式十



    nk=1|wk|λ 
    公式十一


      當線性迴歸增加了(公式十)的約束變得和嶺迴歸差不多,係數縮減了,而如果增加了(公式十一)的約束時就是lasso迴歸,係數有一些0。

  • 前向逐步迴歸 
      有了約束後,求解起來就不像上面那樣直接計算個矩陣運算就行了,回顧第五節說中支持向量機原理,需要使用二次規劃求解,不過仍然有一些像SMO算法一樣的簡化求解算法,比如前向逐步迴歸方法(屬於一種貪心算法): 
      僞代碼(pseudo_code) 
      數據標準化,使其分佈滿足0均值和單位方差 
      在每輪迭代過程中: 
        設置當前最小誤差lowestError爲正無窮 
        對每個特徵: 
          增大或縮小: 
            改變一個係數得到一個新的W 
            計算新W下的誤差 
            如果誤差Error小於當前最小誤差lowestError:設置Wbest等於當前的W 
          將W設置爲新的Wbest 

8.樹迴歸(Classification And Regression Trees)

  前一節的迴歸是一種全局迴歸模型,它設定了一個模型,不管是線性還是非線性的模型,然後擬合數據得到參數,現實中會有些數據很複雜,肉眼幾乎看不出符合哪種模型,因此構建全局的模型就有點不合適。這節介紹的樹迴歸就是爲了解決這類問題,它通過構建決策節點把數據切分成區域,然後局部區域進行迴歸擬合。先來看看分類迴歸樹(CART,Classification And Regression Trees),這個模型優點就是上面所說,可以對複雜和非線性的數據進行建模,缺點就是得到的數據不容易理解。顧名思義,它既可以做分類也可以做迴歸,至於分類前面已經說過了,這裏略過。直接看僞代碼吧。 
  僞代碼(poseudo_code): 
  對每個特徵: 
    對每個特徵之: 
      將數據急切分成兩份 
      計算切分的誤差 
      如果當前誤差小於當前最小誤差,那麼將當前切分設定爲最佳切分並更新最小誤差 
  返回最佳切分的特徵和閾值 
  下面就是無監督學習方法,所謂無監督學習也就是沒有標籤,對樣本進行聚類分析、關聯分析,這兩大類都可以說的很簡單也可以說很複雜,學術的東西本身就一直在更新着。

無監督(unsupervised)

9.利用k-均值聚類對未標註數據分組

  k-均值聚類可以擴展一下形成層次聚類(Hierarchical Clustering),也可以進入概率分佈空間進行聚類。而關聯分析又是另外一個比較有力的工具,它又稱爲購物籃分析,我們可以大概體會它的用途,挖掘之間的關係,經典故事就是啤酒和尿布的關聯。另外提一下,google搜索的兩大核心技術:深度學習和知識圖。深度學習就不說了,知識圖就是挖掘關係。找到了關係就是找到了金礦,關係也可以用複雜網絡(complex network)來建模。好今天就聊到這裏,來看看k-Means的僞代碼: 
  創建k個點作爲起始質心(經常是隨機選擇) 
  當任意一個點的蔟分配結果發生改變時 
    對數據集中的每個數據點 
      對每個質心 
        計算質心與數據點之間的距離 
      將數據點分配到據其最近的蔟 
    對每一個蔟,計算蔟中所有點的均值並將其做爲質心

10.利用Apriori算法進行關聯分析

  《機器學習實戰》的最後的兩個算法對我來說有點陌生,但學過後感覺蠻好玩,瞭解了一般的商品數據關聯分析和搜索引擎智能提示的工作原理。先來看看關聯分析(association analysis)吧,它又稱關聯規則學習(association rule learning),它的主要工作就是快速找到經常在一起的頻繁項,比如著名的“啤酒”和“尿布”。試想一下,給我們一堆交易數據,每次的交易數據中有不同的商品,要我們從中發掘哪些商品經常被一起購買?當然窮舉法也可以解決,但是計算量很大,這節的算法Apriori就是解決此類問題的快速算法。Apriori在拉丁語中表示“from before”(來自以前)的意思,在這裏就是來自於子集的頻繁信息咯,不懂,彆着急。下面給出幾個簡單的交易數據,如(圖一)所示: 

圖一 
(圖一)


  我們的目標就是找到經常在一起出現的頻繁子集,集合哦。我們用大括號“{}”來表示集合。爲了表示某個子集是否是頻繁子集,我們需要用一些量化方法,光計數也不行,因爲不同量的交易數據出現的次數差別很大,一般用支持度(support)和置信度(confident)這兩個指標來量化頻繁子集、關聯規則。這兩個指標的計算都很簡單:


  支持度=(包含該子集的交易數目)/總交易數目

  比如{豆奶}的支持度爲4/5,有四條交易數據都有豆奶,而{豆奶,尿布}的支持度爲3/5。

  置信度只是針對像{尿布}->{葡萄酒}的關聯規則來定義的: 
  尿布到葡萄酒的置信度=支持度({尿布,葡萄酒})/支持度(尿布)

  比如在(圖一)中,{尿布,葡萄酒}的支持度爲3/5,而尿布的支持度爲4/5,那麼尿布->葡萄酒的可信度爲3/4=0.75。 

圖二 
(圖二)


  (圖二)中只有四種商品{0,1,2,3},而其子集則有2^4-1=15個(空子集除外),每計算一個子集的兩個指標都需要遍歷一下數據,要遍歷15次,如果有100種商品,則有1.26*10^30個子集,這個計算量很大,所幸的是研究人員發現了一種Apriori原理:Apriori原理是說如果某個子集不是頻繁的,那麼包含它的所有超集也不是頻繁的,這樣一下就砍掉了一大半,如(圖三)所示: 

圖三 
(圖三)


  (圖三)中{2,3}不是頻繁的,那麼所有包含它的超子集都不是頻繁的,有了這個原則,就使得我們計算頻繁子集的變成可行的。有了Apriori原理作爲指導,我們還需要一些trick 來實現代碼,這些trick就構成了Apriori(a priori一個先驗)算法僞代碼: 
  當集合中項的個數大於0時 
    構建一個k個項組成的候選項集的列表 
    檢查數據已確認每個項集都是頻繁的 
    保留頻繁項集並構建k+1項組成的候選項集的列表


11.利用FP-grownth算法來高效發現頻繁項集

  FP-growth算法只需要對數據庫進行兩次掃描,而Apriori算法對於每個潛在的頻繁項集都會掃描數據集判定給定模式是否頻繁,FP-growth比Apriori算法快。缺點:實現複雜 

圖三 
(圖三)


  僞代碼(poseudo_code): 
  procedure FP_growth(Tree, a) 
  if Tree 含單個路徑P then{ 
    for 路徑P中結點的每個組合(記作b) 
    產生模式b U a,其支持度support = b 中結點的最小支持度; 
  } else { 
    for each ai 在Tree的頭部(按照支持度由低到高順序進行掃描){ 
      產生一個模式b = ai U a,其支持度support = ai .support; 
      構造b的條件模式基,然後構造b的條件FP-樹Treeb; 
      if Treeb 不爲空 then 
        調用 FP_growth (Treeb, b); 
    } 
  }


分佈式(distributed)

12.大數據和MapReduce

  爲什麼 
  當運算需求超出了當前資源的運算能力,可以考慮購買更好的機器。另一個情況是,運算需求超出了合理價位下所能夠買到的機器的運算能力。其中一個解決辦法是將計算轉成並行的作業,MapReduce就提供了這種方案的一個具體實施框架。在MapReduce中,作業被分成map階段和reduce階段。 
  是什麼 
  一個點行的作業流程是先使用map階段並行處理數據,之後將這些數據在reduce階段合併。這種多對一的模式很經典,但不是唯一的流程方式。mapper和reducer之間傳輸數據的形勢是key/value對。一般地,map階段後數據還會按照key值進行排序。Hadoop是一個流行的可運行MapReduce作業的Java項目,它同時也提供非Java作業的運行支持,叫做Hadoop流。 
  怎麼做 
  Amazon 網絡服務(AWS)允許用戶按時長租借計算資源。彈性MapReduce(EMR)是Amazon網絡服務上的一個常用工具,可以幫組用戶在AWS上運行Hadoop流作業。簡單的單步MapReduce任務可以在EMR管理控制檯上實現並運行。更復雜的任務則需要額外的工具。其中一個相對新的開源工具是mrjob,使用該工具可以順序地執行大量的MapReduce作業。經過很少的配置,mrjob就可以自動完成AWS上的各種繁雜步驟。 
  很多機器學習算法都可以很容易地寫成MapReduce作業。而另一些機器學習算法需要經過創新性的修改,才能在MapReduce上運行。SVM是一個強大的文本分類工具,在大量文檔上訓練一個分類器需要耗費巨大的計算資源,而Pegasos算法可以分佈式地訓練SVM分類器。像Pegasos算法一樣,需要多次MapReduce昨夜的機器學習算法可以很方便地使用mrjob來實現。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章