代码之家  ›  专栏  ›  技术社区  ›  user2051561

Scikit学习:如何定义网格搜索的距离度量参数

  •  2
  • user2051561  · 技术社区  · 8 年前

    我有以下代码片段,尝试进行网格搜索,其中一个网格参数是用于KNN算法的距离度量。如果我使用“wminkowski”、“seucidean”或“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)
    

    我认为这是因为我必须设置或定义各种距离参数的范围(例如,对于wminkowski-WMinkowskiDistance,p、w)。“minkowski”距离可能有效,因为其“p”参数的默认值为2。

    所以我的问题是:

    1. 我们可以为网格搜索设置距离度量的参数范围吗?如果可以,如何设置?
    2. 我们可以为网格搜索的距离度量设置参数值吗?如果可以,如何设置?

    希望问题是清楚的。 TIA公司

    1 回复  |  直到 8 年前
        1
  •  4
  •   user2051561    8 年前

    在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]}]
    

    需要注意两件事:

    1. 您可以列出一组参数,对于每组参数,您可以只放置参数组所需的内容。这意味着我们可以选择度量和相应的参数。这些参数是使用键命名的。

    2. 对于每个键,我们可以使用一个值列表-网格搜索将使用这些值的每个组合,并传递给相应的度量函数。

    这仍然给我们留下了一个问题:如何将参数组合传递给度量。注意:并非所有指标都可以由算法使用,因此您必须手动设置这些指标。

    我现在展示我上面要求的示例:

    {'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) } 
    

    请注意以下事项:

    1. 'wminkowski' 仅适用于 ['brute', 'ball_tree'] 算法。
    2. 我们必须在 'metric_params' 为了枚举所有可能的参数组合(我还没有找到自动化的方法)。
    3. 在上面的例子中,我被迫使用numpy数组,因为转换不是隐式进行的(否则会出现异常)

    任何人都知道一种更好的方法,请评论。