<jupyter_start><jupyter_text>Load our data<jupyter_code>iris = load_iris()
iris.keys()
iris.feature_names
# store our data in variable X
X = iris.data; X.shape
# Keep only the first two features: sepal length (cm) and sepal width (cm)
X = X[:,:2]; X.shape

# preprocess the data (Step 0)
def normalize(x,axis):
    return (x-x.mean(axis))/x.std(axis)
X = normalize(X,0)
plt.scatter(X[:,0],X[:,1])
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.show()<jupyter_output><empty_output><jupyter_text>Load Kmeans K-Means Algorithm:- **Step 1** - Pick K random points as cluster centers called centroids.- **Step 2** - Assign each x to the nearest cluster by calculating its distance to each centroid (Euclidean).- **Step 3** - Find the new cluster center by taking the average of the assigned points.- **Step 4** - Repeat Step 2 and 3 for a given number of iterations or until none of the cluster assignments change. Note: typically you would use sci-kit learn's implementation. Here is what is happening under the hood in Kmeans<jupyter_code># Implementing our own Kmeans
class KMeans:
    def __init__(self, x, clusters, iters):
        self.clusters = clusters
        self.iters = iters
        self.x = np.array(x)
        self.all_labels,self.all_centers = [],[]

    def distance(self,x1,x2):
        # euclidean distance (aka pythagorean metric, aka L2 norm)
        assert x1.shape == x2.shape, f"shapes don't match {x1.shape} != {x2.shape} "
        return math.sqrt(sum([(x1[i]-x2[i])**2 for i in range(len(x1))]))
        
    def generate_random_points(self):
        return np.random.randn(self.clusters,self.x.shape[1])
    
    def get_labels(self):
        labels = []
        for i,point in enumerate(self.x): 
            min_dist = float('inf')
            best_cluster = None
            for ic, center in enumerate(self.centers):
                dist = self.distance(point,center)
                if dist < min_dist:
                    min_dist = dist
                    best_cluster = ic
            labels.append(best_cluster)
        return np.array(labels)
    
    def set_centers(self,i):
        if i == 0: 
            return self.generate_random_points()
        centers = []
        for j in range(self.clusters):
            m = self.x[self.labels==j].mean(0)
            centers.append(m)
        return np.array(centers)
            
    def fit(self):
        for i in range(self.iters):
            self.centers = self.set_centers(i)
            self.labels = self.get_labels() 
            # stop early if labels are not changing 
            if i > 0 and np.all(np.equal(self.labels, self.all_labels[-1])):
                return
            self.all_centers.append(self.centers)
            self.all_labels.append(self.labels)
    def predict(self,x):
        """
        predicts on new data. returns the cluster label for the points or point x.
        """
        raise NotImplementedError
            
X.shape
k = KMeans(X,clusters=3,iters=50)
k.fit()<jupyter_output><empty_output><jupyter_text>Plot the clusters<jupyter_code># draw the figure so the animations will work
fig = plt.figure()
fig.canvas.draw()
i = 0
for centers,labels in zip(k.all_centers,k.all_labels):
        print(f"iter {i}")
        plt.scatter(X[:,0],X[:,1],c=labels) # plot something
        cxs, cys = zip(*centers)
        plt.scatter(x=cxs,y=cys,s=300,marker="o",c="red")
        plt.xlabel(iris.feature_names[0])
        plt.ylabel(iris.feature_names[1])
        # update canvas immediately
        plt.pause(0.01) 
        fig.canvas.draw()
        i+=1
print(f"Finished in {i} iterations.")
i<jupyter_output><empty_output><jupyter_text>PCA<jupyter_code>def pca(x,k):
    """
    provide m x n matrix where m are examples and n are features 
    """
    x = x.T # adjusting the matrix to 
    cov = np.cov(x)
    u,_,_ = np.linalg.svd(cov)
    u = u[:,:k]
    res = u.T@x
    return res.T
X = iris.data

X = normalize(X,0) 
X.shape
pca(X,2).shape # we have reduced our dimensions to 2.<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12296697880729424, 'fraction_numerical': 0.011582060128141941, 'mean_word_length': 2.6176470588235294, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, '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': '442045', 'license': 'MIT', 'n_tokens_mistral': 1400, 'n_tokens_neox': 1352, 'n_words': 354, 'path': 'kmeans.ipynb', 'repo_name': 'devkosal/code_challenges', 'size': '4058'}