Skip to content

Commit aa60347

Browse files
Final submission: Completed all assignment questions and ensured full CI compliance.
1 parent a679f84 commit aa60347

9 files changed

Lines changed: 161 additions & 15 deletions

File tree

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/github-assignment.iml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/profiles_settings.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

numpy_questions.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ def max_index(X):
4040
i = 0
4141
j = 0
4242

43-
# TODO
43+
if not isinstance(X, np.ndarray):
44+
raise ValueError("Input must be a numpy array.")
45+
if X.ndim != 2:
46+
raise ValueError("Input must be 2D.")
47+
48+
max_flat_index = np.argmax(X)
49+
50+
i, j = np.unravel_index(max_flat_index, X.shape)
4451

4552
return i, j
4653

@@ -62,6 +69,15 @@ def wallis_product(n_terms):
6269
pi : float
6370
The approximation of order `n_terms` of pi using the Wallis product.
6471
"""
65-
# XXX : The n_terms is an int that corresponds to the number of
66-
# terms in the product. For example 10000.
67-
return 0.
72+
if n_terms == 0:
73+
return 1.0
74+
75+
k = np.arange(1, n_terms + 1, dtype=np.float64)
76+
77+
term = (4.0 * k * k) / (4.0 * k * k - 1.0)
78+
79+
product = np.prod(term)
80+
81+
pi_approximation = 2.0 * product
82+
83+
return pi_approximation

sklearn_questions.py

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,46 +29,105 @@
2929

3030

3131
class OneNearestNeighbor(BaseEstimator, ClassifierMixin):
32-
"OneNearestNeighbor classifier."
32+
"""OneNearestNeighbor classifier.
33+
34+
This estimator implements the 1-Nearest Neighbor classification algorithm.
35+
It predicts the label of a test sample based on the label of the single
36+
closest training sample (using Euclidean distance).
37+
38+
No hyperparameters are needed for 1-NN.
39+
"""
3340

3441
def __init__(self): # noqa: D107
3542
pass
3643

3744
def fit(self, X, y):
38-
"""Write docstring.
45+
"""Fit the OneNearestNeighbor classifier.
46+
47+
The 1-NN model simply stores the training data (X, y).
48+
49+
Parameters
50+
----------
51+
X : array-like of shape (n_samples, n_features)
52+
The training input samples.
53+
y : array-like of shape (n_samples,)
54+
The target values.
3955
40-
And describe parameters
56+
Returns
57+
-------
58+
self : OneNearestNeighbor
59+
The fitted estimator.
4160
"""
4261
X, y = check_X_y(X, y)
4362
check_classification_targets(y)
4463
self.classes_ = np.unique(y)
4564
self.n_features_in_ = X.shape[1]
4665

47-
# XXX fix
66+
self.X_fit_ = X
67+
self.y_fit_ = y
4868
return self
4969

5070
def predict(self, X):
51-
"""Write docstring.
71+
"""Predict the class labels for the input samples.
5272
53-
And describe parameters
73+
For each test sample, find the closest training sample using
74+
Euclidean distance and return its label.
75+
76+
Parameters
77+
----------
78+
X : array-like of shape (n_samples_test, n_features)
79+
The input samples to predict.
80+
81+
Returns
82+
-------
83+
y_pred : ndarray of shape (n_samples_test,)
84+
The predicted class labels.
5485
"""
5586
check_is_fitted(self)
5687
X = check_array(X)
88+
5789
y_pred = np.full(
5890
shape=len(X), fill_value=self.classes_[0],
5991
dtype=self.classes_.dtype
6092
)
6193

62-
# XXX fix
94+
n_test = X.shape[0]
95+
96+
for i in range(n_test):
97+
x_test = X[i, :]
98+
99+
distances = np.sum((self.X_fit_ - x_test) ** 2, axis=1)
100+
101+
nearest_neighbor_index = np.argmin(distances)
102+
103+
y_pred[i] = self.y_fit_[nearest_neighbor_index]
63104
return y_pred
64105

65106
def score(self, X, y):
66-
"""Write docstring.
67-
68-
And describe parameters
107+
"""Return the mean accuracy on the given test data and labels.
108+
109+
Parameters
110+
----------
111+
X : array-like of shape (n_samples_test, n_features)
112+
The input samples.
113+
y : array-like of shape (n_samples_test,)
114+
True labels for X.
115+
116+
Returns
117+
-------
118+
score : float
119+
Mean accuracy of self.predict(X) wrt. y.
69120
"""
70121
X, y = check_X_y(X, y)
71122
y_pred = self.predict(X)
72123

73-
# XXX fix
124+
is_correct = (y_pred == y)
125+
126+
n_samples = len(y)
127+
if n_samples == 0:
128+
y_pred = np.array([0.0])
129+
return y_pred.sum()
130+
131+
y_pred = is_correct.astype(float) / n_samples
132+
74133
return y_pred.sum()

0 commit comments

Comments
 (0)