<jupyter_start><jupyter_text>Helping Implementation<jupyter_code>def plot_data_and_centers(data, centers=None):

    plt.figure(figsize=(9,9))
    
    # Plot the data and the centers generated as random
    plt.scatter(data[:,0], data[:,1], s=7)
    if isinstance(centers,type(np.array([]))):
        plt.scatter(centers[:,0], centers[:,1], marker='o', c='r', s=150)<jupyter_output><empty_output><jupyter_text>K-Means Clustering![](https://raw.githubusercontent.com/SamirMoustafa/Machine-Learning-Implementation/master/K-Mean/Kmean.gif?token=<PASSWORD>)  Generate Random DataGenerate random data normally distributed around 4 centers, with a noise.<jupyter_code># Set three centers, the model should predict similar results
center_1 = np.array([1,1])
center_2 = np.array([5,5])
center_3 = np.array([8,1])
center_4 = np.array([10,5])

# Generate random data and center it to the three centers
data_1 = np.random.randn(200,2) + center_1
data_2 = np.random.randn(200,2) + center_2
data_3 = np.random.randn(200,2) + center_3
data_4 = np.random.randn(200,2) + center_4

data = np.concatenate((data_1, data_2, data_3, data_4), axis = 0)
plot_data_and_centers(data)
# Number of clusters
k = 4
# Number of training data
n = data.shape[0]
# Number of features in the data
c = data.shape[1]

# Generate random centers, here we use sigma and mean to ensure it represent the whole data
mean = np.mean(data, axis = 0)
std = np.std(data, axis = 0)
centers = np.random.randn(k,c)*std + mean
plot_data_and_centers(data, centers)<jupyter_output><empty_output><jupyter_text>Algorithm<jupyter_code>def K_Mean(data, centers=None):
    if not isinstance(centers, type(np.array([]))):
        mean = np.mean(data, axis = 0)
        std = np.std(data, axis = 0)
        centers = np.random.randn(k,c)*std + mean
        
    centers_old = np.zeros(centers.shape) # to store old centers
    centers_new = deepcopy(centers) # Store new centers

    clusters = np.zeros(n)
    distances = np.zeros((n,k))

    error = np.linalg.norm(centers_new - centers_old)

    # When, after an update, the estimate of that center stays the same, exit loop
    while error != 0.0:
        # Measure the distance to every center
        for i in range(k):
            distances[:,i] = np.linalg.norm(data - centers[i], axis=1)
        # Assign all training data to closest center
        clusters = np.argmin(distances, axis = 1)

        centers_old = deepcopy(centers_new)
        # Calculate mean for every cluster and update the center
        for i in range(k):
            centers_new[i] = np.mean(data[clusters == i], axis=0)
        error = np.linalg.norm(centers_new - centers_old)
    
    return centers_new<jupyter_output><empty_output><jupyter_text>Evaluation<jupyter_code>centers = K_Mean(data, centers)
plot_data_and_centers(data, centers)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12548330404217925, 'fraction_numerical': 0.022847100175746926, 'mean_word_length': 4.127927927927928, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '389559', 'license': 'MIT', 'n_tokens_mistral': 1017, 'n_tokens_neox': 988, 'n_words': 238, 'path': 'K-Mean/k-means-clustering.ipynb', 'repo_name': 'SamirMoustafa/Machine-Learning-Implementation', 'size': '2883'}