【笔记】KNN之超参数

超参数

超参数

很多时候,对于算法来说,关于这个传入的参数,传什么样的值是最好的?
这就涉及到了机器学习领域的超参数
超参数简单来说就是在我们运行机器学习之前用来指定的那个参数,就是在算法运行前需要决定的参数
像是knn算法中的k就是典型的超参数

同时,还有一种是模型参数,即在算法过程中学习的参数,不过由于KNN算法没有模型参数,这里就不再赘述

那么怎么才能寻找到好的参数?
大致分为三点:
领域知识
经验数值
实验搜索
前两种是需要专业环境来养成,关于最后一种实验搜索就可以实践体现出来

实践部分(实验搜索)

为保证可复现,种子为666,数据集为sklearn的手写数字数据集

如果我们想要寻找一个好的k,可以使用一个循环,在初始的时候设置成最好的值为0,将for范围为从第二个参数开始的是个参数,那么我们在循环的过程中,每一次我们都创建一个knn_clf,进行fit操作,这样我们就可以得到当前k的分类准确度是多少
然后我们就可以开始比较,如果当前的score比历史上的score都好,那么就将现在的变成best_score,k同理,最后输出最好的k和其对应的预测准确率

  best_score = 0.0
  best_k = -1
  for k in range(1,11):
      knn_clf = KNeighborsClassifier(n_neighbors=k)
      knn_clf.fit(X_train ,y_train)
      score = knn_clf.score(X_test,y_test)
      if score > best_score:
          best_k = k
          best_score = score

  print("best_k =", best_k)
  print("best_score =",best_score)

然而k近邻算法中是不止一个K这样的超参数
还存在一个超参数,距离的权重(可使用倒数比较)

本来如果按照原有的knn算法,当出现三个不一样种类的情况的时候,我们只能随机出来得到一个样本,但是使用距离权重以后,可以有效地解决这种平票的问题

这样,我们引入距离这个想法以后,算法就变成了需不需要考虑距离这个要素的情况

  best_method = ""
  best_score = 0.0
  best_k = -1
  for method in ["uniform","distance"]:
      for k in range(1,11):
          knn_clf = KNeighborsClassifier(n_neighbors=k,weights = method)
          knn_clf.fit(X_train ,y_train)
          score = knn_clf.score(X_test,y_test)
          if score > best_score:
              best_k = k
              best_score = score
              best_method = method

  print("best_method =",best_method)  
  print("best_k =", best_k)
  print("best_score =",best_score)

输出结果

那么距离的定义到底是什么
我们到底需要使用哪种距离

通过对曼哈顿距离和欧拉距离的变形推广,我们可以得到明科夫斯基距离

这样我们就获得了一个新的超参数 p
在sklearn中,p的默认为2,相当于取得是欧拉距离
那么继续修改算法为

  %%time
  best_p = -1
  best_score = 0.0
  best_k = -1

  for k in range(1,11):
      for p in range(1,6):
          knn_clf = KNeighborsClassifier(n_neighbors=k,weights ="distance",p=p)
          knn_clf.fit(X_train ,y_train)
          score = knn_clf.score(X_test,y_test)
          if score > best_score:
              best_k = k
              best_score = score
              best_p = p

  print("best_p =",best_p)  
  print("best_k =", best_k)
  print("best_score =",best_score)

一般这种叫做网格搜索策略

posted @ 2021-01-14 12:43  DbWong_0918  阅读(878)  评论(0编辑  收藏  举报