各位老师朋友们大家好!
一直以来我对机器学习很感兴趣,也有很多困惑,希望能和大家一起分享。
今天我们讨论的主题是:机器学习KNN与kmeans算法易混淆?一文来帮你分清楚!
阅读本文档后,您将能够清晰区分KNN和K-means的适用场景,并在实际项目中做出合理选择。
机器学习(machine learning)是什么,我们通过名字其实也可以理解,机器+学习,就是让机器去学习。
学习完了是不是就完了呢?
不是的,肯定是想让它帮人类做事情。
那么它做事情最主要的特点是什么?
训练(trainning)和预测(predict) 两个大步骤!
即学以致用。
充分理解了这个概念看似很简单,但是对我们后续深入理解自己学机器学习到底在干什么有很大帮助。
机器学习究竟怎么学习呢?
在机器学习这个领域我觉得最经典的算法思想无异于分类和聚类的思想。
分类代表有监督,聚类则代表无监督。
而其中K近邻(KNN)和K均值(kmeans)分别是这两种思想最经典的代表。KNN和kmeans都是基础而重要的机器学习算法,它们各有特点和适用场景。
它们虽然名字里面都有"K",它们两个光听名字容易让人搞混淆,但是本质上这两种属于截然不同的算法类型:
KNN是有监督学习,而kmeans则是无监督学习。光死记硬背你肯定很快又会忘记谁是谁。下面我们一招记住并活学活用。
KNN一般来说它在分类和回归任务中表现出色,尤其适合于特征空间较小且需要渐进式学习的场景。NN就可以看出来它是一个网络(哈哈,瞎编的,帮你理解记忆),emmm, 所以肯定需要人为干预,有监督!
而kmeans是经典的无监督学习算法,mean就知道它在搞平均。它在进行探索性的数据分析、对目标进行细分、图像压缩处理等领域有比较广泛的应用。所以,既然它自己都用数学方法搞平均了,它肯定是无监督!
是不是很清楚?
下面我们再来一起基于实际项目代码实现,深入探讨一下这两种算法的基本原理、实现方式以及其如何分清合适的适用场景来选用,本项目附可运行的项目代码。
首先,我们来看标准定义:
K近邻算法,K-Nearest Neighbors, KNN,是一种基本的监督学习算法,主要用于分类和回归任务。它的核心思想就是:
"物以类聚,人以群分"。
简单来说就是,你和你的朋友肯定在比如性格,喜好,年龄,生活习惯等等一系列方面是高度类似甚至一样的。
典型代表就是各自圈子,兴趣小组。有一个明显的Subject或者Label将你们标记在一起。
对于一个新的样本点,它的类别或值由距离最近的K个邻居决定,从而实现分类。
K均值(kmeans)是一种典型的无监督学习算法,主要用于聚类任务。它会动态调整族群的中心,具备较强的迁移适应能力,其主要思想是:
将数据集划分为K个簇(clusters),即族群,同一簇或者说族群内的数据相似度较高,不同簇间的数据差异较大。
根据刚才咱们的分析,现在总结比较一下两者的核心差异如下:
既然我们说两个算法都围绕K值展开,这个K值即类别的个数,但两者其对K值的定义和使用并不相同。
KNN更关注预测时的局部邻域信息,而kmeans则注重全局数据分布的优化。理解这些差异有助于我们在实际应用中做出更合理的选择。
现在将knn.py
实现如下:
import numpy as np
from collections import Counter
class KNN:
def __init__(self, k=3):
self.k = k
def fit(self, X, y):
self.X_train = X
self.y_train = y
def predict(self, X):
predictions = [self._predict(x) for x in X]
return predictions
def _predict(self, x):
# 计算距离
distances = [np.linalg.norm(x - x_train) for x_train in self.X_train]
# 获取最近的K个样本的索引
k_indices = np.argsort(distances)[:self.k]
# 获取这些样本的标签
k_nearest_labels = [self.y_train[i] for i in k_indices]
# 多数投票
most_common = Counter(k_nearest_labels).most_common(1)
return most_common[0][0]
其实现情况为使用欧氏距离作为距离度量,实现了fit和predict标准接口,并支持批量预测。
kmeans.py
实现如下:
import numpy as np
class kmeans:
def __init__(self, k=3, max_iters=100):
self.k = k
self.max_iters = max_iters
self.centroids = None
self.clusters = None
def fit(self, X):
# 初始化质心
self.centroids = self._initialize_centroids(X)
for _ in range(self.max_iters):
# 分配样本到最近的质心
self.clusters = self._create_clusters(X, self.centroids)
# 更新质心
prev_centroids = self.centroids
self.centroids = self._get_new_centroids(X, self.clusters)
# 检查是否收敛
if self._is_converged(prev_centroids, self.centroids):
break
def _initialize_centroids(self, X):
# 随机选择K个样本作为初始质心
indices = np.random.choice(len(X), size=self.k, replace=False)
return X[indices]
def _create_clusters(self, X, centroids):
clusters = [[] for _ in range(self.k)]
for idx, sample in enumerate(X):
centroid_idx = self._closest_centroid(sample, centroids)
clusters[centroid_idx].append(idx)
return clusters
def _closest_centroid(self, sample, centroids):
distances = [np.linalg.norm(sample - c) for c in centroids]
closest_idx = np.argmin(distances)
return closest_idx
def _get_new_centroids(self, X, clusters):
centroids = np.zeros((self.k, X.shape[1]))
for idx, cluster in enumerate(clusters):
cluster_mean = np.mean(X[cluster], axis=0)
centroids[idx] = cluster_mean
return centroids
def _is_converged(self, prev_centroids, centroids):
distances = [np.linalg.norm(prev_centroids[i] - centroids[i]) for i in range(self.k)]
return sum(distances) == 0
该算法的关键实现特点:
首先,实现了标准的kmeans算法流程,该算法包含初始化质心、分配样本、更新质心等核心步骤,支持收敛判断,并且提供了完整的聚类功能。
总结比较两个算法的特点如下表所示:
场景 | KNN | kmeans |
---|---|---|
算法类型 | 监督学习 | 无监督学习 |
数据标签 | 有 | 无 |
任务类型 | 分类/回归 | 聚类 |
训练过程 | 懒惰学习(无明显训练阶段) | 迭代优化(有明确训练过程) |
参数需求 | K值选择 | K值选择 |
数据规模 | 适合中小规模数据 | 适合大规模数据 |
从计算效率来看,KNN在预测阶段计算量较大,而kmeans则在训练过程中需要更多迭代计算。对于特征维度较高或数据规模较大的情况,可能需要考虑降维或其他优化策略来提升算法性能。
KNN优点是简单直观,易于理解和实现; 无需训练过程;对数据分布无假设,适应性强。缺点是计算复杂度高,预测速度慢; 对高维数据效果差(维度灾难);对不平衡数据敏感;需要选择合适的距离度量。
kmeans优点是计算效率高,适合大数据集;容易被人解释和可视化。缺点是要预先指定K值否则无法计算;对初始中心点和对异常值敏感。
综上,KNN算法特别适合以下场景:
kmeans算法适用于以下情况:
实现demo.py
中示例代码,我们可以生成两种算法的可视化结果:
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from knn import KNN
from kmeans import kmeans
# 生成模拟数据
X, y = make_blobs(n_samples=300, centers=4, random_state=42)
# KNN可视化
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
knn = KNN(k=3)
knn.fit(X, y)
y_pred = knn.predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred, cmap='viridis', s=50)
plt.title('KNN Classification Results')
# kmeans可视化
plt.subplot(1, 2, 2)
kmeans = kmeans(k=4)
kmeans.fit(X)
plt.scatter(X[:, 0], X[:, 1], c=kmeans.clusters, cmap='viridis', s=50)
plt.scatter(kmeans.centroids[:, 0], kmeans.centroids[:, 1], c='red', s=200, marker='X')
plt.title('kmeans Clustering Results')
plt.tight_layout()
plt.show()
运行情况展示如下:
可视化结果展示了:
通过本文的解析,我们可以看到KNN和kmeans这两个算法在数据处理、计算逻辑和应用场景上的显著差异。
本文不仅阐述了算法的基本原理,还结合项目中的具体实现进行了较为深入的分析,并通过可视化示例展示了两种算法的实际效果。
读者可以全面了解KNN和kmeans的区别与联系,更重要的是,我们可以学会如何结合自身实践需要选择合适的机器学习模型,为今后在实际项目中选择和应用合适的算法提供了一份参考依据。
完结,撒花~!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。