In [8]:
import numpy as np

from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn import preprocessing, datasets
from sklearn.neighbors import KNeighborsRegressor
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

1. Загрузите выборку Boston с помощью функции sklearn.datasets.load_boston(). Результатом вызова данной функции является объект, у которого признаки записаны в поле data, а целевой вектор — в поле target.


In [9]:
boston = datasets.load_boston()
X_train = boston.data
y_train = boston.target

2. Приведите признаки в выборке к одному масштабу при помощи функции sklearn.preprocessing.scale.


In [10]:
X_train_scaled = preprocessing.scale(X_train)

3. Переберите разные варианты параметра метрики p по сетке от 1 до 10 с таким шагом, чтобы всего было протестировано 200 вариантов (используйте функцию numpy.linspace). Используйте KNeighborsRegressor с n_neighbors=5 и weights='distance' — данный параметр добавляет в алгоритм веса, зависящие от расстояния до ближайших соседей. В качестве метрики качества используйте среднеквадратичную ошибку (параметр scoring='mean_squared_error' у cross_val_score; при использовании библиотеки scikit-learn версии 0.18.1 и выше необходимо указывать scoring='neg_mean_squared_error'). Качество оценивайте, как и в предыдущем задании, с помощью кросс-валидации по 5 блокам с random_state = 42, не забудьте включить перемешивание выборки (shuffle=True).


In [11]:
kf = KFold(n_splits=5, random_state=42, shuffle=True)
minkovsky = np.linspace(1, 10, num=200)
means = dict()

for p in minkovsky:
    knn = KNeighborsRegressor(p=p, n_neighbors=5, weights='distance')
    score = cross_val_score(knn, X_train_scaled, y_train, cv=kf, scoring='neg_mean_squared_error')
    score_mean = np.mean(score)
    means[p] = score_mean

4. Определите, при каком p качество на кросс-валидации оказалось оптимальным. Обратите внимание, что cross_val_score возвращает массив показателей качества по блокам; необходимо максимизировать среднее этих показателей. Это значение параметра и будет ответом на задачу.


In [12]:
max_key_by_value = max(means, key=means.get)
max_key_by_value
means[max_key_by_value]


Out[12]:
1.0
Out[12]:
-16.050208508436157