機器學習經典算法總結


knn分類算法

1.特點

-    精度高

-    對異常值不敏感、計算時間空間復雜度高

2.基本思想、算法偽代碼

計算待預測樣本與數據集中點的距離
選取前k個與待預測樣本距離最小的點
返回這前k個點出現頻率最高的類別作為待預測樣本的類別

3.構思定義好存儲數據結構

-    dataSet (m*n階矩陣):m代表m個數據,n代表每個數據的特征向量維度

-    labels (m*1 list):m與數據數對應

-    classCount (p個key-value對的字典):p代表類別數,key代表類比名稱,value代表與待預測樣本距離最近的前k個點中相應類別出現的次數
    該結構適用於投票表決情況,例如DT中子節點的類別歸屬問題,同樣適用

4.算法python代碼細節

-    注意利用np.tile將待預測樣本維度擴展,餐能進一步整體計算距離

    例如(testMat = np.tile(x, (m, 1)))

-    注意利用np.argsort()對距離排序,並返回由小到大的索引值
    例如(sortedDistIndex = np.argsort(dist))

-    注意sorted函數與operator.itemgetter(1)的配合使用,對字典的value進行排序,也要注意對字典進行.iems()轉換為可迭代列表操作
    例如(sortedClassCount = sorted(classCount.itmes(), key = operator.itemgetter(1), reverse = True))

-    注意使用字典的.get()方法直接為不存在key設置初始值,簡化代碼
    例如(classCount[label] = classCount.get(label, 0) + 1)

-    注意數據特征的歸一化處理(消除量綱)

-    注意錯誤率的計算思路
    例如(預測標簽和測試集標簽不同的數量/總預測數量)

5.實戰

-    約會網站配對、手寫數字識別

LR分類算法

1.特點

-    計算代價不高,易於理解實現,大部分時間用於訓練,訓練完成后分類快。

-    容易欠擬合,分類精度不高。

2.基本思想

-    LR的目的:尋找一個非線性函數sigmoid的最佳擬合參數,求解過程由最優化算法完成。

-    sigmoid函數:輸入為實數域,輸出為0~1之前的數值,大於0.5歸入1類,小於0.5歸入0類。(可看成是一種概率估計)。

-    最優化算法:BGD(批量梯度下降)、SGD(隨機梯度下降)、mini-batch SGD。
      SGD算法是在線學習算法(與之對應的是批處理算法),他的優勢:在新數據到來時就完成參數的更新,無需重新讀取整個數據集進行計算

-    整體分類處理流程:將測試集上每個特征向量乘以之前最優化算法訓練好的回歸系數,再將乘積結果求和,最后出入到sigmoid函數中即可輸出類別。

3.構思定義好存儲數據結構

-    dataSet(m*n 階矩陣):m代表m個數據點,n代表每個數據點向量維度(最后一維表示該點的標簽),沒有x0。

-    weights(n*1 階矩陣):n代表回歸系數的維度與數據點維度相同。

4.算法偽代碼

def BGD:
    初始化回歸系數為1
    循環k次:
        計算整個數據集梯度(gradient)
        利用alphs*gradient更新回歸系數向量
    返回回歸系數

def SGD:
    初始化回歸系數為1
    循環k次:
        隨機選取之前未選去過的某個數據點:
            計算該數據點的梯度
            更新回歸系數
    返回回歸系數

5.算法python代碼細節

-    注意numpy矩陣(mat)的transpose()使用,避免矩陣相乘出錯

    (例如:weights += alpha * dataMatrix.transpose() * error)

-    注意numpy矩陣(mat)和numpy數組(array)的乘法使用不同

-    注意SGD中隨機選取某個數據點應與之前選去過的去重

    (例如:del(dataIndex[randIndex]))

6.實戰

-    從疝氣病症預測病馬的死亡率

-    數據預處理中數據缺失問題:
      LR特征缺失采用0填充
      原因: 1。更新時不會影響系數的值  weights += alpha * dataMatrix * error ,以0填充,該特征系數將不做更新
                2。對結果預測不產生任何傾斜性,因為sigmoid(dataMatrix * weight)中sigmoid(0)=0.5

-    注意算法錯誤率的計算,並測試多次取平均值思想

決策樹(DT)分類算法

1.特點

-    計算復雜度不高、輸出結果易於理解(訓練好的模型可以序列化存儲)、對中間值的缺失不敏感

