# -*- coding: UTF-8 -*-
import numpy as np
import pylab as pl
def draw(C): #画图函数
colValue = ['r', 'y', 'g', 'b', 'c', 'k', 'm']
for i in range(len(C)):
coo_X = []
coo_Y = []
for j in range(len(C[i])):
coo_X.append(C[i][j][0])
coo_Y.append(C[i][j][1])
pl.scatter(coo_X, coo_Y, marker='x', color=colValue[i % len(colValue)], label=i)
pl.legend(loc='upper right')
pl.show()
class myson(object):
def __init__(self, X, output, times, size):
self.X = X #输入样例
self.output = output #输出
self.times = times #迭代次数
self.size = size #数据长度
self.W = np.random.rand(X.shape[1], output[0] * output[1])
print(self.W.shape)
def reE(self, t, n):
return np.power(np.e, -n) / (t + 2)
def reN(self, t): # 返回拓扑距离
a = min(self.output)
return int(a - float(a) * t / self.times)
def nei(self, index, N): #确定获胜区域点
a, b = self.output
length = a * b
def dis(index1, index2): #计算距离
i1_a, i1_b = index1 // a, index1 % b
i2_a, i2_b = index2 // a, index2 % b
return np.abs(i1_a - i2_a), np.abs(i1_b - i2_b)
def upW(self, X, t, winner): #更新权值
N = self.reN(t)
for x, i in enumerate(winner):
to_update = self.nei(i[0], N)
for j in range(N + 1):
e = self.reE(t, j)
for w in to_update[j]:
self.W[:, w] = np.add(self.W[:, w], e * (X[x, :] - self.W[:, w]))
ans = [set() for i in range(N + 1)]
for i in range(length):
dist_a, dist_b = dis(i, index)
if dist_a <= N and dist_b <= N: ans[max(dist_a, dist_b)].add(i) #将获胜节点加入集合
return ans
def train(self): #训练函数
count = 0
while self.times > count:
train_X = self.X[np.random.choice(self.X.shape[0], self.size)]
normal_W(self.W)
normal_X(train_X)
train_Y = train_X.dot(self.W)
winner = np.argmax(train_Y, axis=1).tolist()
self.upW(train_X, count, winner)
count += 1
return self.W
def af_train(self): #返回训练结果
normal_X(self.X)
train_Y = self.X.dot(self.W)
winner = np.argmax(train_Y, axis=1).tolist()
print(winner)
return winner
def normal_X(X): #输入归一化处理
N, D = X.shape
for i in range(N):
temp = np.sum(np.multiply(X[i], X[i]))
X[i] /= np.sqrt(temp)
return X
def normal_W(W): #初始权值归一化处理
for i in range(W.shape[1]):
temp = np.sum(np.multiply(W[:, i], W[:, i]))
W[:, i] /= np.sqrt(temp)
return W
if __name__ == '__main__':
data = """1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,1,1,1,1;"""
a = data.split(',')
dataset = np.mat([[float(a[i]), float(a[i + 1]),float(a[i+2]),float(a[i+3]),] for i in range(0, len(a) - 1, 4)])
dataset_old = dataset.copy()
myson = myson(dataset, (5, 5), 1,5)
myson.train()
res = myson.af_train()
classify = {}
for i, win in enumerate(res):
if not classify.get(win[0]):
classify.setdefault(win[0], [i])
else:
classify[win[0]].append(i)
A = [] # 未归一化的数据分类结果
B = [] # 归一化的数据分类结果
for i in classify.values():
A.append(dataset_old[i].tolist())
B.append(dataset[i].tolist())
draw(A) #未归一化画出的图
draw(B) #归一化之后画出的图