diff --git a/numpy_questions.py b/numpy_questions.py index 21fcec4b..20be6b06 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -37,12 +37,16 @@ def max_index(X): If the input is not a numpy array or if the shape is not 2D. """ - i = 0 - j = 0 + if not isinstance(X, np.ndarray): + raise ValueError("X must be a numpy array.") - # TODO + if X.ndim != 2: + raise ValueError("X must be a 2D array.") - return i, j + flat_index = np.argmax(X) + i, j = np.unravel_index(flat_index, X.shape) + + return int(i), int(j) def wallis_product(n_terms): @@ -61,7 +65,27 @@ def wallis_product(n_terms): ------- pi : float The approximation of order `n_terms` of pi using the Wallis product. + + Raises + ------ + ValueError + If n_terms is negative or not an integer. """ - # 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 integer.") + + if n_terms < 0: + raise ValueError("n_terms must be non-negative.") + + if n_terms == 0: + return 1.0 + + product = 1.0 + + for k in range(1, n_terms + 1): + numerator = 4.0 * k * k + denominator = numerator - 1.0 + product *= numerator / denominator + + pi_approx = 2.0 * product + return pi_approx diff --git a/sklearn_questions.py b/sklearn_questions.py index f65038c6..64f328bf 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -19,56 +19,93 @@ for the methods you code and for the class. The docstring will be checked using `pydocstyle` that you can also call at the root of the repo. """ -import numpy as np -from sklearn.base import BaseEstimator -from sklearn.base import ClassifierMixin -from sklearn.utils.validation import check_X_y -from sklearn.utils.validation import check_array -from sklearn.utils.validation import check_is_fitted -from sklearn.utils.multiclass import check_classification_targets +from sklearn.base import BaseEstimator, ClassifierMixin +from sklearn.utils.validation import check_X_y, check_array, check_is_fitted +from sklearn.utils.multiclass import unique_labels +from sklearn.metrics import accuracy_score +from sklearn.neighbors import KNeighborsClassifier -class OneNearestNeighbor(BaseEstimator, ClassifierMixin): - "OneNearestNeighbor classifier." +class OneNearestNeighbor(ClassifierMixin, BaseEstimator): + """One-nearest-neighbor classifier. - def __init__(self): # noqa: D107 - pass + This classifier predicts, for each sample, the label of the closest + training sample, using the Euclidean distance. + + Attributes + ---------- + classes_ : ndarray of shape (n_classes,) + Class labels known to the classifier. + + X_ : ndarray of shape (n_samples, n_features) + Training data stored after fitting. + + y_ : ndarray of shape (n_samples,) + Target values stored after fitting. + + n_features_in_ : int + Number of features seen during fit. + """ def fit(self, X, y): - """Write docstring. + """Fit the one-nearest-neighbor classifier. - And describe parameters + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Training data. + + y : array-like of shape (n_samples,) + Target values. + + Returns + ------- + self : OneNearestNeighbor + Fitted estimator. """ - X, y = check_X_y(X, y) - check_classification_targets(y) - self.classes_ = np.unique(y) - self.n_features_in_ = X.shape[1] + X, y = check_X_y(X, y, accept_sparse=False) + knn = KNeighborsClassifier(n_neighbors=1) + knn.fit(X, y) - # XXX fix + self._knn = knn + self.classes_ = unique_labels(y) + self.n_features_in_ = X.shape[1] + self.X_ = X + self.y_ = y return self def predict(self, X): - """Write docstring. + """Predict class labels for the provided data. - And describe parameters - """ - check_is_fitted(self) - X = check_array(X) - y_pred = np.full( - shape=len(X), fill_value=self.classes_[0], - dtype=self.classes_.dtype - ) + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Samples to classify. - # XXX fix - return y_pred + Returns + ------- + y_pred : ndarray of shape (n_samples,) + Predicted class labels. + """ + check_is_fitted(self, ("_knn", "classes_", "n_features_in_")) + X = check_array(X, accept_sparse=False) + return self._knn.predict(X) def score(self, X, y): - """Write docstring. + """Return the mean accuracy on the given test data and labels. - And describe parameters + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Test samples. + + y : array-like of shape (n_samples,) + True labels for X. + + Returns + ------- + score : float + Mean accuracy of the predictions on the given data. """ - X, y = check_X_y(X, y) y_pred = self.predict(X) - - # XXX fix - return y_pred.sum() + return accuracy_score(y, y_pred)