<jupyter_start><jupyter_text>KNN Implementation<jupyter_code>class KNeighborClassifier:
    def __init__(self, n_neighbors: int = 5):
        self.n_neighbors = n_neighbors
        self.X: np.ndarray
        self.y: np.ndarray
        self.num_classes: int
    
    def _distance(self, p1: np.ndarray, p2: np.ndarray):
        return np.linalg.norm(p1 - p2)
    
    def kneighbors(self, X: np.ndarray):
        distances = np.array([[self._distance(sample, x_i) for x_i in self.X] for sample in X])
        sorted_distances_idx = np.argsort(distances[:])
        kneighbors_idxs = sorted_distances_idx[:, :self.n_neighbors]
        return kneighbors_idxs

    def fit(self, X: np.ndarray, y: np.ndarray):
        self.X = X
        self.y = y
        self.num_classes = len(np.unique(self.y))


    def _vote_class(self, kneighbors_idxs: np.ndarray):
        votes = np.zeros(shape=(self.num_classes))
        neighbors_classes = self.y[kneighbors_idxs]
        for neighbor_class in neighbors_classes:
            votes[neighbor_class] += 1
        voted_class = np.argmax(votes)
        return voted_class

    def predict(self, X: np.ndarray):
        kneighbors_idx = self.kneighbors(X)
        y_pred = np.array([self._vote_class(kneighbor_idxs) for kneighbor_idxs in kneighbors_idx])
        return y_pred

    def score(self, X: np.ndarray, y: np.ndarray):
        y_pred = self.predict(X)
        accuracy = np.mean(y_pred == y)
        return accuracy
x_test = np.array([
    [-6, 0.1],
    [10, 4.9],
    [-3, 8]
])
y_test = np.array([0, 1])

clf = KNeighborClassifier(n_neighbors=3)
clf.fit(x, y)

y_pred = clf.predict(x_test)

score = clf.score(x_test, y_test)

print(f"y_pred: {y_pred}")
print(f"score: {score}")
def plot_knn_predicition(clf: KNeighborClassifier, X_samples: np.ndarray, X: np.ndarray, y: np.ndarray):
    colors = ['red', 'blue', 'green']
    for index, point in enumerate(X):
        plt.scatter(point[0], point[1], c=colors[y[index]])
    neighbors_idx = clf.kneighbors(X_samples)
    for index, point in enumerate(X_samples):
        neighbors_points = clf.X[neighbors_idx][index]
        neighbors_classes = clf.y[neighbors_idx][index]
        plt.scatter(point[0], point[1], c="black")
        for neighbor_point, neighbor_class in zip(neighbors_points, neighbors_classes):
            plt.plot([point[0], neighbor_point[0]], [point[1], neighbor_point[1]], '--', c=colors[neighbor_class])
    plt.show()
plot_knn_predicition(clf, x_test, x, y)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13272220007971303, 'fraction_numerical': 0.010362694300518135, 'mean_word_length': 3.232715008431703, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '631277', 'license': 'MIT', 'n_tokens_mistral': 964, 'n_tokens_neox': 950, 'n_words': 179, 'path': 'Chapter3_MLIntroduction/KnnAlgorithm/data_set_prep.ipynb', 'repo_name': 'antonroesler/UdemyML_Template', 'size': '2509'}