1. Вычислим расстояния с помощью NumPy.
import numpy as np
X = np.array([3, 4])
points = np.array([
[3, 5],
[6, 8],
[4, 4]
])
classes = np.array([0, 1, 0])
distances = np.linalg.norm(points - X, axis=1)
nearest_index = np.argmin(distances)
print("Расстояния:", distances)
print("Минимальное расстояние:", distances.min())
print("Ближайший сосед:", points[nearest_index])
print("Прогнозируемый класс:",
classes[nearest_index])
Результат:
Расстояния: [1. 5. 1.]
Минимальное расстояние: 1.0.
Ближайший сосед: [3, 5].
Прогнозируемый класс: 0.
Объекты [3, 5] и [4, 4] находятся на одинаковом минимальном
расстоянии. Оба относятся к классу 0, поэтому прогноз не зависит от выбора
одного из них.
2. Сравним результаты при разных значениях k.
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
X_train = np.array([
[1, 1],
[2, 2],
[3, 3],
[4, 4],
[5, 5]
])
y_train = np.array([1, 0, 0, 0, 1])
new_object = np.array([[1, 1]])
for k in [1, 3, 5]:
model =
KNeighborsClassifier(n_neighbors=k)
model.fit(X_train,
y_train)
prediction =
model.predict(new_object)
print(f"k =
{k}, класс = {prediction[0]}")
Результат:
k = 1, класс = 1.
k = 3, класс = 0.
k = 5, класс = 0.
При k = 1 решение определяется одним ближайшим объектом.
При k = 3 и k = 5 используется голосование нескольких
соседей, поэтому результат может измениться.
Малое k повышает чувствительность к шуму, а большое k
сглаживает границы классов.
В реальных задачах значение k выбирают с помощью
перекрёстной проверки.
3. Сравним обычное и взвешенное среднее.
import numpy as np
from sklearn.neighbors import KNeighborsRegressor
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X_train = np.array([
[1],
[2],
[3]
])
y_train = np.array([40, 50, 60])
new_object = np.array([[2.5]])
model_uniform = KNeighborsRegressor(
n_neighbors=3,
weights="uniform"
)
model_uniform.fit(X_train, y_train)
model_distance = KNeighborsRegressor(
n_neighbors=3,
weights="distance"
)
model_distance.fit(X_train, y_train)
pipeline = make_pipeline(
StandardScaler(),
KNeighborsRegressor(n_neighbors=3)
)
pipeline.fit(X_train, y_train)
print(
"Обычное
среднее:",
model_uniform.predict(new_object)[0]
)
print(
"Взвешенное
среднее:",
model_distance.predict(new_object)[0]
)
print(
"Pipeline:",
pipeline.predict(new_object)[0]
)
Результат:
Обычное среднее: 50.0.
Взвешенное среднее: приблизительно 51.43.
Pipeline: 50.0.
При обычном среднем все три соседа имеют одинаковое влияние
на прогноз.
При взвешенном среднем более близкие объекты получают
больший вес.
Масштабирование важно, поскольку евклидово расстояние
чувствительно к числовому масштабу признаков. Pipeline помогает выполнять
преобразования последовательно и предотвращать утечку информации между
обучением и проверкой модели.