Write K-means from scratch

Created
TagsML Coding
class KMeans:

    def __init__(self, n_clusters = 3, random_state = 0):
        assert n_clusters >=1, "n_clusters must be valid"

        self.n_clusters = n_clusters
        self.random_state = random_state
        np.random.seed(self.random_state)

    def L2(self, M, N):
        return np.sqrt(np.sum((M -N)**2, axis=1))

    def get_label(self, center, X):
        return np.array([np.argmin(self.L2(center, item)) for item in X])

    def get_center(self, labels, X):
        return np.array([np.mean(X[labels == i], axis= 0) for i in range(self.n_clusters)])
    
    def fit_predict(self, X, n_iter = 10):
        
        k = self.n_clusters
        
        center_index = np.random.choice(X.shape[0], self.n_clusters, replace=False)
        center = X[center_index]
        n_iter = n_iter

        while n_iter>0:

            last_center = center
            labels = self.get_label(last_center, X)
            center = self.get_center(labels, X)
            self.cluster_center = center

            if np.allclose(last_center, center):
                self.labels = self.get_label(center, X)
                break

            n_iter += 1

        return self

yf implement

import numpy as np
import random

class KMeans:
    def __init__(self, n_clusters = 3, random_state = 0):
        assert n_clusters >= 1, "must be valid"
        self._n_clusters = n_clusters
        self._random_state = random_state
        self._X = None
        self.cluster_centers_ = None
    
    def distance(self, M, N):
        return (np.sum((M - N) ** 2, axis = 1))** 0.5
    
    def _generate_labels(self, center, X):
        return np.array([np.argmin(self.distance(center, item)) for item in X])
    
    def _generate_centers(self, labels, X):
        return np.array([np.average(X[labels == i], axis=0) for i in np.arange(self._n_clusters)])
    
    def fit_predict(self, X):
        k = self._n_clusters

        if self._random_state:
            random.seed(self._random_state)

        center_index = np.random.choice(np.arange(X.shape[0]), size = k, replace = False)

        center = X[center_index]

        n_iters = 1e3
        while n_iters > 0:
            last_center = center

            labels = self._generate_labels(last_center, X)
            self.labels_ = labels 

            center = self._generate_centers(labels, X)

            self.cluster_centers_ = center

            if (last_center == center).all():
                self.labels_ = self._generate_labels(center, X)
                break
            n_iters -= 1
        return 


import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
# test 

t1 = np.linspace(-1, 1.5, 100)
t2 = np.linspace(-1, 1.5, 100)

X = np.array([(x, y) for x in t1 for y in t2])
print(f"X.shape={X.shape}") # (10000, 2)

plt.figure(figsize=(10, 10))
clf = KMeans(n_clusters=3, random_state=None)
clf.fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=clf.labels_)
center = clf.cluster_centers_
plt.scatter(center[:, 0], center[:, 1],marker="*",s=200)
plt.show()
print('center=', clf.cluster_centers_)