diff --git a/.gitignore b/.gitignore
index 3ec3ce2..b826598 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+*.pkl
+
.vscode/
__pycache__
.ipynb_checkpoints
diff --git a/RCV1 Dataset Visualization/Self Organizing Map.ipynb b/RCV1 Dataset Visualization/Self Organizing Map.ipynb
new file mode 100644
index 0000000..e179079
--- /dev/null
+++ b/RCV1 Dataset Visualization/Self Organizing Map.ipynb
@@ -0,0 +1,461 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "
\n",
+ "
In The Name Of GOD
\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# RCV1 Dataset Visualization with Self Organizing Map"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Import Libraries"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import itertools\n",
+ "import numpy as np\n",
+ "import pickle as pkl\n",
+ "from numpy.ma.core import ceil \n",
+ "from numpy import linalg as LA\n",
+ "from joblib import Parallel, delayed, effective_n_jobs\n",
+ "from numpy import argmin, unravel_index, sqrt, ogrid, newaxis\n",
+ "from sklearn.metrics import DistanceMetric #distance calculation\n",
+ "from sklearn.utils import resample #resampling\n",
+ "from sklearn.preprocessing import MinMaxScaler, StandardScaler #normalization\n",
+ "from sklearn.pipeline import Pipeline #pipeline\n",
+ "from sklearn.model_selection import train_test_split #split data\n",
+ "from sklearn.metrics import accuracy_score #scoring\n",
+ "from sklearn.metrics import confusion_matrix\n",
+ "import matplotlib.pyplot as plt\n",
+ "from matplotlib import animation, colors\n",
+ "from tqdm import tqdm\n",
+ "import pprint"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Hyper parameters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "NUM_SAMPLES = 10000 # number of samples to use\n",
+ "NUM_NEURONS = (5 * np.sqrt(NUM_SAMPLES)) #number of neurons in the SOM rectangular grid\n",
+ "GRID_SIZE = (ceil(np.sqrt(NUM_NEURONS)).astype(np.int32), ceil(np.sqrt(NUM_NEURONS)).astype(np.int32)) #size of the grid\n",
+ "NUM_ITERS = 3000 #number of iterations to run the SOM\n",
+ "BETA0 = 0.5 #initial learning rate\n",
+ "MU = 2 # initial mu for normal distribution\n",
+ "SIGMA0 = 11 # initial sigma for normal distribution\n",
+ "N_JOBS = effective_n_jobs() #number of jobs to run in parallel\n",
+ "MIN_BETA = 0.05 #minimum learning rate\n",
+ "MIN_SIGMA = 1 #minimum sigma for normal distribution"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Self Organizing Map (SOM) Implementation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Helper Functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def normal(x, mu, sigma): #calculate the normal distribution\n",
+ " p = np.divide(1, np.sqrt(2 * np.pi * sigma**2))\n",
+ " return np.multiply(p, np.exp(-0.5 / sigma**2 * (x - mu)**2))\n",
+ "\n",
+ "def get_beta(epoch): #get the learning rate for the SOM\n",
+ " # return max(BETA0 * np.exp(-5 * np.divide(epoch, NUM_ITERS)), MIN_BETA)\n",
+ " return max(MIN_BETA, (BETA0 - MIN_BETA) * (1 - np.divide(epoch, NUM_ITERS)) + MIN_BETA)\n",
+ "\n",
+ "def get_sigma(epoch): #get the sigma for the normal distribution\n",
+ " # return max(SIGMA0 * np.exp(-5 * np.divide(epoch, NUM_ITERS)), MIN_SIGMA)\n",
+ " return max(MIN_SIGMA, (SIGMA0 - MIN_SIGMA) * (1 - np.divide(epoch, NUM_ITERS)) + MIN_SIGMA)\n",
+ "\n",
+ "def expand(x, shape): #expand the normal distribution to the grid size\n",
+ " return np.tile(x[:, :, newaxis], (1, 1, shape))\n",
+ "\n",
+ "def update_neurons(grid, best_match_idx, w, epoch): #update the neurons\n",
+ " x0, y0 = best_match_idx #get the coordinates of the best match\n",
+ " x, y = ogrid[0:GRID_SIZE[0], 0:GRID_SIZE[1]] #create a grid of coordinates\n",
+ " distance_to_best_idx = sqrt(np.power((x - x0), 2) + np.power((y - y0), 2)) #calculate the distance between the neurons and the best match\n",
+ " \n",
+ " sigma = get_sigma(epoch) #get the sigma for the normal distribution\n",
+ " # ns_values = normal(distance_to_best_idx, MU, sigma) #calculate the normal distribution\n",
+ " ns_values = 1 / (distance_to_best_idx + 1)\n",
+ " coefficient = expand(ns_values, grid.shape[-1]) #expand the normal distribution to the grid size\n",
+ " \n",
+ " # coefficient = np.tile(normal(ns_values, MU, get_sigma(epoch)), grid.shape) #calculate the coefficient for the neurons\n",
+ " distances = coefficient * (grid - w) #calculate the distance between the neurons and the input\n",
+ " \n",
+ " grid = grid + get_beta(epoch) * distances #update the neurons\n",
+ "\n",
+ "def find_winning_neuron(grid, x): #find the winning neuron\n",
+ " distances = LA.norm(grid - x, axis=-1) #calculate the distance between the neurons and the input\n",
+ " return unravel_index(argmin(distances), grid.shape[0:-1])\n",
+ "\n",
+ "def get_pipeline(scaler=StandardScaler()): #create a pipeline for the data\n",
+ " return Pipeline([\n",
+ " ('scaler', scaler)\n",
+ " ])\n",
+ "\n",
+ "def get_best_matching_units(grid, X: list): #get the best matching units for the input list\n",
+ " return Parallel(n_jobs=N_JOBS)(delayed(find_winning_neuron)(grid, X[i]) for i in tqdm(range(len(X)), desc='Finding BMUs'))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Import Dataset"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sklearn.datasets import fetch_rcv1 #fetch the RCV1 dataset\n",
+ "rcv1 = fetch_rcv1() \n",
+ "\n",
+ "X, Y = rcv1.data, rcv1.target"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'X.shape: (804414, 47236)'\n",
+ "'Y.shape: (804414, 103)'\n",
+ "'num_samples: 804414'\n",
+ "'num_features: 47236'\n",
+ "'num_classes: 103'\n"
+ ]
+ }
+ ],
+ "source": [
+ "pprint.pprint(f'X.shape: {X.shape}')\n",
+ "pprint.pprint(f'Y.shape: {Y.shape}')\n",
+ "pprint.pprint(f'num_samples: {X.shape[0]}')\n",
+ "pprint.pprint(f'num_features: {X.shape[1]}')\n",
+ "pprint.pprint(f'num_classes: {Y.shape[1]}')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Data Preprocessing"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "X_resampled, Y_resampled = resample(X, Y, n_samples=NUM_SAMPLES, random_state=42) #resample data\n",
+ "\n",
+ "X_train, X_test, Y_train, Y_test = train_test_split(X_resampled, Y_resampled, test_size=0.2, random_state=42) #split data into training and testing sets\n",
+ "\n",
+ "pipeline = get_pipeline()\n",
+ "X_train_pipelined = pipeline.fit_transform(X_train.toarray()) #scale data\n",
+ "X_test_pipelined = pipeline.transform(X_test.toarray()) #scale data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Self Organizing Map (SOM) Initialization"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'Grid rectangle is of width and height of (23, 23)'\n",
+ "'Neuron grid is of shape (23, 23, 47236)'\n"
+ ]
+ }
+ ],
+ "source": [
+ "grid = np.random.rand(*GRID_SIZE, X_train_pipelined.shape[1]) #initialize the grid with random values\n",
+ "\n",
+ "pprint.pprint(f'Grid rectangle is of width and height of {GRID_SIZE}')\n",
+ "pprint.pprint(f'Neuron grid is of shape {grid.shape}')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Training Self Organizing Map (SOM)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Epochs: 100%|██████████| 3000/3000 [10:17<00:00, 4.86it/s]\n"
+ ]
+ }
+ ],
+ "source": [
+ "for epoch in tqdm(range(NUM_ITERS), desc='Epochs', leave=True): #train the SOM\n",
+ " rnd_idx = np.random.randint(0, X_train_pipelined.shape[0]) #get a random index\n",
+ " x = X_train_pipelined[rnd_idx] #get the data\n",
+ " best_match_idx = find_winning_neuron(grid, x) #find the index of the neuron with the smallest distance to the input\n",
+ " update_neurons(grid, best_match_idx, x, epoch) #update the neurons"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Saving weights of SOM"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'SOM saved to model/som.pkl'\n"
+ ]
+ }
+ ],
+ "source": [
+ "with open('model/som.pkl', 'wb') as f: #save the SOM\n",
+ " pkl.dump(grid, f)\n",
+ " pprint.pprint(f'SOM saved to model/som.pkl')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Loading weights of SOM"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "'Grid has been loaded from model/som.pkl'\n"
+ ]
+ }
+ ],
+ "source": [
+ "with open('model/som.pkl', 'rb') as f: #load the SOM\n",
+ " grid = pkl.load(f)\n",
+ " pprint.pprint(f'Grid has been loaded from model/som.pkl')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Visualizing SOM"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Helper Functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dx = [0, 0, 1, -1] #neighborhood offsets\n",
+ "dy = [1, -1, 0, 0] #neighborhood offsets\n",
+ "\n",
+ "def calc_u_matrix(grid): #calculate the U matrix\n",
+ " u_matrix = np.zeros(GRID_SIZE) #initialize the U matrix\n",
+ " for pos in itertools.product(range(grid.shape[0]), range(grid.shape[1])):\n",
+ " num_neighbors = 0\n",
+ " for i in range(len(dx)):\n",
+ " x = pos[0] + dx[i]\n",
+ " y = pos[1] + dy[i]\n",
+ " if x >= 0 and x < grid.shape[0] and y >= 0 and y < grid.shape[1]:\n",
+ " u_matrix[pos] += LA.norm(grid[pos] - grid[x, y], axis=-1)\n",
+ " num_neighbors += 1\n",
+ " u_matrix[pos] /= num_neighbors\n",
+ " return u_matrix"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Plotting U-Matrix"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "u_matrix = calc_u_matrix(grid) #calculate the U matrix"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "