python代碼完成Fisher判別

一.算法描述

Fisher線性判別分析的基本思想:選擇一個投影方向(線性變換,線性組合),將高維問題降低到一維問題來解決,同時變換後的一維數據滿足每一類內部的樣本儘可能聚集在一起,不同類的樣本相隔儘可能地遠。
Fisher線性判別分析,就是通過給定的訓練數據,確定投影方向W和閾值w0, 即確定線性判別函數,然後根據這個線性判別函數,對測試數據進行測試,得到測試數據的類別。
線性判別函數的一般形式可表示成 :
在這裏插入圖片描述
其中
在這裏插入圖片描述
Fisher選擇投影方向W的原則,即使原樣本向量在該方向上的投影能兼顧類間分佈儘可能分開,類內樣本投影儘可能密集的要求。 如下爲具體步驟:

(1)W的確定

各類樣本均值向量mi
在這裏插入圖片描述
樣本類內離散度矩陣 和總類內離散度矩陣
在這裏插入圖片描述
樣本類間離散度矩陣
在這裏插入圖片描述
在投影后的一維空間中,各類樣本均值
在這裏插入圖片描述
樣本類內離散度和總類內離散度
在這裏插入圖片描述
樣本類間離散度
在這裏插入圖片描述
Fisher準則函數爲
在這裏插入圖片描述

(2)閾值的確定

是個常數,稱爲閾值權,對於兩類問題的線性分類器可以採用下屬決策規則:
令 則:
在這裏插入圖片描述

如果g(x)>0,則決策x屬於w1 ;如果g(x)<0,則x屬於w2 ;如果g(x)=0,則可將x任意分到某一類,或拒絕。

(3)Fisher線性判別的決策規則

Fisher準則函數滿足兩個性質:
1.投影后,各類樣本內部儘可能密集,即總類內離散度越小越好。
2.投影后,各類樣本儘可能離得遠,即樣本類間離散度越大越好。
根據這個性質確定準則函數,根據使準則函數取得最大值,可求出
在這裏插入圖片描述

這就是Fisher判別準則下的最優投影方向。
最後得到決策規則

在這裏插入圖片描述

在這裏插入圖片描述

對於某一個未知類別的樣本向量x,如果y=WT·x>y0,則x∈w1;否則x∈w2。

二.數據描述

1.iris數據

IRIS數據集以鳶尾花的特徵作爲數據來源,數據集包含150個數據集,有4維,分爲3 類,每類50個數據,每個數據包含4個屬性,是在數據挖掘、數據分類中非常常用的測試集、訓練集。

2.sonar數據

Sonar數據集包含208個數據集,有60維,分爲2類,第一類爲98個數據,第二類爲110個數據,每個數據包含60個屬性,是在數據挖掘、數據分類中非常常用的測試集、訓練集。

“羣內離散度”要求的是距離越遠越好;而“羣間離散度”的距離越近越好

三.鳶尾花數據集例子

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 
import seaborn as sns
path=r'Iris.csv'
df = pd.read_csv(path, header=0)
Iris1=df.values[0:50,0:4]
Iris2=df.values[50:100,0:4]
Iris3=df.values[100:150,0:4]
m1=np.mean(Iris1,axis=0)
m2=np.mean(Iris2,axis=0)
m3=np.mean(Iris3,axis=0)
s1=np.zeros((4,4))
s2=np.zeros((4,4))
s3=np.zeros((4,4))
for i in range(0,30,1):
    a=Iris1[i,:]-m1
    a=np.array([a])
    b=a.T
    s1=s1+np.dot(b,a)    
for i in range(0,30,1):
    c=Iris2[i,:]-m2
    c=np.array([c])
    d=c.T
    s2=s2+np.dot(d,c) 
    #s2=s2+np.dot((Iris2[i,:]-m2).T,(Iris2[i,:]-m2))
for i in range(0,30,1):
    a=Iris3[i,:]-m3
    a=np.array([a])
    b=a.T
    s3=s3+np.dot(b,a) 
sw12=s1+s2
sw13=s1+s3
sw23=s2+s3
#投影方向
a=np.array([m1-m2])
sw12=np.array(sw12,dtype='float')
sw13=np.array(sw13,dtype='float')
sw23=np.array(sw23,dtype='float')
#判別函數以及T
#需要先將m1-m2轉化成矩陣才能進行求其轉置矩陣
a=m1-m2
a=np.array([a])
a=a.T
b=m1-m3
b=np.array([b])
b=b.T
c=m2-m3
c=np.array([c])
c=c.T
w12=(np.dot(np.linalg.inv(sw12),a)).T
w13=(np.dot(np.linalg.inv(sw13),b)).T
w23=(np.dot(np.linalg.inv(sw23),c)).T
#print(m1+m2) #1x4維度  invsw12 4x4維度  m1-m2 4x1維度
T12=-0.5*(np.dot(np.dot((m1+m2),np.linalg.inv(sw12)),a))
T13=-0.5*(np.dot(np.dot((m1+m3),np.linalg.inv(sw13)),b))
T23=-0.5*(np.dot(np.dot((m2+m3),np.linalg.inv(sw23)),c))
kind1=0
kind2=0
kind3=0
newiris1=[]
newiris2=[]
newiris3=[]
for i in range(30,49):
    x=Iris1[i,:]
    x=np.array([x])
    g12=np.dot(w12,x.T)+T12
    g13=np.dot(w13,x.T)+T13
    g23=np.dot(w23,x.T)+T23
    if g12>0 and g13>0:
        newiris1.extend(x)
        kind1=kind1+1
    elif g12<0 and g23>0:
        newiris2.extend(x)
    elif g13<0 and g23<0 :
        newiris3.extend(x)