-    會產生過度匹配問題(ID3算法),可采用CART算法解決

2.基本思想

-    首先測量初始集合中數據的不一致性,即熵。熵越高,數據越混亂。

-    然后根據信息增益尋找最優方案划分數據集,直至數據集中所有數據屬於同一類

-    信息增益,即熵的減少或者數據無序度的減少。信息增益最高的特征就是最好的划分選擇。

3.構思定義好存儲數據結構

-    dataSet (m*n階矩陣):m個數據、每個數據n-1個特征,最后一維代表標簽

-    myTree    ({feature: { }}字典):構造的決策樹

-    labels (k大小的列表):類別列表

4.算法偽代碼(五個主要函數)

def 遞歸創建決策樹(dataSet, labels):
    遞歸出口(兩種情況):
        1. 划分后的集合類別完全相同
        2. 遍歷完所有特征(采用投票多數選舉策略)
    確定最佳划分特征
    對於該特征的每個特征值划分后的數據:
            遞歸調用創建決策樹
    返回決策樹

def 確定最佳划分特征(dataSet):
    計算初始熵
    對於每個特征:
        對於該特征的每個特征值:
            計算該特征值划分后的熵
        每個特征值划分后的熵相加得到該特征划分后的熵
    返回信息增益(前后熵變化)最大的特征

def 按照給定特征划分數據集(dataSet, axis, value):
    返回指定特征的去除特征值的數據

def 計算給定數據集的香農熵(dataSet):
    統計每個類別數據量
    計算每個類別概率:每個類別數據量/總數據量
    計算香濃熵:- prob * log(prob, 2) 

def 使用決策樹進行分類(tree, labels, testVec):
    對於字典中每個value:
        如果該value是字典型,則遞歸調用函數
        如果不為,則直接返回該類別

5.python代碼細節

-    注意使用列表推導創建新列表,並使用python原生的集合(set)數據類型去重,簡化代碼
    (例如:featValue = set([example[i] for example in dataSet]))

-    注意列表extend和append的恰當使用

-    注意字典類型判斷使用isinstance或type().__name__
    (例如:if type(secondDict[key].__name__ == 'dict')        if isinstance(secondDict[key], dict))

-    注意使用pickle序列化存儲
    (例如pickle.dump(tree, file)    pickle.load(file))

6.實戰

-    預測隱形眼鏡類型

Bayes分類

1.特點

-    數據較少的情況下仍然有效,可處理多類別問題

-    對輸入數據要求較為敏感

2.基本思想

-    朴素貝葉斯前提:特征之間相互獨立,即一個詞的出現概率不依賴於其他的詞    

-    貝葉斯准則:p(c|w) = p(w|c) * p(c) / p(w) 
        其中c代表類別,w代表文本向量。p(c|w)最大即將其划分為對應c類。

-    主要計算p(w|c)和p(c)

-    兩種主要細節解決實際問題
       1.p(w|c)為0問題。在求p(w|c)時,有一個為0就會導致整個條件概率為0。
         采用拉普拉斯平滑方法,初始化時將每個詞條出現次數設為1,將總詞條出現數設為k,k為類別數
       2.下溢出問題。由於p(w|c)往往都很小,python嘗試想成很多很小的數時,會四舍五入為0。
          采用取對數方法,ln(a * b) = ln(a) + ln(b)

3.構思定義好存儲數據結構

-    dataSet (二維列表):存儲文檔集;一維存儲文檔,二維存儲每個文檔的內容(詞)

-    vocList(1*n列表):存儲每個詞;m代表文檔集中的n個不同的詞

-    trainMat(m*n階矩陣):存儲訓練文檔集向量;m代表m個訓練文檔,n代表每個文檔中所有詞出現的次數(與vocList中的n對應)

4.算法偽代碼(共五大函數)

def 創建總詞集合(dataSet):
    對於每個文檔:
        去重詞條
    將所有詞條合並
    返回總詞集合列表

def 將文檔轉化為向量(vocList, doc):   one-hot表示法
    初始化詞計數列表各項為0
    對於該文檔每個詞:
        如果詞在vocList(總詞集合)中:
            詞計數列表相應位置計數+1
        若果不在:
            報錯:總詞集合中不存在該詞
    返回詞計數列表,即文檔向量

