diff --git a/numpy_questions.py b/numpy_questions.py index 21fcec4b..2cf1cb9e 100644 --- a/numpy_questions.py +++ b/numpy_questions.py @@ -37,10 +37,20 @@ def max_index(X): If the input is not a numpy array or if the shape is not 2D. """ + if not isinstance(X, np.ndarray): + raise ValueError("Input is not a numpy array") + if X.ndim != 2: + raise ValueError("Shape of Array is not 2D") + i = 0 j = 0 - - # TODO + cur_max = X[0, 0] + for a in range(X.shape[0]): + for b in range(X.shape[1]): + if X[a, b] > cur_max: + cur_max = X[a, b] + i = a + j = b return i, j @@ -62,6 +72,15 @@ def wallis_product(n_terms): pi : float The approximation of order `n_terms` of pi using the Wallis product. """ + product = 1 + if n_terms == 0: + return 1 + + for x in range(1, n_terms + 1): + curr_factor = 4 * (x**2) / (4 * (x**2) - 1) + product = product * curr_factor + # XXX : The n_terms is an int that corresponds to the number of # terms in the product. For example 10000. - return 0. + + return product * 2 diff --git a/sklearn_questions.py b/sklearn_questions.py index 948c2e54..7801db57 100644 --- a/sklearn_questions.py +++ b/sklearn_questions.py @@ -25,51 +25,100 @@ 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.validation import validate_data from sklearn.utils.multiclass import check_classification_targets +from sklearn.utils.validation import validate_data class OneNearestNeighbor(ClassifierMixin, BaseEstimator): - "OneNearestNeighbor classifier." + """OneNearestNeighbor classifier.""" def __init__(self): # noqa: D107 pass def fit(self, X, y): - """Write docstring. - - And describe parameters + """Return the fitted classifier based on training data. + + Parameters + ---------- + X : ndarray of shape (n_samples, n_features) + The training data. + y : ndarray of shape (n_samples,) + The target labels. + + Returns + ------- + self : OneNearestNeighbor + The fitted classifier. """ + # Check that X and y have compatible shapes and valid values. 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 + # Store the data + self.X_ = X + self.y_ = y + return self def predict(self, X): - """Write docstring. + """Predict labels using the nearest training sample. + + Parameters + ---------- + X : ndarray of shape (n_samples, n_features) + The samples to classify. - And describe parameters + Returns + ------- + y_pred : ndarray of shape (n_samples,) + The predicted labels for input sample. """ check_is_fitted(self) X = check_array(X) + + # Check that the data has the same features: + # Reads n_features_in_ back from the estimator + # And compares it with the number of columns in the new X + X = validate_data(self, X, reset=False) + y_pred = np.full( shape=len(X), fill_value=self.classes_[0], dtype=self.classes_.dtype ) + for i, sample in enumerate(X): + # Subtract this sample from every training observation + differences = self.X_ - sample + + # Find one distance per training observation + distances = np.sqrt(np.sum(differences ** 2, axis=1)) + + # Select the nearest observation and copy its label + min_index = np.argmin(distances) + y_pred[i] = self.y_[min_index] - # XXX fix return y_pred def score(self, X, y): - """Write docstring. - - And describe parameters + """Measure accuracy of predictions. + + Parameters + ---------- + X : ndarray of shape (n_samples, n_features) + The samples to evaluate. + y : ndarray of shape (n_samples,) + The correct labels. + + 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() + # Calculate how accurate the predictions are + # In proportion to the observed classes + accuracy = sum(y_pred == y) / len(y) + return accuracy