#print(newiris1)
for i in range(30,49):
    x=Iris2[i,:]
    x=np.array([x])
    g12=np.dot(w12,x.T)+T12
    g13=np.dot(w13,x.T)+T13
    g23=np.dot(w23,x.T)+T23
    if g12>0 and g13>0:
        newiris1.extend(x)
    elif g12<0 and g23>0:
       
        newiris2.extend(x)
        kind2=kind2+1
    elif g13<0 and g23<0 :
        newiris3.extend(x)
for i in range(30,50):
    x=Iris3[i,:]
    x=np.array([x])
    g12=np.dot(w12,x.T)+T12
    g13=np.dot(w13,x.T)+T13
    g23=np.dot(w23,x.T)+T23
    if g12>0 and g13>0:
        newiris1.extend(x)
    elif g12<0 and g23>0:     
        newiris2.extend(x)
    elif g13<0 and g23<0 :
        newiris3.extend(x)
        kind3=kind3+1
correct=(kind1+kind2+kind3)/60
print("樣本類內離散度矩陣S1:",s1,'\n')
print("樣本類內離散度矩陣S2:",s2,'\n')
print("樣本類內離散度矩陣S3:",s3,'\n')
print('-----------------------------------------------------------------------------------------------')
print("總體類內離散度矩陣Sw12:",sw12,'\n')
print("總體類內離散度矩陣Sw13:",sw13,'\n')
print("總體類內離散度矩陣Sw23:",sw23,'\n')
print('-----------------------------------------------------------------------------------------------')
print('判斷出來的綜合正確率:',correct*100,'%')

四.python代碼推導

1.數據生成

scikit-learn的接口來生成數據:

from sklearn.datasets import make_multilabel_classification
import numpy as np

x, y = make_multilabel_classification(n_samples=20, n_features=2,
                                      n_labels=1, n_classes=1,
                                      random_state=2)  # 設置隨機數種子,保證每次產生相同的數據。

# 根據類別分個類
index1 = np.array([index for (index, value) in enumerate(y) if value == 0])  # 獲取類別1的indexs
index2 = np.array([index for (index, value) in enumerate(y) if value == 1])  # 獲取類別2的indexs

c_1 = x[index1]   # 類別1的所有數據(x1, x2) in X_1
c_2 = x[index2]  # 類別2的所有數據(x1, x2) in X_2

2.fisher算法實現

def cal_cov_and_avg(samples):
    u1 = np.mean(samples, axis=0)
    cov_m = np.zeros((samples.shape[1], samples.shape[1]))
    for s in samples:
        t = s - u1
        cov_m += t * t.reshape(2, 1)
    return cov_m, u1
def fisher(c_1, c_2):
    cov_1, u1 = cal_cov_and_avg(c_1)
    cov_2, u2 = cal_cov_and_avg(c_2)
    s_w = cov_1 + cov_2
    u, s, v = np.linalg.svd(s_w)  # 奇異值分解
    s_w_inv = np.dot(np.dot(v.T, np.linalg.inv(np.diag(s))), u.T)
    return np.dot(s_w_inv, u1 - u2)

3.判定類別

def judge(sample, w, c_1, c_2):
    u1 = np.mean(c_1, axis=0)
    u2 = np.mean(c_2, axis=0)
    center_1 = np.dot(w.T, u1)
    center_2 = np.dot(w.T, u2)
    pos = np.dot(w.T, sample)
    return abs(pos - center_1) < abs(pos - center_2)
w = fisher(c_1, c_2)  # 調用函數,得到參數w
out = judge(c_1[1], w, c_1, c_2)   # 判斷所屬的類別
print(out)

4.繪圖

在jupyter下面繪製需要添加以下代碼:

%matplotlib inline

這樣才能在當前的jupyter下顯示出圖片

import matplotlib.pyplot as plt
%matplotlib inline
plt.scatter(c_1[:, 0], c_1[:, 1], c='#99CC99')
plt.scatter(c_2[:, 0], c_2[:, 1], c='#FFCC00')
line_x = np.arange(min(np.min(c_1[:, 0]), np.min(c_2[:, 0])),
                   max(np.max(c_1[:, 0]), np.max(c_2[:, 0])),
                   step=1)

line_y = - (w[0] * line_x) / w[1]
plt.plot(line_x, line_y)
plt.show()

運行結果:
在這裏插入圖片描述

五.理解和心得

Fisher判別法是判別分析的方法之一。Fisher判別法是一種投影方法,把高維空間的點向低維空間投影。在原來的座標系下,可能很難把樣品分開,而投影后可能區別明顯。一般說,可以先投影到一維空間(直線)上,如果效果不理想,在投影到另一條直線上(從而構成二維空間),依此類推。每個投影可以建立一個判別函數。

六.參考鏈接

沒有顯示圖片問題解決方案
fisher判別分析原理+python實現
波波
個人博客鏈接

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