日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

LDA线性判别分析案例实战

發(fā)布時間:2023/12/20 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LDA线性判别分析案例实战 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

LDA是線性判別分析的簡稱,該方法是一種線性學(xué)習(xí)方法,常用于分類。
本文主要思路:
1、二分類LDA原理
2、二分類LDA如何用python實現(xiàn)
3、二分類LDA案例實戰(zhàn)
4、多分類LDA原理
5、多分類LDA如何用python實現(xiàn)
6、多分類LDA案例實戰(zhàn)

1、二分類LDA原理

講解之前先了解一下向量的知識:
下圖所示設(shè)向量AB單位向量AC是任意向量,向量AC到向量AB投影為|AC|cosx=ABAC

如下圖所示(該圖來源于周志華 機(jī)器學(xué)習(xí)的西瓜書,如有侵權(quán),聯(lián)系刪除),對于一個二維空間中的點想(x, y),點(x, y)與原點(0, 0)可以構(gòu)成一個向量x*。這個向量到圖中直線所對應(yīng)的向量 wT的投影為wT*x。在圖中可以看到,這是一個二分類問題,LDA的思想就是將圖中的點投影到這條直線上,相同類型的點在直線上的位置會很接近。
但如何讓相同類型的點在直線上的投影很接近呢?首先引入方差的概念,方差表示一組數(shù)的波動程度波動程度越大方差越大,如果一組數(shù)據(jù)在某一個方向上方差很小,那么這組數(shù)據(jù)在這個方向上的的波動程度也會很小。從下圖中可以看出,沿直線垂直的方向上數(shù)據(jù)的波動程度很小,那么這些數(shù)據(jù)點投影到這條直線上會挨的很緊密。
LDA是一個有監(jiān)督的方法,首先通過訓(xùn)練數(shù)據(jù)求出所要投影的直線,并求出各個類別的中心點center在直線的位置。當(dāng)需要預(yù)測測試數(shù)據(jù)的類別時,將測試數(shù)據(jù)也投影到這條直線上。并求出測試數(shù)據(jù)點到每個類的中心點center的距離,距離哪一個中心點近就是哪一類。

如何求解這條直線呢?下面將會推導(dǎo):





引用自:https://www.cnblogs.com/hfdkd/articles/7730512.html

通過上述計算最終得到w,求出直線。
(上面推導(dǎo)不止適用于二維空間,同樣適用于高維空間)
**

所以LDA具體步驟為:

