LDA线性判别分析案例实战
LDA是線性判別分析的簡稱,該方法是一種線性學習方法,常用于分類。
本文主要思路:
1、二分類LDA原理
2、二分類LDA如何用python實現
3、二分類LDA案例實戰
4、多分類LDA原理
5、多分類LDA如何用python實現
6、多分類LDA案例實戰
1、二分類LDA原理
講解之前先了解一下向量的知識:
如下圖所示設向量AB是單位向量,AC是任意向量,向量AC到向量AB的投影為|AC|cosx=ABAC
如下圖所示(該圖來源于周志華 機器學習的西瓜書,如有侵權,聯系刪除),對于一個二維空間中的點想(x, y),點(x, y)與原點(0, 0)可以構成一個向量x*。這個向量到圖中直線所對應的向量 wT的投影為wT*x。在圖中可以看到,這是一個二分類問題,LDA的思想就是將圖中的點投影到這條直線上,相同類型的點在直線上的位置會很接近。
但如何讓相同類型的點在直線上的投影很接近呢?首先引入方差的概念,方差表示一組數的波動程度,波動程度越大方差越大,如果一組數據在某一個方向上方差很小,那么這組數據在這個方向上的的波動程度也會很小。從下圖中可以看出,沿直線垂直的方向上數據的波動程度很小,那么這些數據點投影到這條直線上會挨的很緊密。
LDA是一個有監督的方法,首先通過訓練數據求出所要投影的直線,并求出各個類別的中心點center在直線的位置。當需要預測測試數據的類別時,將測試數據也投影到這條直線上。并求出測試數據點到每個類的中心點center的距離,距離哪一個中心點近就是哪一類。
如何求解這條直線呢?下面將會推導:
引用自:https://www.cnblogs.com/hfdkd/articles/7730512.html
通過上述計算最終得到w,求出直線。
(上面推導不止適用于二維空間,同樣適用于高維空間)
**
所以LDA具體步驟為:
**
1、根據訓練數據求出w;
2、根據w計算出訓練數據每一類數據對應中心點M在直線上的投影距離;
3、根據w計算測試數據在直線上的投影距離x,根據投影距離x計算到中心點M的距離,距離那一個中心點近就是哪一類數據。
LDA利用Python編寫:
import numpy as np import pandas as pd from collections import Counter import matplotlib.pyplot as pltclass BinaryClassification:"""LDA二分類"""def fit(self, x, y):""":param x: 訓練樣本:param y: 訓練標簽:return:"""# 將x,y轉換為數組,方便接下來計算x = np.array(x)y = np.array(y)# 判斷是否為二分類問題self.re = Counter(y)if len(self.re.keys()) != 2:raise ValueError("二分類問題,需要傳入兩類數據")# c1存儲第一類數據,c2存儲第一類數據c1 = []c2 = []for temp_x, temp_y in zip(x, y):if temp_y == list(self.re.keys())[0]:c1.append(temp_x)else:c2.append(temp_x)c1 = np.array(c1)c2 = np.array(c2)# 計算每類的平均值mean1 = np.mean(c1, axis=0)mean2 = np.mean(c2, axis=0)# 計算每類的方差var1 = np.var(c1, axis=0)var2 = np.var(c2, axis=0)# print(mean1, mean2, var1, var2)# 計算每類協方差cov1 = np.dot(c1.T, c1)/list(self.re.values())[0]cov2 = np.dot(c2.T, c2)/list(self.re.values())[1]# print(cov1)# print(cov2)# 計算類內散度矩陣Sw就是上文中的BSw = cov1 + cov2# 計算類內散度矩陣Sb就是上文中的Asb = np.array(mean2 - mean1)Sb = np.dot(sb.reshape([-1, 1]), [sb])# 求解瑞利熵的最大值U, sigma, VT = np.linalg.svd(np.dot(np.linalg.inv(Sw), Sb))w = VT[0]# 計算每類樣本中心點在超平面(直線)上的位置center1 = np.dot(w, mean1.T)center2 = np.dot(w, mean2.T)return w, center1, center2def predict(self, X, w, center1, center2):# 計算每個樣本值的在超平面上的位置X = np.array(X)position = np.dot(w, X.T)# 計算樣本點到各個中心點的距離dis1 = np.abs(position - center1)dis2 = np.abs(position - center2)# 比較樣本點到兩個中心點的距離的大小,樣本屬于距離小的點compare = dis1 - dis2# label用于存儲X中數據的類別label = []for i in compare:if i < 0:label.append(list(self.re.keys())[0])else:label.append(list(self.re.keys())[1])return label二分類LDA案例實戰:
訓練數據如下(A-M表示數據特征,label表示標簽,0表示第一類數據,1表示第二類數據):
| | |
測試數據如下(后七個數據為第二類數據,前面為第一類數據):
| | |
測試結果:
可以看出可以準確的分類。
**
4、多分類LDA
**
上述是二分類LDA,對于多分類LDA常見的方式有OVO(1對1),OVR(1對其它),MvM(多對多),以及用上述公式推導直接求出多分類。
(1)OVO(1對1)
該方法是從訓練數據中任意選取兩類數據去構建分類器,(假設有N種類別)一共可以構建N(N-1)/2個分類器,運用這些分類器去分類測試樣本,每一個測試樣本都可以得到N(N-1)/2個結果,對每一個樣本選取結果中數量最多的結果作為最終結果。
代碼:
用上面數據測試結果:
data = pd.read_excel("二分類數據.xlsx", sheet_name=2) data1 = pd.read_excel("二分類數據.xlsx", sheet_name=3) x = np.array(data.values)[:, :-1].reshape([-1, 13]) y = np.array(data.values)[:, -1] X = np.array(data1.values) re = ones_vs_ones(x, y, X) print(re)plt.figure() plt.scatter(list(range(X.shape[0])), re) plt.show() [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
(2)OvR(一對其余)
一對其余是通過構建N個分類器,來進行分類,每一個分類器是選擇一個類別作為正類其它類別作為負類,(例如:有4種類別1,2,3,4;選擇其中2作為正類,1,3,4作為一類叫做負類),總共可以構建N個分類器,用測試數據進行測試時,如果測試數據中一個數據點分類為正類那么他就屬于這一類。一般情況下,每一個測試數據只有一個正類,其它全為負類,但也有時候有多個負類,這時需要計算每個分類器的置信度,選擇置信度大的正類結果作為最終結果。
代碼如下:
用上面數據分類結果:
data = pd.read_excel("二分類數據.xlsx", sheet_name=2) data1 = pd.read_excel("二分類數據.xlsx", sheet_name=3) x = np.array(data.values)[:, :-1].reshape([-1, 13]) y = np.array(data.values)[:, -1] X = np.array(data1.values)re = ones_vs_others(x, y, X)plt.figure() plt.scatter(list(range(X.shape[0])), re) plt.show()
未完待續。。。。
總結
以上是生活随笔為你收集整理的LDA线性判别分析案例实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bin文件夹下的DLL可以做什么?
- 下一篇: 基于浏览器请求的国际化实现