网格搜索

对给定参数进行组合,用某标准进行评价,只适合小数据集

class sklearn.model\_selection.GridSearchCV(estimator, param\_grid, scoring=None, fit\_params=None, n\_jobs=None, iid=’warn’, refit=True, cv=’warn’, verbose=0,   
pre\_dispatch=‘2\*n\_jobs’, error\_score=’raise\-deprecating’, return\_train\_score=’warn’)
  • 1.
  • 2.

参数

estimator:一个学习器对象,它必须有.fit方法用于学习,.predict方法用于预测,.score方法用于评分

param_grid:字典或者字典的列表,每个字典是学习器的一个参数,key是参数名,value是备选参数序列

scoring:评分函数,可以是一个字符串,或一个可调用对象,或者None

如果是None,使用学习器的.score方法,

如果是字符串,可以为如下值:

accuracy:用 metrics.accuracy_score 评分函数

average_precision:用 metrics.average_precision_score 评分函数

f1系列:用 metrics.f1_score 评分函数

f1:用于二分类

f1_micro:micro_averaged

f1_macro:macro_averaged

f1_weighted:weighted average

f1_samples:by multilabel sample

log_loss:用 metrics.log_loss 评分函数

precision:用 metrics.precision_score 评分函数,具体形式类似f1系列

recall:用 metrics.recall_score 评分函数,具体形式类似f1系列

roc_auc:用的是 metrics.roc_auc_score 评分函数

adjusted_rand_score:

mean_absolute_error:

mean_squared_error:

median_absolute_error:

r2:

fit_params:字典形式,用于给学习器的fit传递参数

n_jobs:并行性,默认为-1或None,表示派发任务到所有计算机的cpu上

iid:样本独立同分布,bool值

refit:bool值,如果为True,表示在参数优化之后,使用整个数据集来重新训练该最优的estimator

cv:一个整数,k折交叉生成器,一个迭代器,或者None

如果为None,使用3折交叉验证

如果为整数k,使用k这交叉验证

如果为k折交叉验证生成器

迭代器

verbose:整数,控制输出日志的内容,该值越大,输出越多的内容

pre_dispatch:整数或者字符串,控制并行执行时分发的总的任务量

error_score:

return_train_score:

属性

grid_scores_:命名元组组成的列表,列表中每个元素代表参数组合的得分

best_estimator_:一个学习器对象,代表最后的最优学习器

best_score_:最佳学习器的得分

best_params_:最佳参数组合

方法

fit:执行参数优化

predict:使用学习到的最佳学习器预测数据

predict_log_proba(x):使用最佳学习器来预测属于每个类别的概率的对数值

predict_proba(x):使用最佳学习器来预测属于每个类别的概率

score:最佳学习器的评分

示例代码

from sklearn.datasets import load\_digits
from sklearn.linear\_model import LogisticRegression
from sklearn.metrics import classification\_report
from sklearn.model\_selection import train\_test\_split, GridSearchCV

###
digits = load\_digits()
X\_train, X\_test, y\_train, y\_test \= train\_test\_split(digits.data, digits.target, test\_size=0.25, random\_state=0, stratify=digits.target)

###
tuned\_parameters = \[{'penalty':\['l1', 'l2'\], 'C':\[0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100\], 'solver':\['liblinear'\], 'multi\_class':\['ovr'\]},
                    {'penalty':\['l2'\], 'C':\[0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100\], 'solver':\['lbfgs'\], 'multi\_class':\['ovr', 'multinomial'\]}\]

clf \= GridSearchCV(LogisticRegression(tol=1e-6), tuned\_parameters, cv=10)
clf.fit(X\_train, y\_train)
print(clf.best\_params\_)                     # {'penalty': 'l2', 'multi\_class': 'multinomial', 'C': 0.01, 'solver': 'lbfgs'}

for i in clf.grid\_scores\_:
    print(i)

# mean: 0.93022, std: 0.01571, params: {'penalty': 'l1', 'multi\_class': 'ovr', 'C': 0.01, 'solver': 'liblinear'}
# mean: 0.96511, std: 0.01095, params: {'penalty': 'l2', 'multi\_class': 'ovr', 'C': 0.01, 'solver': 'liblinear'}
# mean: 0.96437, std: 0.01082, params: {'penalty': 'l1', 'multi\_class': 'ovr', 'C': 0.05, 'solver': 'liblinear'}
# mean: 0.96511, std: 0.01164, params: {'penalty': 'l2', 'multi\_class': 'ovr', 'C': 0.05, 'solver': 'liblinear'}
# ...
# mean: 0.95100, std: 0.01262, params: {'penalty': 'l1', 'multi\_class': 'ovr', 'C': 1, 'solver': 'liblinear'}
# mean: 0.95323, std: 0.01390, params: {'penalty': 'l2', 'multi\_class': 'ovr', 'C': 1, 'solver': 'liblinear'}
# mean: 0.95249, std: 0.01096, params: {'penalty': 'l1', 'multi\_class': 'ovr', 'C': 5, 'solver': 'liblinear'}
# mean: 0.95100, std: 0.01237, params: {'penalty': 'l2', 'multi\_class': 'ovr', 'C': 5, 'solver': 'liblinear'}
# ...
# mean: 0.94358, std: 0.01260, params: {'penalty': 'l2', 'multi\_class': 'ovr', 'C': 50, 'solver': 'lbfgs'}
# mean: 0.95768, std: 0.01487, params: {'penalty': 'l2', 'multi\_class': 'multinomial', 'C': 50, 'solver': 'lbfgs'}
# mean: 0.93690, std: 0.01520, params: {'penalty': 'l2', 'multi\_class': 'ovr', 'C': 100, 'solver': 'lbfgs'}
# mean: 0.95620, std: 0.01314, params: {'penalty': 'l2', 'multi\_class': 'multinomial', 'C': 100, 'solver': 'lbfgs'}

