線形弁別関数(Pythonはバッチパーセプトロンアルゴリズム、Ho Kashyapアルゴリズム、およびMSEマルチクラス拡張メソッドを実装します)-パターン認識プログラミングの割り当て

前に書く

このブログは、バッチパーセプトロンアルゴリズム、Ho Kashyapアルゴリズム、およびMSEマルチクラス拡張メソッドを実装するパターン認識ジョブの記録です。教科書[1] \ color {#0000FF} {[1]}を参照してください[ 1 ]使用されるデータは次のとおりです。
ここに写真の説明を挿入

バッチパーセプトロンアルゴリズム

a = 0から\ mathbf a = 0A=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=3 4 0 - 3 0 4 3 4 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)

参照。

[1] Richard O.Duda。パターン分類[M]。LiHongdong他による翻訳。ChinaMachineryIndustryPress、CITIC Press、2003年。

おすすめ

転載: blog.csdn.net/liuz_notes/article/details/109528712