当前位置: 首页 > 面试题库 >

从GridSearchCV检索特定的分类器和数据

岑经纶
2023-03-14
问题内容

我正在使用以下代码在服务器上运行Python 3分类脚本:

# define knn classifier for transformed data
knn_classifier = neighbors.KNeighborsClassifier()

# define KNN parameters
knn_parameters = [{
    'n_neighbors': [1,3,5,7, 9, 11],
    'leaf_size': [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60],
    'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],
    'n_jobs': [-1],
    'weights': ['uniform', 'distance']}]

# Stratified k-fold (default for classifier)
# n = 5 folds is default
knn_models = GridSearchCV(estimator = knn_classifier, param_grid = knn_parameters, scoring = 'accuracy')

# fit grid search models to transformed training data
knn_models.fit(X_train_transformed, y_train)

然后,我GridSearchCV使用保存对象pickle

# save model
with open('knn_models.pickle', 'wb') as f:
    pickle.dump(knn_models, f)

因此,我可以通过运行以下命令在本地计算机上的较小数据集中测试分类器:

knn_models = pickle.load(open("knn_models.pickle", "rb"))
validation_knn_model = knn_models.best_estimator_

如果我只想评估验证集中的最佳估计量,那就太好了。但是我实际上想做的是:

  • GridSearchCV对象中拉出原始数据(我假设它存储在对象中的某个位置,因为要对新的验证集进行分类,这是必需的)
  • 尝试使用一些特定的分类器,这些分类器具有由网格搜索确定的几乎所有最佳参数,但是会更改特定的输入参数,即 k = 3, 5, 7
  • 检索y_pred我上面测试的所有新分类器的每个验证集的预测

问题答案:

GridSearchCV不包含原始数据(如果包含原始数据,那将是荒谬的)。它包括的唯一数据是它自己的簿记,即每个CV折页尝试的详细得分和参数。在best_estimator_返回的是该模型适用于遇到的任何新数据所需要的唯一的事,但如果像你说的,你想在细节上深入挖掘,充分结果在其返回cv_results_属性。

使用您自己的网格将示例从文档改编为knn分类器knn_parameters(但是删除n_jobs,这只会影响拟合速度,并且不是算法的真正超参数),cv=3为简单起见,我们拥有:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import GridSearchCV
import pandas as pd

iris = load_iris()
knn_parameters = [{
    'n_neighbors': [1,3,5,7, 9, 11],
    'leaf_size': [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60],
    'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],
    'weights': ['uniform', 'distance']}]

knn_classifier = KNeighborsClassifier()
clf = GridSearchCV(estimator = knn_classifier, param_grid = knn_parameters, scoring = 'accuracy', n_jobs=-1, cv=3)
clf.fit(iris.data, iris.target)

clf.best_estimator_
# result:
KNeighborsClassifier(algorithm='auto', leaf_size=5, metric='minkowski',
                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,
                     weights='uniform')

因此,如上所述,最后的结果告诉您将算法应用于任何新数据(验证,测试,来自部署等)的所有知识。此外,您可能会发现,实际上除去n_jobs从进入knn_parameters电网和要求,而不是用于n_jobs=-1GridSearchCV一个对象中的结果
快CV过程。不过,如果您想使用n_jobs=-1最终模型,则可以轻松地操纵best_estimator_来做到这一点:

clf.best_estimator_.n_jobs = -1
clf.best_estimator_
# result
KNeighborsClassifier(algorithm='auto', leaf_size=5, metric='minkowski',
                     metric_params=None, n_jobs=-1, n_neighbors=5, p=2,
                     weights='uniform')

这实际上回答了您的第二个问题,因为您也可以类似地操纵best_estimator_来更改其他超参数。

因此,找到最好的模型是大多数人停止的地方。但是,如果出于某种原因想要进一步深入了解整个网格搜索过程的详细信息,则将在cv_results_属性中返回详细结果,甚至可以将其导入到pandas数据框中以方便检查:

cv_results = pd.DataFrame.from_dict(clf.cv_results_)

