To use MiniSom for classification, you can map input samples to neurons and assign labels to those neurons based on the majority class of the training samples they represent.
- Prepare Data: Load your dataset and scale the features (e.g., using
sklearn.preprocessing.scale). - Initialize MiniSom: Create a
MiniSom instance specifying the grid dimensions, input dimension, and hyperparameters like sigma, learning_rate, and neighborhood_function. - Initialize Weights: Use
som.pca_weights_init(X_train) to initialize weights using Principal Component Analysis, which often improves convergence. - Train: Use
som.train_random(X_train, num_iteration) to train the map. - Classify: Use
som.labels_map(X_train, y_train) to create a mapping of winning neurons to their most frequent labels. For new samples, find the winning neuron using som.winner(sample) and retrieve the associated label from the map.
from minisom import MiniSom
import numpy as np
import pandas as pd
from sklearn.preprocessing import scale
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 1. Prepare and scale data
columns=['area', 'perimeter', 'compactness', 'length_kernel', 'width_kernel',
'asymmetry_coefficient', 'length_kernel_groove', 'target']
data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/00236/seeds_dataset.txt',
names=columns,
sep='\t+', engine='python')
labels = data['target'].values
data = scale(data.values)
# 2. Split data
X_train, X_test, y_train, y_test = train_test_split(data, labels, stratify=labels)
# 3. Initialize and train MiniSom
som = MiniSom(7, 7, data.shape[1], sigma=3, learning_rate=0.5,
neighborhood_function='triangle', random_seed=10)
som.pca_weights_init(X_train)
som.train_random(X_train, 500, verbose=False)
# 4. Classification logic using labels_map
def classify(som, data, X_train, y_train):
winmap = som.labels_map(X_train, y_train)
# Determine a default class from the most common label in the winmap
default_class = list(winmap.values())[0].most_common()[0][0]
result = []
for d in data:
win_position = som.winner(d)
if win_position in winmap:
result.append(winmap[win_position].most_common()[0][0])
else:
result.append(default_class)
return result
# 5. Evaluate
print(classification_report(y_test, classify(som, X_test, X_train, y_train)))