Fisher线性判别分析Fisher Linear Distrimination

Fisher线性判别分析是一种线性分类方法,它的主要思想是:是类内的方差小,类均值之间相差比较大。(类间大,类内小)

以两个类的分类为例:

将两个类由在x1,x2上投影到向量u 上,这样由二维转到了一维,然后将两类从两团点的中间分开。

如果要使类间相差大的话,那么每个类的平均数之间也会相差大,设\mu_1,\mu_2分别为加号点和减号点的平均值,那么投影后,他们距离的平方,也就是||\mu_1^T\mu-\mu_2^T\mu||^2尽可能大。

如果要使类内方差小的话,那么两个类投影到直线(向量)上后,他们的点分别为\mu^T\Sigma_1\mu,\mu^T\Sigma_2\mu,表示两个协方差的投影。

\Sigma_1=( x-\mu_1)(x-\mu_1)^T

\Sigma_2=( x-\mu_2)( x-\mu_2)^T

所以他们的和也要尽可能小\mu^T\Sigma_1\mu+\mu^T\Sigma_2\mu

因此把大的作为分子,小的作为分母,他们相除的整体就是越大越好,

                             Lossfunction:J(\mu) = \frac{\mu^T(\mu_1-\mu_2)(\mu_1-\mu_2)^T\mu}{ \mu^T \Sigma_1 \mu+ \mu^T \Sigma_2 \mu }

                                           设     S_B=(\mu_1-\mu_2)(\mu_1-\mu_2)^T 

                                                      S_W=\Sigma_1^2+\Sigma_2^2

                                           则      J(\mu)=\frac{ \mu^TS_B\mu }{\mu^TS_W\mu}

对J(u)进行求导,则有\frac{ \2 S_B\mu(\mu^TS_w\mu)-2 S_W\mu(\mu^TS_B\mu) }{(\mu S_W \mu)^2}

令导数等于0,      得到          S_B\mu = (\frac{\mu^TS_B\mu}{u^TS_W\mu})S_W\mu

括号里的可以用一个缩放值来代替

则                             \mu = \alpha S_W^{-1}S_B\mu=\alpha S_W^{-1}(\mu_1-\mu_2)(\mu_1-\mu_2)^T\mu

因为(\mu_1-\mu_2)^T\mu在相乘之后变为常数

因此最终                                       \mu = \beta S_W^{-1}(\mu_1-\mu_2)

就是我们要投影的向量。

import matplotlib.pyplot as plt
import numpy as np

def gauss2D(x, m, C):
  Ci = np.linalg.inv(C)  #求矩阵的逆
  dC = np.linalg.det(C)  #求矩阵的行列式
  num = np.exp(-0.5 * np.dot((x-m).T, np.dot(Ci,(x-m))))
  den = 2 * np.pi * (dC**0.5) #计算矩阵的密度函数

  return num/den

def twoDGaussianPlot(nx, ny, m, C):
  x = np.linspace(-6, 6, nx)
  y = np.linspace(-6, 6, ny)
  X, Y = np.meshgrid(x, y, indexing='ij')

  Z = np.zeros([nx,ny])
  for i in range(nx):
    for j in range(ny):
      xvec = np.array([X[i,j], Y[i,j]])
      Z[i,j] = gauss2D(xvec, m, C)
  
  return X, Y, Z

X = np.random.randn(200, 2)
C1 = np.array([[2,1],[1,2]])
C2 = np.array([[2,1],[1,2]])
m1 = np.array([0, 3])
m2 = np.array([3,2.5])
A = np.linalg.cholesky(C1)

Y1 = X @ A.T + m1
Y2 = X @ A.T + m2

plt.figure(1)
plt.scatter(Y1[:,0], Y1[:,1], c='c', s=4)
plt.scatter(Y2[:,0], Y2[:,1], c='m', s=4)

Xp, Yp, Zp = twoDGaussianPlot(40,50,m1,C1)
plt.contour(Xp, Yp, Zp, 5)

Xp2, Yp2, Zp2 = twoDGaussianPlot(40,50,m2,C2)
plt.contour(Xp2, Yp2, Zp2, 5)

uF = np.linalg.inv(C1 + C2)@(m1-m2)
print(uF)
#ax.arrow(0, 0, *(uF*10), color='b', linewidth=2.0, head_width=0.20, head_length=0.25)
plt.arrow(0, 0, *(uF), color='b', linewidth=2.0, head_width=0.30, head_length=0.35)

plt.axis('equal')
plt.grid()
plt.xlim([-6,6])
plt.ylim([-5,8])

plt.savefig('density graph.png')

yp1 = Y1 @ uF
yp2 = Y2 @ uF

plt.figure(2)
plt.rcParams.update({'font.size':16})
plt.hist(yp1, bins=40)
plt.hist(yp2, bins=40)
plt.savefig('histogramprojections.png')

猜你喜欢

转载自blog.csdn.net/qq_39696563/article/details/122550278
今日推荐