例如,cv_results数据框包括一列rank_test_score,顾名思义,该列包含每个参数组合的等级:

cv_results['rank_test_score']
# result:
0      481
1      481
2      145
3      145
4        1
      ... 
571      1
572    145
573    145
574    433
575      1
Name: rank_test_score, Length: 576, dtype: int32

这里的1意思是最好的,您可以很容易地看到有不止一种组合被排名为1-因此,实际上,我们这里有不止一种“最佳”模型(即参数组合)!尽管在这里这很可能是由于所用虹膜数据集的相对简单性,但原则上也没有理由在实际情况下也不会发生这种情况。在这种情况下,返回best_estimator_的只是这些情况中的第一个-
这里是组合编号4:

cv_results.iloc[4]
# result:
mean_fit_time                                              0.000669559
std_fit_time                                               1.55811e-05
mean_score_time                                             0.00474652
std_score_time                                             0.000488042
param_algorithm                                                   auto
param_leaf_size                                                      5
param_n_neighbors                                                    5
param_weights                                                  uniform
params               {'algorithm': 'auto', 'leaf_size': 5, 'n_neigh...
split0_test_score                                                 0.98
split1_test_score                                                 0.98
split2_test_score                                                 0.98
mean_test_score                                                   0.98
std_test_score                                                       0
rank_test_score                                                      1
Name: 4, dtype: object

您可以轻松地看到与我们best_estimator_上面的参数相同的参数。但是现在您可以通过以下方法检查所有“最佳”模型:

cv_results.loc[cv_results['rank_test_score']==1]

就我而言,这将导致不少于144个模型(在6*12*4*2 = 576尝试的所有模型中)!因此,您实际上可以在更多选择中进行选择,甚至可以使用其他附加条件,例如返回分数的标准偏差(越小越好,尽管此处的最小值为0),而不是仅仅依赖于最大平均分数,这是自动过程将返回的分数。

希望这些足以让您入门…



 类似资料:
  • 我有一个用Java编写的管理应用程序,可以管理我的用户 我创建了一个自定义json 这就是我的JSON看起来的样子 在我的列表中,我只显示电子邮件地址 现在我的问题,例如,如果我单击包含电子邮件的列表,我想在对话框中显示与此电子邮件相关的数据,即、和 怎样​​我可以检索其他值吗​​使用电子邮件? 我在网上找不到任何关于它的信息

  • 请帮助我想从Firebase实时数据库检索一个特定的数据,我有2个用户,教授和学生,我想使用该数据进行验证。 FireBase实时数据库 FireBase实时数据库

  • 问题内容: 我有对象的Postgres JSONB数组,看起来像这样: 此JSONB是一个函数参数。 什么是最有效的检索方法 。 我尝试过玩,但是到目前为止我所做的一切看起来都非常混乱。 问题答案: 在 Postgres 9.4+中 ,可以在横向 联接中 使用该函数: 您可以通过一个简单的函数来实现该想法,例如: 在 Postgres 12+中, 您可以使用jsonb路径函数的形式来替代: Db

  • 问题内容: 我试图学习有关MySQL的更多信息,并使用Java(在Android上)从WAMS服务器上的数据库访问和检索信息。我的应用程序的设置方式是它具有一个初始登录屏幕,该屏幕还捕获(从另一个表中)登录的用户名的“ uid”并进行存储。 登录后(功能正常- 我设置了一个敬酒通知,其中显示了登录用户的检索到的用户名和uid),它会转到一个新屏幕(dashboard.xml),该屏幕具有一个Tex

  • 问题内容: 我正在使用一个每个键有两个值的Multimap。下面是我用来分别获取每个值的代码: 代码的第一位获取第一个对象值: 然后,我正在使用另一种方法来检索其他值。此方法将第一个对象作为参数: 这似乎是一种“骇人的”做事方式,那么我有什么办法可以更轻松地获得价值? 问题答案:

  • 当我试图检索recycleview中保存的数据时,它们显示的是所有用户的数据,而不是登录的用户。有人能帮忙吗?