Self-organizing map in Python NumPy version

If you try to use a self-organizing map (SOM) in Python, I couldn't find a fast implementation made with numpy, so I made it.

Since there were implementations (1, 2) made with numpy to some extent, Based on this, I finish it with numpy.

An execution example is released on ipython notebook.

You can MAP like this Screen Shot 2016-01-20 at 8.29.10 PM.png

code

python


import numpy as np
from matplotlib import pyplot as plt

class SOM():
    
    def __init__(self, teachers, N, seed=None):
        self.teachers = np.array(teachers)
        self.n_teacher = self.teachers.shape[0]
        self.N = N
        if not seed is None:
            np.random.seed(seed)
            
        x, y = np.meshgrid(range(self.N), range(self.N))
        self.c = np.hstack((y.flatten()[:, np.newaxis],
                            x.flatten()[:, np.newaxis]))
        self.nodes = np.random.rand(self.N*self.N,
                                    self.teachers.shape[1])
    
    def train(self):
        for i, teacher in enumerate(self.teachers):
            bmu = self._best_matching_unit(teacher)
            d = np.linalg.norm(self.c - bmu, axis=1)
            L = self._learning_ratio(i)
            S = self._learning_radius(i, d)
            self.nodes += L * S[:, np.newaxis] * (teacher - self.nodes)
        return self.nodes

    def _best_matching_unit(self, teacher):
        #compute all norms (square)
        norms = np.linalg.norm(self.nodes - teacher, axis=1)
        bmu = np.argmin(norms) #argment with minimum element 
        return np.unravel_index(bmu,(self.N, self.N))

    def _neighbourhood(self, t):#neighbourhood radious
        halflife = float(self.n_teacher/4) #for testing
        initial  = float(self.N/2)
        return initial*np.exp(-t/halflife)

    def _learning_ratio(self, t):
        halflife = float(self.n_teacher/4) #for testing
        initial  = 0.1
        return initial*np.exp(-t/halflife)

    def _learning_radius(self, t, d):
        # d is distance from BMU
        s = self._neighbourhood(t)
        return np.exp(-d**2/(2*s**2))
        
        
N = 20        
teachers = np.random.rand(10000, 3)
som = SOM(teachers, N=N, seed=10)

# Initial map
plt.imshow(som.nodes.reshape((N, N, 3)),
           interpolation='none')
plt.show()

# Train
som.train()

# Trained MAP
plt.imshow(som.nodes.reshape((N, N, 3)),
           interpolation='none')
plt.show()      

References

Recommended Posts

Self-organizing map in Python NumPy version
Matrix multiplication in python numpy
Put python, numpy, opencv3 in ubuntu14
How to check opencv version in python
Prevent double launch in Python (improved version)
Quadtree in Python --2
My Numpy (Python)
CURL in python
Metaprogramming in Python
Python 3.3 in Anaconda
Geocoding in python
where in numpy
SendKeys in Python
Meta-analysis in Python
Unittest in python
Discord in Python
Sudoku in Python
DCI in Python
quicksort in python
nCr in python
N-Gram in Python
Programming in python
#Python basics (#Numpy 1/2)
Plink in Python
Constant in python
#Python basics (#Numpy 2/2)
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Csv in python
Disassemble in Python
Reflection in Python
PYTHON2.7 64bit version
Constant in python
nCr in Python.
format in python
Scons in Python3
Puyo Puyo in python
python in virtualenv
PPAP in Python
Python #Numpy basics
Quad-tree in Python
Reflection in Python
Chemistry in Python
Hashable in python
DirectLiNGAM in Python
LiNGAM in Python
Flatten in python
[Python] Numpy memo
flatten in python
Put python xgboost in max osx (llvm version)
[Python] Swapping rows and columns in Numpy data
Install Python 3.5.1 + numpy + scipy + α in Windows environment
How to specify TLS version in python requests
Spread the Geographical Survey Map tiles in Python
[Rust / Python] Handle numpy with PyO3 (August 2020 version)
Implement PRML algorithm in Python (almost Numpy only)
Sorted list in Python