print(clf.score(X\_test, y\_test))            # 0.973333333333
pred \= clf.predict(X\_test)
print(classification\_report(y\_test, pred))
#               precision    recall  f1-score   support
#
#           0       1.00      1.00      1.00        45
#           1       0.87      0.98      0.92        46
#           2       1.00      0.98      0.99        44
#           3       1.00      1.00      1.00        46
#           4       1.00      0.96      0.98        45
#           5       0.96      0.98      0.97        46
#           6       1.00      0.98      0.99        45
#           7       1.00      1.00      1.00        45
#           8       0.93      0.88      0.90        43
#           9       1.00      0.98      0.99        45
#
# avg / total       0.97      0.97      0.97       450
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.

随机搜索

随机搜索的原理和网格搜索是一致的,只是随机搜索在取参数值时是随机取值,其主要解决以下问题

1. 参数很多

2. 参数取值是连续的,或者参数取值范围很大,或者参数可取值非常多

随机取值其实不是完全随机,如根据参数取值的分布进行采样,其实也可以自己定义

class sklearn.model\_selection.RandomizedSearchCV(estimator, param\_distributions, n\_iter=10, scoring=None, fit\_params=None, n\_jobs=None, iid=’warn’, refit=True,   
cv=’warn’, verbose=0, pre\_dispatch=‘2\*n\_jobs’, random\_state=None, error\_score=’raise\-deprecating’, return\_train\_score=’warn’)\[source\]
  • 1.
  • 2.

参数

参数与gridsearchCV大致相同,简单解释下

param_distributions:相当于上面的param_grid,只是字典的值是个分布,通常使用scipy.stats模块提供的分布类,如 scipy.expon 指数分布,scipy.gamma gamma分布,scipy.uniform 均匀分布等

n_iter:整数,指定每个参数采样的数量,通常该值越大,参数优化效果越好,但计算量也越大

{'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1),'kernel': \['rbf'\], 'class\_weight':\['balanced', None\]}
  • 1.

属性

cv_results_:不同参数组合的得分

best_params_,best_score_ 等

示例代码

from sklearn.datasets import load\_iris
from sklearn.neighbors import KNeighborsClassifier  # 要估计的是knn里面的参数,包括k的取值和样本权重分布方式 
from sklearn.model\_selection import GridSearchCV,RandomizedSearchCV 

iris \= load\_iris()
X \= iris.data  
y \= iris.target 

k\_range \= range(1, 31)  # 优化参数k的取值范围
weight\_options = \['uniform', 'distance'\]  # 代估参数权重的取值范围。uniform为统一取权值,distance表示距离倒数取权值
param\_grid = {'n\_neighbors':k\_range,'weights':weight\_options}  # 字典中的key值必须是分类算法的函数的参数名
print(param\_grid)

knn \= KNeighborsClassifier(n\_neighbors=5)  

# ================================网格搜索=======================================
# 这里GridSearchCV的参数形式和cross\_val\_score的形式差不多,其中param\_grid是parameter grid所对应的参数
# GridSearchCV中的n\_jobs设置为-1时,可以实现并行计算(如果你的电脑支持的情况下)
grid = GridSearchCV(estimator = knn, param\_grid = param\_grid, cv=10, scoring='accuracy') #针对每个参数对进行了10次交叉验证。scoring='accuracy'使用准确率为结果的度量指标。可以添加多个度量指标
grid.fit(X, y)

print('网格搜索-度量记录:',grid.cv\_results\_)  # 包含每次训练的相关信息
print('网格搜索-最佳度量值:',grid.best\_score\_)  # 获取最佳度量值
print('网格搜索-最佳参数:',grid.best\_params\_)  # 获取最佳度量值时的代定参数的值。是一个字典
print('网格搜索-最佳模型:',grid.best\_estimator\_)  # 获取最佳度量时的分类器模型

# 使用获取的最佳参数生成模型,预测数据
knn = KNeighborsClassifier(n\_neighbors=grid.best\_params\_\['n\_neighbors'\], weights=grid.best\_params\_\['weights'\])  
knn.fit(X, y)  
print(knn.predict(\[\[3, 5, 4, 2\]\]))  

# =====================================随机搜索===========================================
rand = RandomizedSearchCV(knn, param\_grid, cv=10, scoring='accuracy', n\_iter=10, random\_state=5)  #
rand.fit(X, y)

print('随机搜索-度量记录:',grid.cv\_results\_)  # 包含每次训练的相关信息
print('随机搜索-最佳度量值:',grid.best\_score\_)  # 获取最佳度量值
print('随机搜索-最佳参数:',grid.best\_params\_)  # 获取最佳度量值时的代定参数的值。是一个字典
print('随机搜索-最佳模型:',grid.best\_estimator\_)  # 获取最佳度量时的分类器模型

# 使用获取的最佳参数生成模型,预测数据
knn = KNeighborsClassifier(n\_neighbors=grid.best\_params\_\['n\_neighbors'\], weights=grid.best\_params\_\['weights'\])  
knn.fit(X, y)  
print(knn.predict(\[\[3, 5, 4, 2\]\]))  

# =====================================自定义度量===========================================
from sklearn import metrics
# 自定义度量函数
def scorerfun(estimator, X, y):
    y\_pred \= estimator.predict(X)
    return metrics.accuracy\_score(y, y\_pred)

rand \= RandomizedSearchCV(knn, param\_grid, cv=10, scoring=scorerfun, n\_iter=10, random\_state=5)  #
rand.fit(X, y)

print('随机搜索-最佳度量值:',grid.best\_score\_)  # 获取最佳度量值
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.