def 訓練參數(trainMat, trainClass):
    計算pc1=屬於類別c1的文檔數/總文檔數
    對於每個文檔:
        對於每個類別:
            統計各詞條出現次數
            統計總詞條出現次數
    對於每個類別:
        對於每個詞條:
            計算p(w|c) = 該詞條出現次數/總詞條出現次數
    返回各個p(w|c)和p(c)

def 分類函數(testVec, pwc0, pwc1, pc1):
    計算p0和p1
    將測試文檔划分為p值(概率)大的那一類

def 垃圾郵件分類封裝函數():
    對於每篇文檔:
        文檔預處理(去除特殊符號、和長度小於2的詞、轉化為小寫)
        讀入詞列表、類別標簽
    形成文檔集合
    創建總詞集合
    留存交叉驗證划分訓練集和測試集
    訓練出p(w|c)和p(c)
    對於每篇測試文檔:
        根據訓練好的參數分類
    計算誤差(錯誤率)

5.python代碼細節

-    注重集合set類型的去重使用和並集操作
    (例如:vocList = vocList | set(doc))    

-    注重列表快速初始化
    (例如:docVec = [0] * len(vocList)   trainingSet = range(50))

-    注重留存交叉驗證技巧,設置隨機索引,並注意del的使用
    (例如:trainingSet = range(50)      for i in range(10):randIndex = random.randint(0, len(trainingSet))   testSet.append(tS[rI])  del(tS[rI]))

6.實戰

-    過濾網站惡意留言、過濾垃圾郵件

SVM支持向量機

1.特點

-    泛化能力強、計算開銷不大、結果易解釋

-    對參數調節和核函數的選擇敏感,原始不加修改的分類器僅適用於二分類

2.基本思想

-    最大化支持向量到分隔超平面的距離;支持向量:離分隔超平面最近的那些點;公式化:argmax{miny(wx+b)*1/||w||}
        ||w||為w的L2范數

-    最優分離超平面由支持向量完全決定

-    函數間隔、幾何間隔:幾何間隔在函數間隔的基礎上對超平面的法向量w加某些約束(當w和b成倍增加時,超平面不變,而函數間隔卻也成倍增加,所以引入幾何間隔,即*1/||w||)

-    凸二次規划問題,求解方法:朗格朗日乘子法;通過求解對偶問題學習線性支持向量機,即首先求解對偶問題的最優質α,然后求最優質w和b,得出分離超平面和分類決策函數
      
-    對偶問題:實質相同但從不同角度提出不同提法的一對問題。
      二次規划問題:優化的目標函數為二次函數、約束函數為線性函數。
      凸二次規划:目標函數是凸函數。

-    核函數:通過非線性變換將低維非線性問題映射為高維線性問題。常用核函數:高斯徑向基函數。

-    SMO(序列最小優化)算法:是支持向量機學習的一種快速算法。
    基本思想:不斷將原二次規划問題分解為只有兩個變量的二次規划子問題,並對子問題進行求解,直到所有變量滿足KKT條件為止。

AdaBoost(Boosting)元算法

1.特點

-    分類器組合,與bagging都屬於集成算法或元算法。與bagging區別:bagging通過隨機抽樣的替換方式,得到與元數據集規模一樣的數據集(RF隨機森林算法),而boosting在bagging的思路上更進一步,它在數據集上順序應用多個分類器,共同決定分類結果。

2.基本思想

-    AdaBoost以弱分類器作為基分類器,輸入數據,使其通過權重向量D進行加權。在第一次迭代中,所有數據樣本的權重相等為1/N,在后續迭代過程中,前次迭代分錯的數據的權重會增大。最后基於每個弱分類器的錯誤率計算每個弱分類器的權重alpha,所有這些弱分類器的結果加權求和就得到了最終結果。

3.構思定義好存儲數據結構

-    numIt(整數):AdaBoost訓練迭代次數,即弱分類器個數

-    classEst(列表中元素對應1或-1):弱分類器評估的類別

-    bestStump(字典):存儲給定數據權重向量D時所得到的弱分類器,即最佳DS(單層決策樹),的相關信息(划分特征、閾值、該分類器權重alpha等)

-    weakClassList(列表):存儲每個bestStump的列表集合,用於封裝各個弱分類器的相關信息,即該列表每行對應一個弱分類器的bestStump。

