Вывод функции knn.kneighbors(X=X_test)
более читабелен, если вы установите return_distance=False
. В этом случае каждая строка в результирующем массиве представляет индексы n_neighbors
числа ближайших соседей для каждой точки (строки) в X_test
.
Обратите внимание, что эти индексы соответствуют индексам в обучающем наборе X_train
. Если вы хотите отобразить их обратно в столбец Name
в исходном фрейме данных, я думаю, что вы должны использовать индексы pandas.
Надеюсь, приведенный ниже пример имеет смысл.
Создание набора данных:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
np.random.seed(42) # for repoducibility
df = pd.DataFrame(np.random.randn(20, 3),
columns=["X1", "X2", "X3"])
df["Name"] = df.index.values * 100 # assume the names are just pandas index * 100
Y = np.random.randint(0, 2, 20) # targets
print(df)
X1 X2 X3 Name
0 0.496714 -0.138264 0.647689 0
1 1.523030 -0.234153 -0.234137 100
2 1.579213 0.767435 -0.469474 200
3 0.542560 -0.463418 -0.465730 300
4 0.241962 -1.913280 -1.724918 400
5 -0.562288 -1.012831 0.314247 500
6 -0.908024 -1.412304 1.465649 600
7 -0.225776 0.067528 -1.424748 700
8 -0.544383 0.110923 -1.150994 800
9 0.375698 -0.600639 -0.291694 900
10 -0.601707 1.852278 -0.013497 1000
11 -1.057711 0.822545 -1.220844 1100
12 0.208864 -1.959670 -1.328186 1200
13 0.196861 0.738467 0.171368 1300
14 -0.115648 -0.301104 -1.478522 1400
15 -0.719844 -0.460639 1.057122 1500
16 0.343618 -1.763040 0.324084 1600
17 -0.385082 -0.676922 0.611676 1700
18 1.031000 0.931280 -0.839218 1800
19 -0.309212 0.331263 0.975545 1900
Разделить тест поезда:
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:, :3],
Y,
random_state=24 # for reproducibility
)
Обратите внимание на индекс каждого фрейма данных:
print(X_train)
X1 X2 X3
8 0.375698 -0.600639 -0.291694
14 -0.115648 -0.301104 -1.478522
16 0.343618 -1.763040 0.324084
7 -0.225776 0.067528 -1.424748
10 -0.601707 1.852278 -0.013497
12 0.208864 -1.959670 -1.328186
19 -0.309212 0.331263 0.975545
18 1.031000 0.931280 -0.839218
15 -0.719844 -0.460639 1.057122
11 -1.057711 0.822545 -1.220844
4 0.241962 -1.913280 -1.724918
1 1.523030 -0.234153 -0.234137
0 0.496714 -0.138264 0.647689
3 0.542560 -0.463418 -0.465730
2 1.579213 0.767435 -0.469474
print(X_test)
X1 X2 X3
13 0.196861 0.738467 0.171368
6 -0.908024 -1.412304 1.465649
17 -0.385082 -0.676922 0.611676
5 -0.562288 -1.012831 0.314247
9 0.375698 -0.600639 -0.291694
Поскольку мы обеспечили воспроизводимость, установив случайные начальные числа, давайте внесем изменения, которые помогут нам понять результат knn.kneighbors(X=X_test)
. Я устанавливаю первый ряд в X_train
таким же, как в последнем ряду X_test
. Поскольку эти две точки идентичны, когда мы запрашиваем X_test.loc[[9]]
(или X_test.iloc[4, :]
), он должен возвращать себя в качестве ближайшей точки.
Обратите внимание, что первая строка с индексом 8 была изменена и равна последний ряд X_test
:
X_train.loc[8] = X_test.loc[9]
print(X_train)
X1 X2 X3
8 0.375698 -0.600639 -0.291694
14 -0.115648 -0.301104 -1.478522
16 0.343618 -1.763040 0.324084
7 -0.225776 0.067528 -1.424748
10 -0.601707 1.852278 -0.013497
12 0.208864 -1.959670 -1.328186
19 -0.309212 0.331263 0.975545
18 1.031000 0.931280 -0.839218
15 -0.719844 -0.460639 1.057122
11 -1.057711 0.822545 -1.220844
4 0.241962 -1.913280 -1.724918
1 1.523030 -0.234153 -0.234137
0 0.496714 -0.138264 0.647689
3 0.542560 -0.463418 -0.465730
2 1.579213 0.767435 -0.469474
Обучение модели KNN:
knn = KNeighborsClassifier(n_neighbors=2)
knn.fit(X_train, y_train)
Чтобы упростить задачу, давайте получим ближайших соседей в одну точку (такое же объяснение применимо для несколько точек).
Получение двух ближайших соседей для указанного c пункта X_test.loc[[9]] = [ 0.375698 -0.600639 -0.291694]
, который мы использовали выше для изменения X_train
):
nn_indices = knn.kneighbors(X=X_test.loc[[9]], return_distance=False)
print(nn_indices)
[[ 0 13]]
, которые:
print(X_train.iloc[np.squeeze(nn_indices)])
X1 X2 X3
8 0.375698 -0.600639 -0.291694 < - Same point in X_train
3 0.542560 -0.463418 -0.465730 < - Second closest point in X_train
Это означает, что строки 0
и 13
в X_train
являются ближайшими к точке [ 0.375698 -0.600639 -0.291694]
Чтобы сопоставить их с именами, вы можете используйте:
print(df["Name"][np.squeeze(X_train.index.values[nn_indices])])
8 800
3 300
Name: Name, dtype: int64
Если вы не установили return_distance=False
, вы заметите, что первое значение расстояния равно нулю (расстояние до точки, которая оказывается самой собой, равно нулю)
nn_distances, nn_indices = knn.kneighbors(X=X_test.loc[[9]])
print(nn_distances)
[[0. 0.27741858]]
Вы также можете использовать аргумент n_neighbors
, чтобы получить больше ближайших соседей. По умолчанию он будет работать для значения, используемого при подгонке модели .
Редактировать:
Для всего X_test
вы можете сделать:
nn_indices = knn.kneighbors(X=X_test, return_distance=False)
pd.DataFrame(nn_indices).applymap(lambda x: df["Name"][X_train.index.values[x]])
0 1
0 1900 0
1 1500 1600
2 1500 0
3 1500 1600
4 800 300