Files
ML/task11/cross_val copy.py
2025-11-12 11:34:34 +03:00

74 lines
2.3 KiB
Python

import numpy as np
import typing
from collections import defaultdict
def kfold_split(
num_objects: int, num_folds: int
) -> list[tuple[np.ndarray, np.ndarray]]:
indices = np.arange(num_objects)
fold_size = num_objects // num_folds
result = []
for i in range(num_folds):
start = i * fold_size
if i == num_folds - 1:
end = num_objects
else:
end = (i + 1) * fold_size
val_indices = indices[start:end]
train_indices = np.concatenate([indices[:start], indices[end:]])
result.append((train_indices, val_indices))
return result
def knn_cv_score(
X: np.ndarray,
y: np.ndarray,
parameters: dict[str, list],
score_function: callable,
folds: list[tuple[np.ndarray, np.ndarray]],
knn_class: object,
) -> dict[str, float]:
results = {}
normalizers = parameters.get("normalizers", [(None, None)])
n_neighbors_list = parameters.get("n_neighbors", [5])
metrics_list = parameters.get("metrics", ["euclidean"])
weights_list = parameters.get("weights", ["uniform"])
for normalizer_tuple in normalizers:
normalizer, normalizer_name = normalizer_tuple
for n_neighbors in n_neighbors_list:
for metric in metrics_list:
for weight in weights_list:
fold_scores = []
for train_idx, val_idx in folds:
X_train, X_val = X[train_idx], X[val_idx]
y_train, y_val = y[train_idx], y[val_idx]
if normalizer is not None:
normalizer_fitted = normalizer.fit(X_train)
X_train = normalizer_fitted.transform(X_train)
X_val = normalizer_fitted.transform(X_val)
knn = knn_class(
n_neighbors=n_neighbors, metric=metric, weights=weight
)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_val)
score = score_function(y_val, y_pred)
fold_scores.append(score)
mean_score = np.mean(fold_scores)
key = (normalizer_name, n_neighbors, metric, weight)
results[key] = mean_score
return results