4.5 超参数
- 超参数就是指在运行机器学习算法之前,需要指定的参数。
- 模型参数:算法过程中学习的参数。
- KNN算法没有模型参数,k是典型的超参数。
- 调参一般说的就是超参数</br>
如何寻找到一个好的超参数呢?
- 领域知识
- 经验数值
- 实验搜索
import numpy as np
from sklearn import datasets
# 加载手写数字数据集
digits = datasets.load_digits()
X = digits.data
y = digits.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=666)
from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train, y_train)
knn_clf.score(X_test, y_test)
寻找最好的k
# 初始设置为0
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=10,这时候我们需要将设定的范围扩大,将range变为(8,20)在重新寻找一下最好的k值。因为一般最好的k取到边界值时,有可能最好的在边界外。</br>
除了k之外,k近邻算法还有一个超参数。</br>
看下面的示例图,按照普通的k近邻算法,新的样本点(绿色点)计算与它周围最近的三个点,发现蓝色个数一共有2个,所以蓝色获胜。但是其实样本点是距离红色是最近的,所以在这种情况下是不是红色点的权重应该要比蓝色点的要重一些呢?这就是k近邻的另外一个用法,考虑了距离的权重
。
image
通常而言,我们考虑的
距离权重是将距离的倒数作为权重
。距离越近权重越大。</br>红色是1,蓝色是1/3+1/4=7/12 红色胜
考虑距离权重还有一个优点。比如之前的普通方法有可能选取的最近的三个点是三类点,出现平票的情况,这时候会随机选择一个点作为预测点,显然这样也是不合理的。所以加入了距离的权重之后,可以根据三点之间的距离权重选择更为精确的预测点。
考虑距离?不考虑距离?
best_method = ""
best_score = 0.0
best_k = -1
# weights有两个值,默认不使用是uniform
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)
运行结果如下:
image
更多关于距离的定义
曼哈顿距离
image
曼哈顿距离就是点在每个维度的距离之和。在这个图中,红黄紫色的都是曼哈顿距离,而绿色就是欧拉距离。
欧拉距离
对欧拉距离
公式进行变形,整理可得
而曼哈顿距离
也可以写成如下的形式:
因此我们可以统一表达式为:
那么,我们称这个式子为明科夫斯基距离(Minkowski Distance)
。当p为1时,就是曼哈顿距离,为2时就是欧拉距离,从这个公式中,我们得到了一个超参数p。
搜索明科夫斯基距离p
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")
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)
运行结果如下:
image