Skip to content

Instantly share code, notes, and snippets.

@jogonba2
Last active September 9, 2016 15:14
Show Gist options
  • Save jogonba2/c1cb6431280e87d55d2fe66aea0ec234 to your computer and use it in GitHub Desktop.
Save jogonba2/c1cb6431280e87d55d2fe66aea0ec234 to your computer and use it in GitHub Desktop.
Self-organizing maps (SOM)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
from sklearn.datasets import load_iris
class SOM:
def __init__(self,X,it,size_x,size_y,min_w=0,max_w=1,a=0.01):
self.X = X
self.it = it
self.a = a
self.size_x = size_x
self.size_y = size_y
self.lattice = np.array([[np.random.uniform(min_w,max_w,X.shape[1]) for j in xrange(size_y)] for i in xrange(size_x)])
def __euclidean_distance(self,sample):
aux_distance = np.sqrt(((np.ones(self.lattice.shape)*sample)-self.lattice)**2)
euclidean_distance = np.array([np.ones(self.size_y)])
for i in xrange(aux_distance.shape[0]):
euclidean_distance = np.concatenate((euclidean_distance,np.array([np.sum(aux_distance[i],axis=1)])),axis=0)
return euclidean_distance[1:]
def fit(self):
sigma_zero = max(self.size_x,self.size_y)/2.0
lambda_time = self.it / np.log(sigma_zero)
a_aux = self.a
for y in xrange(self.it):
if y%100==0: print "Iteration",y
sample = self.X[np.random.randint(self.X.shape[0])]
euclidean_distance = self.__euclidean_distance(sample)
min_distance = euclidean_distance.argmin()
bmu = np.unravel_index(min_distance,euclidean_distance.shape)
sigma = sigma_zero * np.exp(-(float(y)/lambda_time)) # Radius
self.a = a_aux * np.exp(-(float(y)/self.it)) # Learning factor
for i in xrange(self.lattice.shape[0]):
for j in xrange(self.lattice.shape[1]):
bmu_dist = np.sqrt( ((i-bmu[0])**2) + ((j-bmu[1])**2) )
if bmu_dist<=sigma:
theta = np.exp(-((bmu_dist**2)/(2*(sigma**2)))) # Regularizer
self.lattice[i][j] = self.lattice[i][j] + theta*self.a*(sample-self.lattice[i][j])
return self.lattice
def get_lattice(self): return self.lattice
def get_u_matrix(self): pass
if __name__ == "__main__":
X = load_iris().data
clf = SOM(X,200,5,5)
print clf.fit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment