算法修炼——KNN(微进阶)

好了,又回来了。在进入本章之前,我们先来学一点东西:

超参数和模型参数:

那么我们应该怎样去寻找好的超参数呢?

一般来说有三个方法:领域知识、经验数值、实验搜索。

我们的knn也有两个很重要的超参数:1、k值的选取 。  2、距离的权重。

接下来让我们寻找最好的k值:

 首先我本次使用的是digits数字集:

digits = datasets.load_digits()
X = digits.data
y = digits.target

# 然后调用sklearn的分割函数,分割数据集(将数据集分为训练集和测试集)。

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

# 思路,遍历1-11 ,分别拿每一个k去调用knn算法,取出分值最高的那个k
best_k = -1
best_score = 0.0
for i in range(1,11):
    clf_knn1 = KNeighborsClassifier(n_neighbors=i)
    clf_knn1.fit(X_train,y_train)
    score = clf_knn1.score(X_test,y_test)
    if score > best_score:
        best_k = i
        best_score = score
# 如果best_k为10,则需要测试10以后的数。
print("best_k=",best_k)
print("best_score",best_score)

很明显,我们找到了最好的k值为4,这个时候我们的knn算法的准确度达到了99.1%。

 

大家应该能发现,上一章的knn算法有一个很明显的不足,那就是没有考虑距离的权重。我们来看一张图:

如果按照我们原来的那种算法,最后的结果就是目标点是蓝色,但是考虑权重以后目标点应该是红的。(般情况下使用距离的导数作为权证),而且,考虑权重可以帮助我们解决平票的问题。

接下来,让我们用代码验证一下考虑距离与不考虑距离的区别:

# 思路,遍历1-11 ,分别拿每一个k去调用knn算法,取出分值最高的那个k
best_method = ""
best_k = -1
best_score = 0.0
for m in ["uniform","distance"]:
    for i in range(1,11):
        clf_knn1 = KNeighborsClassifier(n_neighbors=i,weights=m)
        clf_knn1.fit(X_train,y_train)
        score = clf_knn1.score(X_test,y_test)
        if score > best_score:
            best_k = i
            best_score = score
            best_method = m
# 如果best_k为10,则需要测试10以后的数。
print("best_k=",best_k)
print("best_score=",best_score)
print("best_method=",best_method)

由结果我们发现,对于我们的数字集还是不考虑距离权重的结果更好,但这只是个例,接下来我们还是引入距离的概念:

那么我们既然要考虑距离,那么我们需要考虑的是什么距离?

1、欧拉距离

2、曼哈顿距离:

什么是曼哈顿距离,就是X1,X2两个样本在每个维度上的差值的和。

 我们可以发现欧拉距离和曼哈顿距离在数学形式上具有一定的一致性:

最后我们可以推广出一个公式,数学上称这个距离为:明克夫斯基距离。

然后,我们就获得了一个新的超参数:p

接下来,让我用代码搜索明可夫斯基距离相应的p:

# 思路,遍历1-11 ,分别拿每一个k去调用knn算法,取出分值最高的那个k
best_p = -1
best_k = -1
best_score = 0.0
for i in range(1,11):
    for p in range(1,6):
        clf_knn1 = KNeighborsClassifier(n_neighbors=i,weights="distance",p=p)
        clf_knn1.fit(X_train,y_train)
        score = clf_knn1.score(X_test,y_test)
        if score > best_score:
            best_k = i
            best_score = score
            best_p = p
# 如果best_k为10,则需要测试10以后的数。
print("best_k=",best_k)
print("best_score",best_score)
print("best_p=",best_p)

关于网格搜索,归一化问题,下一章再做介绍。

刚刚开始学习,有不对的地方,还望多多指正。

### KNN算法在机器学习中的实现与应用 #### 一、KNN算法简介 K近邻(K-Nearest Neighbor, KNN)是一种基本分类与回归方法。该算法的核心思想在于通过计算待测样本与训练集中各个样本的距离,选取距离最小的前K个邻居,并依据这些邻居的信息来进行决策。对于分类问题而言,则是根据多数表决原则决定新实例所属类别;而对于回归问题来说,则通常采用这K个最接近的数据点的目标属性平均值作为预测结果。 #### 二、R语言下的具体实践案例 针对鸢尾花数据集的应用展示了如何利用基础函数完成整个流程而无需依赖额外包的支持[^2]。在这个例子中,通过对不同特征维度间欧氏距离或其他度量方式的选择实现了对未知样本的有效识别。这种做法不仅有助于理解原理本身,同时也锻炼了编程技巧以及解决实际问题的能力。 ```r # 加载必要的库并读入数据 library(ggplot2) data(iris) head(iris) # 数据预处理... set.seed(1234) trainIndex <- sample(seq_len(nrow(iris)), size = floor(.7 * nrow(iris))) trainingData <- iris[trainIndex, ] testingData <- iris[-trainIndex, ] # 定义knn函数用于后续调用 knnPredict <- function(trainSet, testInstance, labels, k){ distances <- sqrt(rowSums((t(t(trainSet[,1:4]) - as.numeric(testInstance)))^2)) sortedDistIndices <- order(distances)[1:k] classCounts <- table(labels[sortedDistIndices]) return(names(which.max(classCounts))) } predictions <- sapply(as.matrix(testingData[,1:4]), knnPredict, trainSet=as.matrix(trainingData[,1:4]), labels=trainingData$Species,k=3L) confusionMatrix <- table(predictions,factor(testingData$Species)) print(confusionMatrix) ``` 上述代码片段演示了一个完整的基于自定义逻辑而非第三方工具包构建KNN模型的过程,包括但不限于数据分割、相似性测量及最终评估等方面的工作。 #### 三、应用场景探讨 尽管存在诸如计算复杂度较高等局限之处,但在某些特定条件下依然能够展现出独特价值: - **低维空间**:当输入变量数量较少时,性能表现良好; - **多模态分布**:可以很好地适应具有多个峰值的概率密度函数所描述的现象; - **快速原型开发**:由于易于理解和编码特性,在初期探索阶段可作为一种高效手段迅速验证想法可行性[^3]。 综上所述,虽然与其他更先进的技术相比可能显得不够先进,但凭借其实现简便性和灵活性依旧占据着不可替代的地位。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值