**
1、根據(jù)訓(xùn)練數(shù)據(jù)求出w;
2、根據(jù)w計算出訓(xùn)練數(shù)據(jù)每一類數(shù)據(jù)對應(yīng)中心點M在直線上的投影距離;
3、根據(jù)w計算測試數(shù)據(jù)在直線上的投影距離x,根據(jù)投影距離x計算到中心點M的距離,距離那一個中心點近就是哪一類數(shù)據(jù)。

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: 訓(xùn)練樣本:param y: 訓(xùn)練標(biāo)簽:return:"""# 將x,y轉(zhuǎn)換為數(shù)組,方便接下來計算x = np.array(x)y = np.array(y)# 判斷是否為二分類問題self.re = Counter(y)if len(self.re.keys()) != 2:raise ValueError("二分類問題,需要傳入兩類數(shù)據(jù)")# c1存儲第一類數(shù)據(jù),c2存儲第一類數(shù)據(jù)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)# 計算每類協(xié)方差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)# 計算類內(nèi)散度矩陣Sw就是上文中的BSw = cov1 + cov2# 計算類內(nèi)散度矩陣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中數(shù)據(jù)的類別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案例實戰(zhàn):
訓(xùn)練數(shù)據(jù)如下(A-M表示數(shù)據(jù)特征,label表示標(biāo)簽,0表示第一類數(shù)據(jù),1表示第二類數(shù)據(jù)):
| | |

測試數(shù)據(jù)如下(后七個數(shù)據(jù)為第二類數(shù)據(jù),前面為第一類數(shù)據(jù)):
| | |

def main():lda = BinaryClassification()data = pd.read_excel("二分類數(shù)據(jù).xlsx", sheet_name=2)data1 = pd.read_excel("二分類數(shù)據(jù).xlsx", sheet_name=3)x = np.array(data.values)[:, :-1].reshape([-1, 13])y = np.array(data.values)[:, -1]w, center1, center2 = lda.fit(x, y)print(center1)print(center2)X = np.array(data1.values)label = lda.predict(X, w, center1, center2)print(label)if __name__ == "__main__":main()

測試結(jié)果:

可以看出可以準(zhǔn)確的分類。

**

4、多分類LDA

**
上述是二分類LDA,對于多分類LDA常見的方式有OVO(1對1),OVR(1對其它),MvM(多對多),以及用上述公式推導(dǎo)直接求出多分類。
(1)OVO(1對1)
該方法是從訓(xùn)練數(shù)據(jù)中任意選取兩類數(shù)據(jù)去構(gòu)建分類器,(假設(shè)有N種類別)一共可以構(gòu)建N(N-1)/2個分類器,運(yùn)用這些分類器去分類測試樣本,每一個測試樣本都可以得到N(N-1)/2個結(jié)果,對每一個樣本選取結(jié)果中數(shù)量最多的結(jié)果作為最終結(jié)果。
代碼:

from collections import Counter def ones_vs_ones(x, y, X):# 一對一分類lda = BinaryClassification()count = Counter(y)# 計算有多少種類的數(shù)據(jù)label = list(count.keys())# print(label)num = len(count)# 存儲每次分類出的類別result = []for i in range(num - 1):sub_label = []sub_x = []sub_y = []for j in np.arange(i+1, num, 1):sub_label.append(label[i])sub_label.append(label[j])for index, temp in enumerate(y):if (temp == sub_label[0]) or (temp == sub_label[1]):sub_x.append(x[index])sub_y.append(temp)w, center1, center2 = lda.fit(sub_x, sub_y)result.append(lda.predict(X, w, center1, center2))result = np.array(result)# 計算最終結(jié)果re = []for i in range(X.shape[0]):re.append(max(Counter(result[:, i])))return re

用上面數(shù)據(jù)測試結(jié)果:

data = pd.read_excel("二分類數(shù)據(jù).xlsx", sheet_name=2) data1 = pd.read_excel("二分類數(shù)據(jù).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(一對其余)
一對其余是通過構(gòu)建N個分類器,來進(jìn)行分類,每一個分類器是選擇一個類別作為正類其它類別作為負(fù)類,(例如:有4種類別1,2,3,4;選擇其中2作為正類,1,3,4作為一類叫做負(fù)類),總共可以構(gòu)建N個分類器,用測試數(shù)據(jù)進(jìn)行測試時,如果測試數(shù)據(jù)中一個數(shù)據(jù)點分類為正類那么他就屬于這一類。一般情況下,每一個測試數(shù)據(jù)只有一個正類,其它全為負(fù)類,但也有時候有多個負(fù)類,這時需要計算每個分類器的置信度,選擇置信度大的正類結(jié)果作為最終結(jié)果。
代碼如下:

def ones_vs_others(x, y, X):# 一對其余,這里沒有計算分類器的置信度lda = BinaryClassification()count = Counter(y)# 計算有多少種類的數(shù)據(jù)label = list(count.keys())# 存儲每次分類出的類別result = []for i in label:sub_x = np.copy(x)sub_y = np.copy(y)for index, j in enumerate(y):if j != i:sub_y[index] = 0else:sub_y[index] = 1w, center1, center2 = lda.fit(sub_x, sub_y)result.append(lda.predict(X, w, center1, center2))result = np.array(result)re = []for i in range(X.shape[0]):for temp, j in enumerate(result[:, i]):if j == 1:re.append(label[temp])return re

用上面數(shù)據(jù)分類結(jié)果:

data = pd.read_excel("二分類數(shù)據(jù).xlsx", sheet_name=2) data1 = pd.read_excel("二分類數(shù)據(jù).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()


未完待續(xù)。。。。

總結(jié)

以上是生活随笔為你收集整理的LDA线性判别分析案例实战的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。