📜  自组织地图– Kohonen地图

📅  最后修改于: 2021-04-17 02:54:38             🧑  作者: Mango

自组织映射(或Kohonen映射或SOM)是一种人工神经网络,它也受到1970年代的神经系统生物学模型的启发。它遵循无监督的学习方法,并通过竞争性学习算法训练了其网络。 SOM用于聚类和映射(或降维)技术,以将多维数据映射到低维,这使人们可以减少复杂的问题,以便于解释。 SOM有两层,一层是输入层,另一层是输出层。下面给出了具有两个群集和任意样本的n个输入要素的自组织图的体系结构:

SOM如何工作?

假设输入数据的大小为(m,n),其中m是训练示例的数量,n是每个示例中的特征数量。首先,它初始化大小(n,C)的权重,其中C是簇数。然后遍历输入数据,对于每个训练示例,它更新获胜向量(距训练示例最短距离(例如,欧几里得距离)的权重向量)。权重更新规则由给出:

wij = wij(old) - alpha(t) *  (xik - wij(old))

其中alpha是时间t的学习率,j表示获胜矢量,i表示训练示例的第i个特征,k表示输入数据中的第k个训练示例。在训练SOM网络之后,将训练后的权重用于聚类新示例。一个新的例子落在获胜矢量群中。

算法

涉及的步骤有:

  • 重量初始化
  • 对于1到N个纪元
  • 选择一个训练实例
  • 计算获胜向量
  • 更新获胜矢量
  • 对所有训练示例重复步骤3、4、5。
  • 聚类测试样本

下面是上述方法的实现:

import math
  
  
class SOM :
      
    # Function here computes the winning vector
    # by Euclidean distance
    def winner( self, weights, sample ) :
          
        D0 = 0       
        D1 = 0
          
        for i  in range( len( sample ) ) :
              
            D0 = D0 + math.pow( ( sample[i] - weights[0][i] ), 2 )
            D1 = D1 + math.pow( ( sample[i] - weights[1][i] ), 2 )
              
            if D0 > D1 :
                return 0
            else : 
                return 1
      
    # Function here updates the winning vector
    def update( self, weights, sample, J, alpha ) :
          
        for i in range( len ( weights ) ) :
            weights[J][i] = weights[J][i] + alpha * ( sample[i] - weights[J][i] ) 
  
        return weights
  
# Driver code
def main() :
      
    # Training Examples ( m, n )
    T =  [ [ 1, 1, 0, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 0, 1, 1 ] ] 
  
    m, n = len( T ), len( T[0] )
      
    # weight initialization ( n, C )
    weights = [ [ 0.2, 0.6, 0.5, 0.9 ], [ 0.8, 0.4, 0.7, 0.3 ] ]
      
    # training
    ob = SOM()
      
    epochs = 3
    alpha = 0.5
      
    for i in range( epochs ) :
        for j in range( m ) :
              
            # training sample
            sample = T[j]
              
            # Compute winner vector
            J = ob.winner( weights, sample )
          
            # Update winning vector
            weights = ob.update( weights, sample, J, alpha )
              
    # classify test sample
    s = [ 0, 0, 0, 1 ]
    J = ob.winner( weights, s )
      
    print( "Test Sample s belongs to Cluster : ", J )
    print( "Trained weights : ", weights )
      
if __name__ == "__main__":
    main()
输出: