Хочу уточнить одну вещь. Я знаю, что следующая команда сгенерирует равномерно распределенную случайную величину между (loc, loc + scale)

from scipy.stats import uniform
C =uniform.rvs(loc=0,scale=4)
print(C)

И давайте предположим, что я хочу использовать это распределение в логистической регрессии при использовании алгоритма RandomiizedSearchCV, как показано ниже:

parameters =dict(C =uniform(loc=0,scale=4),penalty=['l2', 'l1'])
from sklearn.model_selection import RandomizedSearchCV
clf = RandomizedSearchCV(logreg, parameters, random_state=0)
search = clf.fit(iris.data, iris.target)
print(search.best_params_)

Но я не понял одного: RandomizedSearchCV похож на поиск по сетке, просто он пытается выбрать случайное число комбинации с заданным количеством проб (n_iter), но здесь C - это объект, это не array или что-то в этом роде, даже я не могу распечатать его значение, так как я могу понять этот код? как он генерирует случайное число? без указания РВС?

0
dato datuashvili 18 Июн 2020 в 19:33

1 ответ

Лучший ответ

Не совсем понятно, в чем именно заключается ваш вопрос. Тем не менее, согласно документации для param_distributions аргумент (здесь parameters):

Словарь с именами параметров (str) в качестве ключей и распределениями или списками параметров для проверки. Распределения должны предоставлять метод rvs для выборки (например, из scipy.stats.distributions). Если список дан, он выбирается единообразно.

Итак, что происходит на каждой итерации:

  • Выберите значение для C в соответствии с равномерным распределением в [0, 4]
  • Выберите значение для penalty, равномерно между l1 и l2 (т.е. с вероятностью 50% для каждого)
  • Используйте эти выборочные значения для составления резюме и сохраните результаты.

Используя пример из документации (практически идентичный остроумию параметры в вашем вопросе):

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform

iris = load_iris()
logistic = LogisticRegression(solver='saga', tol=1e-2, max_iter=200,
                               random_state=0)
distributions = dict(C=uniform(loc=0, scale=4),
                      penalty=['l2', 'l1'])

clf = RandomizedSearchCV(logistic, distributions, random_state=0)
search = clf.fit(iris.data, iris.target)

Мы получили

search.best_params_
# {'C': 2.195254015709299, 'penalty': 'l1'}

Мы можем пойти еще дальше и увидеть все (10) используемых комбинаций, а также их производительность:

import pandas as pd
df = pd.DataFrame(search.cv_results_)
print(df[['params','mean_test_score']])
# result:
                                        params  mean_test_score
0    {'C': 2.195254015709299, 'penalty': 'l1'}         0.980000
1   {'C': 3.3770629943240693, 'penalty': 'l1'}         0.980000
2   {'C': 2.1795327319875875, 'penalty': 'l1'}         0.980000
3   {'C': 2.4942547871438894, 'penalty': 'l2'}         0.980000
4     {'C': 1.75034884505077, 'penalty': 'l2'}         0.980000
5  {'C': 0.22685190926977272, 'penalty': 'l2'}         0.966667
6   {'C': 1.5337660753031108, 'penalty': 'l2'}         0.980000
7   {'C': 3.2486749151019727, 'penalty': 'l2'}         0.980000
8   {'C': 2.2721782443757292, 'penalty': 'l1'}         0.980000
9     {'C': 3.34431505414951, 'penalty': 'l2'}         0.980000

Откуда действительно очевидно, что все запрошенные значения C были в [0, 1], как и было запрошено. Кроме того, поскольку было несколько комбинаций, получивших лучший результат 0,98, scikit-learn использует первую, возвращенную в cv_results_.

Присмотревшись, мы видим, что только 4 испытания были выполнены со штрафом l1 (а не 50% из 10, т.е. 5, как можно было бы ожидать), но этого следовало ожидать с небольшими случайными выборками (здесь только 10).

1
desertnaut 18 Июн 2020 в 17:22