-    aggClassEst(列表中元素為float):存儲每次alpha權重加權求和后的類別估計值,后續引入符號函數sign(aggClassEst)形成強分類器。

4.算法偽代碼(三大函數)

根據向量D構建最佳DS
def buildStamp(dataList, classLabels, D):
    初始化最小錯誤率為正無窮
    對於數據集中的每個特征:
        對於每個步長:
            對於每個不等號:
                建立一顆單層決策樹並利用加權數據集對其進行測試
                如果錯誤率低於最小錯誤率,則將當前單層決策樹作為最佳單層決策樹
    返回最佳單層決策樹

基於DS的adaboost訓練函數
def adaBoostTrainDS(dataList, classLabels, numIt=40):
    初始化數據權重D為1/N
    對於每次迭代:
        找到該D下的最佳單層決策樹,返回該最佳決策樹信息,在D下的誤差和類別數組
        將該DS加入DS累積數組
        利用該弱分類器在D下的誤差計算出分類器權重alpha
        計算更新D
        更新累計類別估計值,即計算alpha和相應弱分類器的類別數組加權求和
        通過符號函數sign得到強分類器,計算錯誤率。如果錯誤率等於0,退出循環
    返回DS累積數組

adaboost分類函數
def adaClassify(testData, classifyArr):
    對於訓練好的每個弱分類器:
        計算測試數據的類別
        進行相應alpha加權求和
    利用符號函數返回類別

5.實戰

-    提升從疝氣病症預測病馬的死亡率的准確度

-    非均衡分類問題(正反樣例數目不相等)解決辦法:1. 通過過抽樣(復制樣例)和欠抽樣(刪除樣例)調節  2. 訓練分類器時,將錯誤代價考慮在內

K-means聚類算法

1.特點

-  容易實現,無監督(無需訓練操作)

-  容易受到初始簇質心的影響,可能收斂到局部最小、在大規模數據集上收斂較慢。

2.基本思想

-  隨機確定k個初始點作為質心。

-  將數據集中每個點分配到一個簇中(為每個點找出距離其最近的質心,並將其分配給該質心所對應的簇)。

-  更新每個簇的質心為所有點的平均值(直至每個點的簇分配結果不再改變)

3.構思定義好存儲數據結構

-  數據集dataSet(m*n 階 numpy 數據 (矩陣) ):m代表有m個數據點,n代表每個數據點向量維度為n。

-  質心集centroids(k*n 階):k代表有k個質心,n對應向量維度。

-  簇分配集clustAss(m*2)[minIndex, minDis]:m對應m個數據點,索引[0](即minIndex)代表相應數據點分配的質心索引,索引[1](即minDis)代表數據點和其分配質心的距離平方。

4.算法偽代碼

初始化k個質心
當任意一個數據點的簇分配結果改變時:
    對數據集中的每個點:
        對每個質心:
            計算該點與該質心的距離
        將該點分配到距離最近的質心所在簇
        對每個質心所在簇:
            更新其質心為簇中所有點的均值

5.算法python代碼細節

-  善於使用數組過濾器

    (例如:更新質心時簡短代碼:centroids[i, :] = np.mean(dataSet[np.nonzero(clustAss[i, :] == cent) [0] ]))

-  善於使用標志變量

    (例如:利用clustchanged來標記數據點簇分配結果是否改變)

-  善於打包函數,防止主程序過於臃腫

    (例如:將加載文件、計算距離和隨即初始化質心集另打包為三個函數,在kmeans主函數中直接使用上述函數)

6.算法改進

-  二分k-means聚類算法

-  基本思想:將所有點作為一個簇,然后使用傳統Kmeans聚類算法(k=2)對其進行划分。下一次迭代時,選擇有最大誤差的簇進行划分,直至k個簇創建成功。

-  偽代碼:

    將所有點看作一個簇
    當簇數目小於k時:
        計算總誤差
        對於每個簇:
            對該簇進行傳統k-means聚類(k=2)
            計算將該簇一分為二后的總誤差
        選擇使得總誤差最小的簇進行實際划分操作

7.實戰

-  地圖點聚類

-  具體步驟:
    0. 目的:將多個地方聚類,選擇最佳地點
    1. 利用Yahoo PlaceFinder API 將地名轉化為數據,並提取出經緯度
    2. 應用biKmeans算法聚類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM