Scikit-learn: как определить параметр метрики расстояния для поиска в сетке
У меня есть следующий фрагмент кода, который пытается выполнить поиск сетки, в которой один из параметров сетки является метрикой расстояния, которая будет использоваться для алгоритма KNN. В приведенном ниже примере произойдет сбой, если я использую метрики расстояний "wminkowski", "seuclidean" или "mahalanobis".
# Define the parameter values that should be searched
k_range = range(1,31)
weights = ['uniform' , 'distance']
algos = ['auto', 'ball_tree', 'kd_tree', 'brute']
leaf_sizes = range(10, 60, 10)
metrics = ["euclidean", "manhattan", "chebyshev", "minkowski", "mahalanobis"]
param_grid = dict(n_neighbors = list(k_range), weights = weights, algorithm = algos, leaf_size = list(leaf_sizes), metric=metrics)
param_grid
# Instantiate the algorithm
knn = KNeighborsClassifier(n_neighbors=10)
# Instantiate the grid
grid = GridSearchCV(knn, param_grid=param_grid, cv=10, scoring='accuracy', n_jobs=-1)
# Fit the models using the grid parameters
grid.fit(X,y)
Я предполагаю, что это потому, что я должен установить или определить диапазоны для различных параметров расстояния (например, p, w для "wminkowski" - WMinkowskiDistance). Расстояние "Минковского" может работать, потому что его параметр "p" имеет значение по умолчанию 2.
Итак, мои вопросы:
- Можем ли мы установить диапазон параметров для метрик расстояния для поиска по сетке, и если да, то как?
- Можем ли мы установить значение параметров для метрик расстояния для поиска в сетке, и если да, то как?
Надеюсь, вопрос ясен. ТИА
1 ответ
Я наконец получил ответ с помощью списка рассылки пользователей и разработчиков Scikit. Я помещаю сюда то, что я узнал, в надежде, что это поможет и другим.
Ответ на два вопроса выше: да. Вот пример кода, который я получил из списка рассылки:
params = [{'kernel':['poly'],'degree':[1,2,3],'gamma':[1/p,1,2],'coef0':[-1,0,1]},
{'kernel':['rbf'],'gamma':[1/p,1,2]},
{'kernel':['sigmoid'],'gamma':[1/p,1,2],'coef0':[-1,0,1]}]
Следует отметить две вещи:
Вы можете перечислить набор параметров, для каждого набора вы можете разместить только то, что требуется для группы параметров. Это означает, что мы можем выбрать метрику и соответствующие параметры. Параметры именуются с помощью клавиш.
Для каждого из ключей мы можем использовать список значений - каждая комбинация этих значений будет использоваться при поиске по сетке и передаваться соответствующей метрической функции.
Это все еще оставляет нас с проблемой: как мы передаем комбинацию параметров в метрику. Примечание: не все метрики могут использоваться алгоритмом, поэтому вы должны установить их вручную.
Теперь я покажу пример, который я просил выше:
{'metric': ['wminkowski'],
'metric_params':[
{'w':np.array([2.0] * len(X.columns)),'p':1.0}, # L1
{'w':np.array([2.0] * len(X.columns)),'p':1.5},
{'w':np.array([2.0] * len(X.columns)),'p':2.0}, # L2
{'w':np.array([2.0] * len(X.columns)),'p':2.5},
{'w':np.array([2.0] * len(X.columns)),'p':3.5},
{'w':np.array([2.0] * len(X.columns)),'p':3.0}
],
'algorithm': ['brute', 'ball_tree'],
'n_neighbors': list(k_range), 'weights': weights, 'leaf_size': list(leaf_sizes) }
Обратите внимание на следующее:
'wminkowski'
работает только с['brute', 'ball_tree']
алгоритмы.- Мы должны использовать список словарей в
'metric_params'
Для того, чтобы перечислить все возможные комбинации параметров (я не нашел способ автоматизировать это). - В приведенном выше случае я был вынужден использовать массив NumPy, потому что преобразование не было сделано неявно (в противном случае мы получаем исключение)
Кто-нибудь знает лучший способ сделать это, пожалуйста, прокомментируйте.