2.1 MiB
2.1 MiB
In [3]:
#! curl https://raw.githubusercontent.com/MSU-ML-COURSE/ML-COURSE-25-26/refs/heads/master/requirements/requirements.txt -o ./requirements_2025_26_for_colab_small.txt
! pip install -q -r ./requirements_2025_26_for_colab_small.txtIn [4]:
import catboost
assert(catboost.__version__ == '1.2.8')In [5]:
from sklearn.preprocessing import StandardScaler, MinMaxScalerIn [6]:
import numpy as np
import seaborn as sns
import pickle
from matplotlib import pyplot as plt
plt.rcParams["figure.figsize"] = (5,5)In [7]:
!gdown 1acbP4PNmu11rkBzozvIc3bowWaQL7iFeIn [10]:
with open('data.pkl', 'rb') as file:
X, y = pickle.load(file)In [12]:
def plot_data_points(X, labels, xlim, ylim):
g = sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=labels)
g.set(xlim=xlim, ylim=ylim)
plt.xlabel('x_1')
plt.ylabel('x_2')
plt.grid()In [13]:
plot_data_points(X, y, xlim=(-15, 15), ylim=(-15, 15))In [16]:
from matplotlib.colors import ListedColormap
from sklearn import neighbors, datasets
def plot_knn_bound(X, y, scaler=None, n_neighbors=10, xlim=(-15, 15), ylim=(-20, 20)):
h = 0.05
cmap_light = ListedColormap(['C0', 'orange', 'cyan', 'green'][:np.unique(y).shape[0]])
cmap_bold = ['C0', 'orange', 'c', 'darkgreen'][:np.unique(y).shape[0]]
x_min, x_max = xlim
y_min, y_max = ylim
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
grid = np.c_[xx.ravel(), yy.ravel()]
X_scaled = X
if scaler is not None:
grid = scaler.transform(grid)
X_scaled = scaler.transform(X)
clf = neighbors.KNeighborsClassifier(n_neighbors, algorithm='brute')
clf.fit(X_scaled, y)
Z = clf.predict(grid)
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=cmap_light)
sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=y,
palette=cmap_bold, alpha=1.0, edgecolor="black")
plt.xlabel('x_1')
plt.ylabel('x_2')
plt.title('Разделющие поверхности алгоритма {}-NN'.format(n_neighbors))
plt.grid()
plt.show()In [17]:
plot_knn_bound(X, y, n_neighbors=1)
plot_knn_bound(X, y, n_neighbors=10)In [18]:
X = np.random.randn(4, 2)
y = np.arange(4)
plot_knn_bound(X, y, n_neighbors=1, xlim=(-3, 3), ylim=(-3, 3))In [19]:
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizerIn [20]:
X_train, y_train = fetch_20newsgroups(subset='train', return_X_y=True, random_state=42)
X_test, y_test = fetch_20newsgroups(subset='test', return_X_y=True, random_state=42)In [21]:
print(X_train[0])From: lerxst@wam.umd.edu (where's my thing) Subject: WHAT car is this!? Nntp-Posting-Host: rac3.wam.umd.edu Organization: University of Maryland, College Park Lines: 15 I was wondering if anyone out there could enlighten me on this car I saw the other day. It was a 2-door sports car, looked to be from the late 60s/ early 70s. It was called a Bricklin. The doors were really small. In addition, the front bumper was separate from the rest of the body. This is all I know. If anyone can tellme a model name, engine specs, years of production, where this car is made, history, or whatever info you have on this funky looking car, please e-mail. Thanks, - IL ---- brought to you by your neighborhood Lerxst ----
In [22]:
X_train = np.array(X_train, dtype=object)In [23]:
X_test = np.array(X_test, dtype=object)In [24]:
y_train = np.array(y_train)
y_test = np.array(y_test)In [25]:
count_vec = CountVectorizer(max_df=0.8, min_df=10, max_features=1000, stop_words='english')
tf_idf = TfidfVectorizer(max_df=0.8, min_df=10, max_features=1000, stop_words='english')In [26]:
from sklearn.metrics import accuracy_score
parameters = {
'n_neighbors': [i for i in range(1, 11)],
'metrics': ['cosine'],
'weights': ['uniform', 'distance'],
'normalizers': [(count_vec, 'CountVectorizer'), (tf_idf, 'TfidfVectorizer')]
}In [30]:
from cross_val import knn_cv_score, kfold_split
result = knn_cv_score(X_train, y_train, parameters, accuracy_score, kfold_split(X_train.shape[0], 3), neighbors.KNeighborsClassifier)
resultOut [30]:
{('CountVectorizer', 1, 'cosine', 'uniform'): np.float64(0.672087658236065),
('CountVectorizer', 1, 'cosine', 'distance'): np.float64(0.672087658236065),
('CountVectorizer', 2, 'cosine', 'uniform'): np.float64(0.6110139528291619),
('CountVectorizer', 2, 'cosine', 'distance'): np.float64(0.6722644460023516),
('CountVectorizer', 3, 'cosine', 'uniform'): np.float64(0.6174660970088653),
('CountVectorizer', 3, 'cosine', 'distance'): np.float64(0.6675804372619494),
('CountVectorizer', 4, 'cosine', 'uniform'): np.float64(0.6152563436671689),
('CountVectorizer', 4, 'cosine', 'distance'): np.float64(0.6666965921674022),
('CountVectorizer', 5, 'cosine', 'uniform'): np.float64(0.6185263080537139),
('CountVectorizer', 5, 'cosine', 'distance'): np.float64(0.6643980465607984),
('CountVectorizer', 6, 'cosine', 'uniform'): np.float64(0.6142833782286147),
('CountVectorizer', 6, 'cosine', 'distance'): np.float64(0.6595370157118955),
('CountVectorizer', 7, 'cosine', 'uniform'): np.float64(0.6131343983530804),
('CountVectorizer', 7, 'cosine', 'distance'): np.float64(0.6559130305425707),
('CountVectorizer', 8, 'cosine', 'uniform'): np.float64(0.6038539779918916),
('CountVectorizer', 8, 'cosine', 'distance'): np.float64(0.6522894906234525),
('CountVectorizer', 9, 'cosine', 'uniform'): np.float64(0.604472524265902),
('CountVectorizer', 9, 'cosine', 'distance'): np.float64(0.648135376497482),
('CountVectorizer', 10, 'cosine', 'uniform'): np.float64(0.5998765813295434),
('CountVectorizer', 10, 'cosine', 'distance'): np.float64(0.6455722350969835),
('TfidfVectorizer', 1, 'cosine', 'uniform'): np.float64(0.6936529067480152),
('TfidfVectorizer', 1, 'cosine', 'distance'): np.float64(0.6936529067480152),
('TfidfVectorizer', 2, 'cosine', 'uniform'): np.float64(0.6346121200480795),
('TfidfVectorizer', 2, 'cosine', 'distance'): np.float64(0.6936529067480152),
('TfidfVectorizer', 3, 'cosine', 'uniform'): np.float64(0.6405339477973659),
('TfidfVectorizer', 3, 'cosine', 'distance'): np.float64(0.6917972913602056),
('TfidfVectorizer', 4, 'cosine', 'uniform'): np.float64(0.6429204420369062),
('TfidfVectorizer', 4, 'cosine', 'distance'): np.float64(0.6895880770056014),
('TfidfVectorizer', 5, 'cosine', 'uniform'): np.float64(0.6401806066070069),
('TfidfVectorizer', 5, 'cosine', 'distance'): np.float64(0.6828707746106897),
('TfidfVectorizer', 6, 'cosine', 'uniform'): np.float64(0.6398272654166478),
('TfidfVectorizer', 6, 'cosine', 'distance'): np.float64(0.683401184777992),
('TfidfVectorizer', 7, 'cosine', 'uniform'): np.float64(0.6392082973266522),
('TfidfVectorizer', 7, 'cosine', 'distance'): np.float64(0.6788934013825628),
('TfidfVectorizer', 8, 'cosine', 'uniform'): np.float64(0.6343471493066424),
('TfidfVectorizer', 8, 'cosine', 'distance'): np.float64(0.6742089708261753),
('TfidfVectorizer', 9, 'cosine', 'uniform'): np.float64(0.6307235390848599),
('TfidfVectorizer', 9, 'cosine', 'distance'): np.float64(0.6723531210961516),
('TfidfVectorizer', 10, 'cosine', 'uniform'): np.float64(0.6277182642290952),
('TfidfVectorizer', 10, 'cosine', 'distance'): np.float64(0.6687294874401477)}In [31]:
tfidf = [v for k,v in result.items() if k[0] == 'TfidfVectorizer']
count = [v for k,v in result.items() if k[0] == 'CountVectorizer']
print(f'TfidfVectorizer - {np.mean(tfidf):.2f}, CountVectorizer {np.mean(count):.2f}')TfidfVectorizer - 0.66, CountVectorizer 0.64
In [32]:
num_neighbours = [k[1] for k,v in result.items()]
num_neighbours = np.unique(num_neighbours)
mean_vals = [np.mean([result[key] for key, val in result.items() if key[1] == k]) for k in num_neighbours]
plt.figure(figsize = [16, 8])
plt.plot(num_neighbours, mean_vals)
plt.ylabel('Точность')
plt.xlabel('Число соседей')
plt.title('Зависимость метрики качества от числа соседей')
plt.grid()
In [33]:
maxim = max(result, key = lambda x: result[x])
X_train_vec = tf_idf.fit_transform(X_train)
X_test_vec = tf_idf.transform(X_test)
model = neighbors.KNeighborsClassifier(1, weights = 'uniform', metric = 'cosine')
model.fit(X_train_vec, y_train)
y_pred = model.predict(X_test_vec)
print(maxim, result[maxim])
accuracy_score(y_test, y_pred)Out [33]:
('TfidfVectorizer', 1, 'cosine', 'uniform') 0.6936529067480152
0.5315985130111525
In [35]:
x = np.arange(0, 20)
data = []
for i in range(20):
y_pred = model.predict(X_test_vec[y_test == i])
data.append(accuracy_score(y_test[y_test == i], y_pred))
data_tr = []
for i in range(20):
y_pred = model.predict(X_train_vec[y_train == i])
data_tr.append(accuracy_score(y_train[y_train == i], y_pred))
plt.figure(figsize = [16, 8])
plt.plot(x, data_tr)
plt.plot(x, data)
plt.xticks(x)
plt.ylabel('Точность классификации')
plt.xlabel('Категория')
plt.legend(['Обучающая выборка', 'Тестовая выборка'], loc = 'right')
plt.show()