<jupyter_start><jupyter_text>Plot the Decision boundary<jupyter_code>iris_x = np.array(iris_df[['petal length (cm)', 'petal width (cm)']])
iris_y = np.array(iris_df['target'])

X_space = np.linspace(0,7,200)
Y_space = np.linspace(0,3,200)
mesh_x, mesh_y = np.meshgrid(X_space, Y_space)

# use np.unique with suitable options to map the class names to numbers
target_names, iris_y_ids = np.unique(iris_y, return_inverse=True)
# print(target_names, iris_y_ids)

mesh_data = np.hstack([mesh_x.reshape(-1, 1), mesh_y.reshape(-1, 1)])

preds = KNN(iris_x, iris_y_ids, mesh_data, ks)
for k, preds_k in preds.items():
    plt.figure(dpi=100)
    plt.title(f"Decision boundary for k={k}")
    plt.contourf(mesh_x, mesh_y, preds_k.reshape(200,200), levels=2, cmap='Pastel1')
    plt.scatter(iris_x[:,0], iris_x[:,1], c=iris_y_ids, s=10, cmap=cmap_bold)<jupyter_output><empty_output><jupyter_text>Estimate performance for various k<jupyter_code>def err_rates(preds, test_Y):
    ret = {}
    for k, preds_k in preds.items():
        assert(len(test_Y) == len(preds_k))
        ret[k] = np.sum(preds_k != test_Y) / test_Y.shape[0]
    return ret
iris_x = np.array(iris_df[['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']])
iris_y = np.array(iris_df['target'])
N = len(iris_y)

ks = np.arange(1, 20, 2)
results = []

for _rep in tqdm.tqdm(range(1000)):
    train_idx, test_idx = np.split(np.random.permutation(N), [math.floor(N * 0.666)])

    preds = KNN(iris_x[train_idx], iris_y[train_idx], iris_x[test_idx], ks)
    errs = err_rates(preds, iris_y[test_idx])
    
    for k, errs_k in errs.items():
        results.append({'K':k, 'err_rate': errs_k})

# results_df will be a data_frame in long format
results_df = pd.DataFrame(results)
plt.figure()
sns.regplot(x=results_df.K, y=results_df.err_rate, data=results_df, x_estimator=np.mean, order=2)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16149395055234086, 'fraction_numerical': 0.022619673855865333, 'mean_word_length': 5.361204013377926, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '253001', 'license': 'MIT', 'n_tokens_mistral': 849, 'n_tokens_neox': 821, 'n_words': 151, 'path': 'Projects/KNN/KNN_iris.ipynb', 'repo_name': 'TheFebrin/Machine-Learning', 'size': '1901'}