注:博客中的样本表示 都是一列,不是一行
实验代码:
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 17 19:50:39 2019
@author: LCCFM
"""
# -*- coding: utf-8 -*-
# 二分类问题 w1 w2
import math
import numpy as np
import matplotlib.pyplot as plt
def fisher(w1, w2):
#将行向量转置为列向量
w1=w1.T
w2=w2.T
sz1 = np.size(w1,1)
sz2 = np.size(w2,1)
# 1.求wi均值
m1 = np.mean(w1, axis=1)
m2 = np.mean(w2, axis=1)
# 2.计算样本内离散度 Si 和总类内离散度矩阵 Sw
s1 = np.zeros((w1.shape[0],w1.shape[0]))
n, m = w1.shape
for i in range(m):
tmp = w1[:,i] - m1
s1 = s1 + tmp * tmp.T
s2 = np.zeros((w2.shape[0],w2.shape[0]))
n, m = w2.shape
for i in range(m):
tmp = w2[:,i] - m2
s2 = s2 + tmp * tmp.T
sw = (sz1*s1 + sz2*s2)/(sz1+sz2)
# 3.计算样本间离散度 sb
sb = (m1 - m2) * (m1 - m2).T
# 4.计算w_star
w_star = np.linalg.inv(sw) * (m1-m2)
res1=0
for i in range(sz1):
res1 = res1 + w1[:,i].T*w_star
res1/=sz1
res2=0
for i in range(sz2):
res2 = res2 +w2[:,i].T*w_star
res2/=sz2
'''
# 4.另外一种计算 w_star的方式,
#求sw^(-1)*sb 的特征值,特征向量
t = np.linalg.inv(sw)*sb
v, Q = np.linalg.eig(t)
#找到最大特征值对应的特征向量
res_pos = v.argmax(axis=0)
w_star2 = Q[:,res_pos]
#计算 sw^(-1/2)
v2,Q2 =np.linalg.eig(sw)
v_half=np.zeros((v2.size,v2.size))
for i in range(v2.size):
v_half[i][i]=math.sqrt(v2[i])
sw_half=Q2 * v_half*(Q2**(-1))
#最后的结果为 sw^(-1/2)*w_star
sw_half=sw_half**(-1)
w_star2=sw_half*w_star2
res1=0
for i in range(sz1):
res1 = res1 + w1[:,i].T*w_star2
res1/=sz1
res2=0
for i in range(sz2):
res2 = res2 +w2[:,i].T*w_star2
res2/=sz2
'''
return -(res1*sz1+res2*sz2)/(sz1+sz2), w_star
def get_res(X, w0 ,w_star):
res = X * w_star + w0
if res >=0:
print('合格')
else:
print('不合格')
def get_line(w, w0):
# 换两类之间的分界线
w = np.array(w)
x = np.linspace(1, 5, 50)
y = -w[0,0]*x/w[1,0]-w0/w[1,0]
y=y.reshape(-1,1)#将行向量转置
return x, np.array(y)
def show_fig(w):
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(np.array(w1[:,0]), np.array(w1[:,1]),c='r')
ax1.scatter(np.array(w2[:,0]), np.array(w2[:,1]),c='y')
ax1.plot(wx,wy)
ax1.scatter(np.array(w[0,0]), np.array(w[0,1]),c='b')
plt.show()
if __name__ == '__main__':
w1 = np.mat([[2.95, 6.63], [2.53, 7.79], [3.57, 5.65],[3.16,5.47]])
w2 = np.mat([[2.58, 4.46], [2.16, 6.22], [3.27, 3.52]])
w0,w_star=fisher(w1, w2)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.scatter(np.array(w1[:,0]), np.array(w1[:,1]),c='r')
ax1.scatter(np.array(w2[:,0]), np.array(w2[:,1]),c='y')
wx,wy=get_line(w_star, w0)
#显示分类情况
ax1.plot(wx,wy)
plt.show()
#输入样例
while True:
n1,n2= map(float,input().split())
#print(n1,n2)
w=np.mat([n1,n2])
show_fig(w)
get_res(w,np.array(w0),w_star)
性判别
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 18 17:01:50 2019
@author: LCCFM
"""
import os
import cv2 #导入opencv库
import numpy as np
def get_w(file_path):
#读取文件夹下所有文件
#print(file_path)
#创建一个空矩阵
train_set = np.zeros(shape=[1,32*32])
for filename in os.listdir(file_path): #listdir的参数是文件夹的路径
#print (filename) #此时的filename是文件夹中文件的名称
img = cv2.imread(file_path+'/'+filename,cv2.IMREAD_GRAYSCALE) #读取图片,第二个参数表示以灰度图像读入
#res= cv2.resize(img,(28,28)) #对图片进行缩放,第一个参数是读入的图片,第二个是制定的缩放大小
#cv2.imshow('img',img)
#cv2.waitKey(0)
res=img
sp = img.shape
#print(sp)
res_1 = res.reshape(1,sp[0]*sp[1]) #将表示图片的二维矩阵转换成一维
res_2= res_1.tolist() #将numpy.narray类型的矩阵转换成list
#train_set.append(res_2) #将list添加到已有的list中
train_set=np.row_stack((train_set,res_2))
#print(train_set)
return train_set
'''
def get_res(w,res1,res2,w_star):
#print(res1-w.T*w_star,res2-w.T*w_star)
if abs(res1-w.T*w_star)<abs(res2-w.T*w_star):
print('第一个人')
else:
print('第二个人')
'''
def get_res(X, w0 ,w_star):
res = X * w_star + w0
if res >=0:
print('第一个人')
else:
print('第二个人')
def fisher(w1, w2):
#将行向量转置为列向量
w1=w1.T
w2=w2.T
sz1 = np.size(w1,1)
sz2 = np.size(w2,1)
# 1.求wi均值
m1 = np.mean(w1, axis=1)
m2 = np.mean(w2, axis=1)
# 2.计算样本内离散度 Si 和总类内离散度矩阵 Sw
s1 = np.zeros((w1.shape[0],w1.shape[0]))
n, m = w1.shape
for i in range(m):
tmp = w1[:,i] - m1
s1 = s1 + tmp * tmp.T
s2 = np.zeros((w2.shape[0],w2.shape[0]))
n, m = w2.shape
for i in range(m):
tmp = w2[:,i] - m2
s2 = s2 + tmp * tmp.T
sw = (sz1*s1 + sz2*s2)/(sz1+sz2)
# 3.计算样本间离散度 sb
sb = (m1 - m2) * (m1 - m2).T
# 4.计算w_star
w_star = np.linalg.inv(sw) * (m1-m2)
res1=0
for i in range(sz1):
res1 = res1 + w1[:,i].T*w_star
res1/=sz1
res2=0
for i in range(sz2):
res2 = res2 +w2[:,i].T*w_star
res2/=sz2
'''
# 4.另外一种计算 w_star的方式,
#求sw^(-1)*sb 的特征值,特征向量
t = np.linalg.inv(sw)*sb
v, Q = np.linalg.eig(t)
#找到最大特征值对应的特征向量
res_pos = v.argmax(axis=0)
w_star2 = Q[:,res_pos]
#计算 sw^(-1/2)
v2,Q2 =np.linalg.eig(sw)
v_half=np.zeros((v2.size,v2.size))
for i in range(v2.size):
v_half[i][i]=math.sqrt(v2[i])
sw_half=Q2 * v_half*(Q2**(-1))
#最后的结果为 sw^(-1/2)*w_star
sw_half=sw_half**(-1)
w_star2=sw_half*w_star2
res1=0
for i in range(sz1):
res1 = res1 + w1[:,i].T*w_star2
res1/=sz1
res2=0
for i in range(sz2):
res2 = res2 +w2[:,i].T*w_star2
res2/=sz2
'''
return -(res1*sz1+res2*sz2)/(sz1+sz2), w_star
if __name__ == '__main__':
#D:\学习\大三\AI\expriment\Two\2\Train
w1 = get_w(r'D:/STUDY/Three/AI/expriment/Two/2/Train/1')
w2 = get_w(r'D:/STUDY/Three/AI/expriment/Two/2/Train/2')
w1 = np.delete(w1,1,axis=0)
w2 = np.delete(w2,1,axis=0)
w0, w_star=fisher(np.mat(w1), np.mat(w2))
file_path='./Test'
for filename in os.listdir(file_path): #listdir的参数是文件夹的路径
print (filename) #此时的filename是文件夹中文件的名称
img = cv2.imread(file_path+'/'+filename,cv2.IMREAD_GRAYSCALE) #读取图片,第二个参数表示以灰度图像读入
#res= cv2.resize(img,(28,28)) #对图片进行缩放,第一个参数是读入的图片,第二个是制定的缩放大小
res=img
sp =img.shape
res_1 = res.reshape(1,sp[0]*sp[1]) #将表示图片的二维矩阵转换成一维
res_2= res_1.tolist() #将numpy.narray类型的矩阵转换成list
get_res(np.mat(res_2), w0 ,w_star)