线性判别函数(Python实现批感知器算法、Ho Kashyap算法和MSE多类扩展方法)——模式识别编程作业

   日期:2020-11-16     浏览:102    评论:0    
核心提示:本博客为模式识别作业的记录,Python实现批感知器算法、Ho Kashyap算法和MSE多类扩展方法

文章目录

  • 写在前面
  • 批感知器算法
  • Ho Kashyap算法
  • MSE多类扩展方法
  • Ref.

写在前面

本博客为模式识别作业的记录,实现批感知器算法、Ho Kashyap算法和MSE多类扩展方法,可参考教材 [ 1 ] \color{#0000FF}{[1]} [1]。所用数据如下如所示:

批感知器算法

a = 0 \mathbf a=0 a=0开始迭代,分类 ω 1 \omega_1 ω1 ω 2 \omega_2 ω2并计算最终的解向量,记录下收敛的步数。

"""批感知器算法"""

import matplotlib.pyplot as plt
import numpy as np
import math

data = np.loadtxt('data.txt')
trn_data1 = data[0:20, 0:2]   # 问题一(1)
trn_lable1 = data[0:20, 2]

# trn_data1 = data[10:30, 0:2] # 问题一(1)
# trn_lable1 = data[10:30, 2]

plt.scatter(trn_data1[0:10, 0], trn_data1[0:10, 1], color='blue', marker='o', label=''r'$\omega_1$')
plt.scatter(trn_data1[10:20, 0], trn_data1[10:20, 1], color='red', marker='x', label=''r'$\omega_2$')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.legend(loc='upper left')
plt.title('Original Data')
plt.show()

X = np.hstack((np.ones((trn_data1.shape[0], 1)), trn_data1))

X1 = X[0:10, :]
X2 = -1 * X[10:20, :]
X = np.vstack((X1, X2))   # 规范化增广样本
w = np.zeros((3, 1), dtype='float32')


step = 0
for i in range(100):
    if i == 0:
        y_pred = np.where(np.dot(X, w) == 0)[0]  # 统计分类错误的点数
    else:
        y_pred = np.where(np.dot(X, w) < 0)[0]
    step += 1
    print('第%2d次更新,分类错误的点个数:%2d' % (step, len(y_pred)))
    if len(y_pred) > 0:
        w += (np.sum(X[y_pred, :], axis=0)).reshape((3, 1))
    else:
        break

print('解向量为:', w)
x1 = np.array([-5, 8])
x2 = -1 * (w[1]*x1 + w[0])/w[2]

plt.scatter(trn_data1[0:10, 0], trn_data1[0:10, 1], color='blue', marker='o', label=''r'$\omega_1$')
plt.scatter(trn_data1[10:20, 0], trn_data1[10:20, 1], color='red', marker='x', label=''r'$\omega_2$')
plt.plot([x1[0], x1[1]], [x2[0], x2[1]], 'black')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.legend(loc='upper left')
plt.title('classified Data')
plt.show()

算法在第24次更新收敛,此时解向量 a = ( 34.0 , − 30.4 , 34.1 ) \mathbf{a} = (34.0,−30.4, 34.1) a=(34.0,30.4,34.1)

Ho Kashyap算法

"""Ho Kashyap算法"""

import matplotlib.pyplot as plt
import numpy as np
import math

data = np.loadtxt('data.txt')
trn_data1 = data[0:10, 0:2]   # 问题二(1)
trn_lable1 = data[0:10, 2]
temp = data[20:30, 0:2]
temp_lb = data[20:30, 2]

# trn_data1 = data[10:20, 0:2] # 问题二(2)
# trn_lable1 = data[10:20, 2]
# temp = data[30:40, 0:2]
# temp_lb = data[30:40, 2]

trn_data = np.vstack((trn_data1, temp))
trn_lable = np.vstack((trn_lable1, temp_lb))

# print(trn_data.shape, '\n', trn_lable.shape)
# print(trn_data)

plt.scatter(trn_data[0:10, 0], trn_data[0:10, 1], color='blue', marker='o', label=''r'$\omega_2$')
plt.scatter(trn_data[10:20, 0], trn_data[10:20, 1], color='red', marker='x', label=''r'$\omega_4$')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.legend(loc='upper left')
plt.title('Original Data')
plt.show()

X = np.hstack((np.ones((trn_data.shape[0], 1)), trn_data))
X1 = X[0:10, :]
X2 = -1 * X[10:20, :]
X = np.vstack((X1, X2))   # 规范化增广样本
w = np.random.randn(3, 1)
b = np.random.rand(X.shape[0], 1)
eta = 0.1
MAX_iteration = 1000

step = 0
acc = 0
for i in range(MAX_iteration):
    e = np.dot(X, w) - b
    e_p = 0.5 * (e + abs(e))
    eta_k = eta/(i+1)
    # if (e == 0).all():
    if max(abs(e)) <= min(b):
        print(e)
        break
    else:
        b += 2 * eta_k * e_p
        Y_p = np.linalg.pinv(X)
        w = np.dot(Y_p, b)
    step += 1
    acc = (np.sum(np.dot(X, w) > 0)) / X.shape[0]
    print('第%2d次更新, 分类准确率%f' % (step, acc))
    # print(e, '\n')
    if step == MAX_iteration and acc != 1:
        print("未找到解,线性不可分!")


x1 = np.array([-8, 8])
x2 = -1 * (w[1]*x1 + w[0])/w[2]
plt.scatter(trn_data[0:10, 0], trn_data[0:10, 1], color='blue', marker='o', label=''r'$\omega_2$')
plt.scatter(trn_data[10:20, 0], trn_data[10:20, 1], color='red', marker='x', label=''r'$\omega_4$')
plt.plot([x1[0], x1[1]], [x2[0], x2[1]], 'black')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.text(3, -2, 'Accuracy: %.3f' % acc)
plt.legend(loc='upper left')
plt.title('classified Data')
plt.show()

MSE多类扩展方法

首先根据训练样本计算出权值W,然后根据此权值和测试样本计算出预测值,并对该值取argmax 得到最终的输出标签,从而得到分类正确率为100%。

"""MSE多类扩展方法"""

import numpy as np

data = np.loadtxt('data.txt')
train_data = []
train_label = []
test_data = []
test_label = []

# 数据预处理
for i in [0, 10, 20, 30]:
    temp_data = data[i:i+8, 0:2]
    temp_label = data[i:i+8, 2]
    train_data.append(temp_data)
    train_label.append(temp_label)
    test_data.append(data[i+8:i+10, 0:2])
    test_label.append(data[i+8:i+10, 2])

train_data = np.array(train_data).reshape((32, 2))
train_label = np.array(train_label).reshape(-1).astype(int) - 1
test_data = np.array(test_data).reshape((8, 2))
test_label = np.array(test_label).reshape(-1).astype(int) - 1

train_label = np.eye(4)[train_label]      # 32x4大小,one-hot向量矩阵
test_label = np.eye(4)[test_label]        # 8x4大小


train_data = np.hstack((train_data, np.ones((train_data.shape[0], 1))))
test_data = np.hstack((test_data, np.ones((test_data.shape[0], 1))))

print(train_data.shape, train_label.shape)
print(test_data.shape, test_label.shape)

train_data = train_data.T     # 按照课件的公式调整数据维度
train_label = train_label.T
test_data = test_data.T
test_label = test_label.T

print(train_data.shape, train_label.shape)
print(test_data.shape, test_label.shape)

lam = 1e-9
temp = np.linalg.inv(np.dot(train_data, train_data.T) + lam)
W = np.dot(np.dot(temp, train_data), train_label.T)   # 3x4维

y_pred = np.dot(W.T, test_data)
index = np.argmax(y_pred, axis=0)   # 得到每个样本对应类别的值最大的索引
y_pred = np.eye(y_pred.shape[0])[index].T   # 转换为one-hot向量

wrong_num = sum(sum(y_pred - test_label))
acc = (1 - wrong_num / len(test_label)) * 100
print('分类正确率为:%.2f%% ' % acc)

Ref.

[1]Richard O. Duda. 模式分类[M]. 李宏东等译. 机械工业出版社 中信出版社, 2003.

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服