• xiaohanqinyue
    了解作者
  • Python
    开发工具
  • 2KB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • 10 积分
    下载积分
  • 2
    下载次数
  • 2020-04-30 15:52
    上传日期
用python实现了SOM(自组织映射)算法
python实现SOM算法.zip
  • python实现SOM算法
  • SOM2.py
    5.6KB
内容介绍
import numpy as np import math #import copy from matplotlib import pyplot as plt #用该代码,代码已读懂 #初始化输入层与竞争层神经元的连接权值矩阵 def initCompetition(n , m , d): #随机产生0-1之间的数作为权值 array = np.random.random(size=n * m *d) com_weight = array.reshape(n,m,d) return com_weight def initCompetition2(n , m , d): #随机产生0-1之间的数作为权值 array = np.random.random(size=n * m *d) com_weight = array.reshape(n,m,d) return com_weight #计算向量的二范数 def cal2NF(X): res = 0 for x in X: res += x*x return res ** 0.5 #对数据集进行归一化处理 def normalize(dataSet): old_dataSet = dataSet.copy() for data in dataSet: two_NF = cal2NF(data) for i in range(len(data)): data[i] = data[i] / two_NF return dataSet , old_dataSet #对权值矩阵进行归一化处理 def normalize_weight(com_weight): for x in com_weight: for data in x: two_NF = cal2NF(data) for i in range(len(data)): data[i] = data[i] / two_NF return com_weight #得到获胜神经元的索引值 def getWinner(data , com_weight): max_sim = 0 n,m,d = np.shape(com_weight) mark_n = 0 mark_m = 0 for i in range(n): for j in range(m): if sum(data * com_weight[i,j]) > max_sim: max_sim = sum(data * com_weight[i,j]) mark_n = i mark_m = j return mark_n , mark_m #得到神经元的N邻域 def getNeibor(n , m , N_neibor , com_weight): #n,m:获胜神经元的坐标 res = [] #存放优胜邻域内的输出神经元和与获胜神经元的距离 nn,mm , _ = np.shape(com_weight) for i in range(nn): for j in range(mm): N = int(((i-n)**2+(j-m)**2)**0.5) #N:输出神经元与获胜神经元的距离,即拓扑距离 if N<=N_neibor: res.append((i,j,N)) return res #学习率函数 def eta(t,N): #N:拓扑距离 return (0.8/(t+1))* (math.e ** -N) def learnfun(t,T): return 0.8*np.exp(-t/T) #SOM算法的实现 #N_neibor:初始邻域 #返回res={key:[val1,val2,val3,...]} key:获胜神经元 val:属于该获胜神经元的输入向量 def do_som(dataSet , com_weight, T , N_neibor0): ''' T:最大迭代次数 N_neibor:初始近邻数(初始优胜邻域),随训练时间逐渐收缩 ''' N_neibor = N_neibor0 for t in range(T-1): com_weight = normalize_weight(com_weight) for data in dataSet: n , m = getWinner(data , com_weight) neibor = getNeibor(n , m , N_neibor , com_weight) for x in neibor: j_n=x[0];j_m=x[1];N=x[2] #x[0]x[1]:优胜领域内输出神经元的坐标,x[2]:优胜领域内输出神经元与获胜神经元的距离(看一下getNeibor函数的返回值) #权值调整 # com_weight[j_n][j_m] = com_weight[j_n][j_m] + eta(t,N)*(data - com_weight[j_n][j_m]) com_weight[j_n][j_m] = com_weight[j_n][j_m] + learnfun(t,T)*np.exp(-N*N/(2*N_neibor*N_neibor))*(data - com_weight[j_n][j_m]) # N_neibor = N_neibor+1-(t+1)/200 #拓扑邻域N_neibor随时间增大距离变小 N_neibor = N_neibor0 * np.exp(-t/T) res = {} N,M, _ =np.shape(com_weight) for i in range(len(dataSet)): n, m = getWinner(dataSet[i], com_weight) key = n*M + m #if res.has_key(key): #字典的函数 if key in res: #修改后的,因为python3.x删除了has_key res[key].append(i) else: res[key] = [] #此处res[key]的值是一个[],key包含了获胜神经元的信息,v是映射到该获胜神经元的所有输入神经元形成的[] res[key].append(i) return res #如何获得聚类中心??? #SOM算法主方法 def SOM(dataSet,com_n,com_m,T,N_neibor): #N_neibor:初始邻域 dataSet, old_dataSet = normalize(dataSet) com_weight = initCompetition(com_n,com_m,np.shape(dataSet)[1]) M=com_weight.shape[1] print('初始权向量:','\n',com_weight) C_res = do_som(dataSet, com_weight, T, N_neibor) centroids=[] for key in C_res: n=int(key/M) m=key%M centroids.append(com_weight[n][m]) print(key,':',C_res[key]) centroids=np.array(centroids) # centroids=normalize(centroids) print('SOM算法产生的聚类中心为:\n',centroids) return centroids # draw(C_res, dataSet) # draw(C_res, old_dataSet) def draw(C , dataSet): color = ['r', 'y', 'g', 'b', 'c', 'k', 'm' , 'd'] count = 0 for i in C.keys(): X = [] Y = [] datas = C[i] for j in range(len(datas)): X.append(dataSet[datas[j]][0]) Y.append(dataSet[datas[j]][1]) plt.scatter(X, Y, marker='o', color=color[count % len(color)], label=i) count += 1 plt.legend(loc='upper right') plt.show() def loadDataSet(fileName): dataMat = [] fr = open(fileName) for line in fr.readlines(): curLine = line.strip().split(' ') fltLine =list( map(float,curLine)) dataMat.append(fltLine) return dataMat if __name__ == '__main__': X = loadDataSet('data_bak.txt'); X = np.array(X) centroids=SOM(X,8,8,4,3) # print('centroids:\n',centroids) print(centroids.shape) # dataSet = loadDataSet("data") # SOM(dataSet,2,2,300,1.5)
评论
    相关推荐