根据documentation 的param_distributions 参数(此处为parameters):
以参数名称 (str) 作为键和分布或要尝试的参数列表的字典。发行版必须提供rvs 抽样方法(例如来自 scipy.stats.distributions 的抽样方法)。如果给定一个列表,则统一采样。
所以,每次迭代发生的事情是:
- 根据
[0, 4] 中的均匀分布对C 的值进行采样
- 为
penalty 采样一个值,统一在l1 和l2 之间(即每个都有50% 的概率)
- 使用这些采样值运行 CV 并存储结果
使用documentation 中的示例(实际上与您问题中的参数相同):
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, 4] 中,按照要求。此外,由于有多个组合达到了 0.98 的最佳分数,因此 scikit-learn 使用 cv_results_ 返回的第一个组合。
仔细观察,我们发现只有 4 次试验以 l1 惩罚(而不是 10 次中的 50%,即 5 次,正如我们预期的那样),但这对于小随机样本是可以预料的(这里只有 10 个)。