From 6b9bb8e7be8c6c7cbe0689aec11ceaba2fbc374c Mon Sep 17 00:00:00 2001 From: Ilan Rousseau Date: Tue, 10 Nov 2026 16:54:24 +0100 Subject: [PATCH] I am pushing the two questions files --- numpy_questions.py | 29 ++++++++++-------- sklearn_questions.py | 72 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/numpy_questions.py b/numpy_questions.py index 21fcec4b..41398d47 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -15,13 +15,15 @@ This will be enforced with `flake8`. You can check that there is no flake8 errors by calling `flake8` at the root of the repo. """ + + import numpy as np def max_index(X): """Return the index of the maximum in a numpy array. - - Parameters + + Parameters ---------- X : ndarray of shape (n_samples, n_features) The input array. @@ -37,18 +39,17 @@ def max_index(X): If the input is not a numpy array or if the shape is not 2D. """ - i = 0 - j = 0 - - # TODO - + if not isinstance(X, np.ndarray) or X.ndim != 2: + raise ValueError("X must be a 2D numpy array") + max_value_loc = np.argmax(X) + i, j = np.unravel_index(max_value_loc, X.shape) return i, j def wallis_product(n_terms): """Implement the Wallis product to compute an approximation of pi. - - See: + + See: https://en.wikipedia.org/wiki/Wallis_product Parameters @@ -62,6 +63,10 @@ def wallis_product(n_terms): pi : float The approximation of order `n_terms` of pi using the Wallis product. """ - # XXX : The n_terms is an int that corresponds to the number of - # terms in the product. For example 10000. - return 0. + loop = 1.0 + if n_terms == 0: + return 1.0 + for i in range(1, n_terms+1): + loop *= (4*i**2)/((4*i**2)-1) + pi = loop * 2 + return pi diff --git a/sklearn_questions.py b/sklearn_questions.py index f65038c6..80d763eb 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -28,47 +28,87 @@ from sklearn.utils.multiclass import check_classification_targets -class OneNearestNeighbor(BaseEstimator, ClassifierMixin): - "OneNearestNeighbor classifier." +class OneNearestNeighbor(ClassifierMixin, BaseEstimator): # specific parent comes before generic + """OneNearestNeighbor classifier.""" def __init__(self): # noqa: D107 pass def fit(self, X, y): - """Write docstring. - - And describe parameters + """Store the inputs on self: every training point and its label/class. + + Parameters + ---------- + X : 2D ndarray of shape (n_samples_train, n_features) + The design matrix. + y : 1D ndarray of shape (n_samples,) + The target. + + Returns + ------- + self : OneNearestNeighbor + The fitted classifier. """ X, y = check_X_y(X, y) check_classification_targets(y) self.classes_ = np.unique(y) self.n_features_in_ = X.shape[1] - # XXX fix + self.X_ = X + self.y_ = y + return self def predict(self, X): - """Write docstring. - - And describe parameters + """Return the predicted class of the points. + + Parameters + ---------- + X : 2D ndarray of shape (n_samples_test, n_features) + The samples to classify. + + Returns + ------- + y_pred : 1D ndarray of shape (n_samples_test,) + The predicted class label for each sample. """ check_is_fitted(self) X = check_array(X) + if X.shape[1] != self.n_features_in_: + raise ValueError( + f"X has {X.shape[1]} features, but OneNearestNeighbor " + f"is expecting {self.n_features_in_} features as input." + ) y_pred = np.full( shape=len(X), fill_value=self.classes_[0], dtype=self.classes_.dtype ) + for i, x in enumerate(X): + distances = np.sum((self.X_ - x)**2, axis=1) + # broadcasting method to subtract the X from every training row; + # the subtracted values are then squared and summed + y_pred[i] = self.y_[np.argmin(distances)] + # array of predictions takes the value of of the closest true y value classification to the x point + # note that we use argmin to retrieve the position of the smallest distance, and not the distance itself - # XXX fix return y_pred def score(self, X, y): - """Write docstring. - - And describe parameters + """Provide an accuracy score of the fitted model. + + Parameters + ---------- + X : 2D ndarray of shape (n_samples, n_features) + The samples to classify. + y : 1D ndarray of shape (n_samples,) + The true classification of each point. + + Returns + ------- + accuracy : float + The proportion of correctly-classified samples. """ X, y = check_X_y(X, y) y_pred = self.predict(X) - - # XXX fix - return y_pred.sum() + accuracy = np.mean(y_pred == y) + return accuracy \ No newline at end of file