From bbbbe504fd197075d5e3be3efa81164e22efedee Mon Sep 17 00:00:00 2001 From: Your Full Name Date: Fri, 14 Nov 2025 01:22:45 +0100 Subject: [PATCH 1/2] RomainETIENNE's Assignment -> Done. --- numpy_questions.py | 27 +++++++++++---- sklearn_questions.py | 80 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 83 insertions(+), 24 deletions(-) diff --git a/numpy_questions.py b/numpy_questions.py index 21fcec4b..1681fc39 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -37,13 +37,15 @@ def max_index(X): If the input is not a numpy array or if the shape is not 2D. """ - i = 0 - j = 0 + if X is None or not isinstance(X, np.ndarray): + raise ValueError("Input must be a numpy.ndarray with 2 dimensions") - # TODO - - return i, j + if X.ndim != 2: + raise ValueError("Input must be a 2D numpy.ndarray") + flat_index = int(np.argmax(X)) + return tuple(int(x) for x in np.unravel_index(flat_index, X.shape)) + def wallis_product(n_terms): """Implement the Wallis product to compute an approximation of pi. @@ -64,4 +66,17 @@ def wallis_product(n_terms): """ # XXX : The n_terms is an int that corresponds to the number of # terms in the product. For example 10000. - return 0. + if not isinstance(n_terms, int): + raise ValueError("n_terms must be an int") + + # By convention in the tests, n_terms == 0 returns 1.0 + if n_terms == 0: + return 1.0 + + product = 1.0 + for n in range(1, n_terms + 1): + numerator = 4.0 * (n ** 2) + denominator = numerator - 1.0 + product *= numerator / denominator + + return 2.0 * product diff --git a/sklearn_questions.py b/sklearn_questions.py index f65038c6..087d4b11 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -28,47 +28,91 @@ from sklearn.utils.multiclass import check_classification_targets -class OneNearestNeighbor(BaseEstimator, ClassifierMixin): - "OneNearestNeighbor classifier." +class OneNearestNeighbor(ClassifierMixin, BaseEstimator): + """OneNearestNeighbor classifier. + + A minimal 1-nearest-neighbor classifier using Euclidean distance. + Implements the scikit-learn estimator interface (``fit``, ``predict``, + ``score``) and stores the training samples for nearest-neighbor queries. + """ def __init__(self): # noqa: D107 pass def fit(self, X, y): - """Write docstring. + """Fit the 1-nearest-neighbor classifier. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Training data. - And describe parameters + y : array-like of shape (n_samples,) + Target labels. + + Returns + ------- + self : OneNearestNeighbor + The fitted estimator. """ X, y = check_X_y(X, y) check_classification_targets(y) + # store class labels and training data self.classes_ = np.unique(y) self.n_features_in_ = X.shape[1] - - # XXX fix + self.X_train_ = np.asarray(X) + self.y_train_ = np.asarray(y) return self def predict(self, X): - """Write docstring. + """Predict the class labels for the provided samples. - And describe parameters + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Input samples. + + Returns + ------- + y_pred : ndarray of shape (n_samples,) + Predicted class labels. """ check_is_fitted(self) X = check_array(X) - y_pred = np.full( - shape=len(X), fill_value=self.classes_[0], - dtype=self.classes_.dtype - ) - # XXX fix + if X.ndim == 1: + X = X.reshape(1, -1) + + if X.shape[1] != self.n_features_in_: + msg = ( + f"X has {X.shape[1]} features, but {self.__class__.__name__} " + f"is expecting {self.n_features_in_} features as input" + ) + raise ValueError(msg) + + # compute squared Euclidean distances between X and training points + # shape (n_samples, n_train) + dists = np.sum((X[:, np.newaxis, :] - self.X_train_[np.newaxis, :, :]) ** 2, axis=2) + nn_idx = np.argmin(dists, axis=1) + y_pred = self.y_train_[nn_idx] return y_pred def score(self, X, y): - """Write docstring. + """Return the mean accuracy on the given test data and labels. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Test samples. - And describe parameters + y : array-like of shape (n_samples,) + True labels for `X`. + + Returns + ------- + score : float + Mean accuracy of `self.predict(X)` with respect to `y`. """ X, y = check_X_y(X, y) y_pred = self.predict(X) - - # XXX fix - return y_pred.sum() + return np.mean(y_pred == y) From ee848729259836b7648242d7fec7a6573b3e08ed Mon Sep 17 00:00:00 2001 From: Your Full Name Date: Fri, 14 Nov 2025 01:30:44 +0100 Subject: [PATCH 2/2] flake8 issues -> Corrected. --- numpy_questions.py | 2 +- sklearn_questions.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/numpy_questions.py b/numpy_questions.py index 1681fc39..eaf9ef1d 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -45,7 +45,7 @@ def max_index(X): flat_index = int(np.argmax(X)) return tuple(int(x) for x in np.unravel_index(flat_index, X.shape)) - + def wallis_product(n_terms): """Implement the Wallis product to compute an approximation of pi. diff --git a/sklearn_questions.py b/sklearn_questions.py index 087d4b11..5b8e69de 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -92,7 +92,8 @@ def predict(self, X): # compute squared Euclidean distances between X and training points # shape (n_samples, n_train) - dists = np.sum((X[:, np.newaxis, :] - self.X_train_[np.newaxis, :, :]) ** 2, axis=2) + dists = np.sum((X[:, np.newaxis, :] - + self.X_train_[np.newaxis, :, :]) ** 2, axis=2) nn_idx = np.argmin(dists, axis=1) y_pred = self.y_train_[nn_idx] return y_pred