机器学习探索计划——KNN的超参数搜索

文章目录

  • 数据加载
  • 手写超参数搜索
  • sklearn 超参数搜索

数据加载

import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
x = iris.data
y = iris.target
x.shape, y.shape
((150, 4), (150,))
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.7, random_state=666, stratify=y)

x_train.shape, x_test.shape, y_train.shape, y_test.shape
((105, 4), (45, 4), (105,), (45,))

random_state的取值不同,最后算法的预测结果也会收到影响,比如我这里设置为233,最后会更容易得到100%的结果,原因是取值不同会导致训练集和测试集划分不同,进而影响训练和测试数据的组合。

手写超参数搜索

from sklearn.neighbors import KNeighborsClassifier
neigh = KNeighborsClassifier(
    n_neighbors=3,
    weights='distance',
    p=2
)

n_neighbors: 设置为3,表示在进行分类时考虑最近的3个邻居的标签。
weights: 设置为’distance’,表示使用距离的倒数作为权重。这意味着与目标样本距离越近的邻居对分类的贡献越大。如果将其设置为’uniform’,则所有邻居的权重都相等。
p: 设置为2,表示使用欧氏距离作为距离度量。如果p设置为1,则使用曼哈顿距离。

neigh.fit(x_train, y_train)
neigh.score(x_test, y_test)
0.9333333333333333
best_score = -1
best_n = -1
best_weight = ''
best_p = -1

for n in range(1, 20):
    for weight in ['uniform', 'distance']:
        for p in range(1, 7):
            neigh = KNeighborsClassifier(
                n_neighbors=n,
                weights=weight,
                p=p
            )
            neigh.fit(x_train, y_train)
            score = neigh.score(x_test, y_test)
            
            if score > best_score:
                best_score = score
                best_n = n
                best_p = p
                best_weight = weight
            
print("n_neighbors:", best_n)
print("weights:", best_weight)
print("p:", best_p)
print("score:", best_score)
n_neighbors: 8
weights: uniform
p: 2
score: 0.9777777777777777

当p为整数值时,常用的取值为1和2:
p = 1:表示使用曼哈顿距离(Manhattan distance),也称为L1距离。它是从一个点到另一个点沿着网格线的距离,即两点横坐标差的绝对值加上纵坐标差的绝对值。
p = 2:表示使用欧氏距离(Euclidean distance),也称为L2距离。它是从一个点到另一个点的直线距离,即两点之间的直线距离的平方根。

当p为浮点数时,表示使用闵可夫斯基距离(Minkowski distance)。闵可夫斯基距离是曼哈顿距离和欧氏距离的一般化形式,可以根据p的值调整距离的计算方式。当p趋近于无穷大时,闵可夫斯基距离逐渐变为切比雪夫距离(Chebyshev distance)。

sklearn 超参数搜索

from sklearn.model_selection import GridSearchCV
params = {
    'n_neighbors': [n for n in range(1, 30)],
    'weights': ['uniform', 'distance'],
    'p': [p for p in range(1, 7)]
}
grid = GridSearchCV(
    estimator=KNeighborsClassifier(),
    param_grid=params,
    n_jobs=-1  # 使用所有可用的CPU
)
grid.fit(x_train, y_train)
grid.best_params_, grid.best_score_
({'n_neighbors': 3, 'p': 2, 'weights': 'uniform'}, 0.9904761904761905)
grid.best_estimator_.predict(x_test)
grid.best_estimator_.score(x_test, y_test)
0.9333333333333333

发现结果与之前手写的超参数搜索的不同,这是准确度计算方法不同导致的。

你可能感兴趣的:(机器学习,人工智能)