Алгоритм ML k-ближайших соседей (kNN)

Подскажите, возможно ли и как можно добавить условие, чтобы прогнозирование метки knn.predict(x_test) происходило только в том случае если 2 ближайших соседа n_neighbors=2 имеют одинаковые метки.

Пример, прогнозируем метку 1 или 0. При поиске 2 ближайших соседей, если они оба имеют метку 1, то knn.predict(x_test) будет равно 1, если оба 0, то будет равно 0. Но если один сосед 0, а другой 1, то в таком случае прогнозирование метки не происходит.

Используемый код:

knn = KNeighborsClassifier(n_neighbors=2, n_jobs=-1, weights='distance').fit(X, Y)
y_knn = knn.predict(x_test)
AA = accuracy_score(y_test, y_knn)
print(y_knn)
print(AA)

Также использую перекрестную модель все кроме одного:

knn = KNeighborsClassifier(n_neighbors=2, n_jobs=-1, weights='distance').fit(X, Y)
scores = cross_val_score(knn, X, Y, cv=LeaveOneOut())
print(scores.mean())

Или есть другой более подходящий для этих целей метод? Спасибо!


Ответы (1 шт):

Автор решения: CrazyElf

Если вы используете KNeighborsClassifier из пакета sklearn, то вы можете использовать для предсказания функцию predict_proba и пользоваться предсказаниями только в том случае, когда на выходе для какого-то из классов получается ровно 1, а если у всех классов получается вероятность меньше 1, то отбрасывать такие предсказания. Вот пример кода на сгенерированных данных:

from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np

X, y = make_classification(n_features=20, n_redundant=0, n_informative=10,
                           random_state=1, n_clusters_per_class=2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4, random_state=42)

knn = KNeighborsClassifier(n_neighbors=2, n_jobs=-1, weights='distance').fit(X_train, y_train)
y_knn = knn.predict(X_test)
print('все предсказания', y_knn)
y_knn_filt = np.max(knn.predict_proba(X_test), axis=1) == 1
print('фильтр уверенных предсказаний', y_knn_filt)
print('только уверенные предсказания', np.array(y_knn)[y_knn_filt])
AA = accuracy_score(y_test, y_knn)
print('score по всем предсказаниям', AA)
AA_filt = accuracy_score(np.array(y_test)[y_knn_filt], np.array(y_knn)[y_knn_filt])
print('score по уверенным предсказаниям', AA_filt)

Результат:

все предсказания [0 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1
 1 0 1]
фильтр уверенных предсказаний [ True  True  True False False  True  True  True  True False  True  True
  True  True  True False  True  True  True  True  True  True False False
  True  True  True  True False False  True  True  True  True  True  True
  True  True  True  True]
только уверенные предсказания [0 1 1 1 1 0 0 1 0 1 0 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 1 1 0 1]
score по всем предсказаниям 0.925
score по уверенным предсказаниям 1.0
→ Ссылка