1. KNN 算法基本概念
1.1 KNN(K-Nearest Neighbors ,K个最近的邻居)算法
是一种基本的机器学习算法,它主要用于分类和回归问题。
1.2 KNN算法的基本思想:
根据数据样本之间的距离,将一个新数据点分类到离它最近的k个训练数据点中出现最多的类别。
底层思想:物以类聚,人以群分;近朱者赤,近墨者黑。
1.3 KNN算法的应用场景很广泛,例如:
- 智能推荐系统:根据用户历史浏览记录、搜索历史等,推荐相似的商品或服务。
- 金融领域:根据历史银行贷款记录,判断新的贷款申请是否合理。
- 医疗诊断:根据病人的症状、病史等信息,判断疾病的种类和预后。
- 语音识别:根据已知的语音样本,判断新的语音片段所属的语音类别。
- 图像识别:根据已知的图像样本,判断新的图像属于哪个类别。
KNN算法虽然简单,但是它的分类结果很可靠,因此在实际应用中被广泛使用。但是,KNN算法的缺点是计算复杂度高,对数据量大、维度高的数据集处理起来比较慢。
1.4 样本的相似度计算
- x:[x1, x2, ..., xn]
- 从线性代数的视角出发,认为每个样本都是一个 n 维的向量
- 样本的相似度就可以用向量的相似度来表达
- 用向量的余弦相似度来表达
- cosine_similarity = a @ b / |a| / |b|
- 用向量的余弦相似度来表达
- 样本的相似度就可以用向量的相似度来表达
- 从欧式空间的视角出发,认为每个样本都是一个 n 维空间内的点
- 样本的相似度就可以用点的欧式距离来表达
- 欧式距离越小,代表越相似
- d = sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2 +....)
- 欧式距离越小,代表越相似
- 样本的相似度就可以用点的欧式距离来表达
2. KNN算法的 sklearn 实现
"""
KKN 分类算法
"""
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
X, y = load_iris(return_X_y=True)
# 切分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=True)
# KNN 分类器
from sklearn.neighbors import KNeighborsClassifier
# 第一步:构建一个对象
knn = KNeighborsClassifier(n_neighbors=5)
# 第二步:训练
knn.fit(X=X_train, y=y_train)
# 第三步:预测
y_pred = knn.predict(X=X_test)
# 评价
(y_test == y_pred).mean()
"""
KKN 回归算法
""
# 第一步:构建模型
knn = KNeighborsRegressor(n_neighbors=7)
# 第二步:训练模型
knn.fit(X=X_train, y=y_train)
# 模型测试
y_pred = knn.predict(X=X_test)
# 模型评价
# Mean Squared Errors MSE
((y_test - y_pred) ** 2).mean()
3. 自定义一个KNN 分类器
from collections import Counter
class MyKNeighborsClassifier(object):
"""
自定义个一个KNN分类器
"""
def __init__(self, n_neighbors=5):
"""
初始化函数
"""
self.n_neighbors = n_neighbors
def fit(self, X, y):
"""
训练函数
惰性计算
"""
# 转类型
X = np.array(X)
y = np.array(y)
# 基本校验
if X.ndim != 2 or y.ndim != 1:
raise ValueError("输入的参数维度有错误!")
# 把训练集挂到模型上面
self.X = X
self.y = y
def predict(self, X):
"""
预测函数
- 第一步:先从训练集中,找出跟待预测的样本很类似的 n 个样本(欧式距离)
- 第二步:这 n 样本中,哪个类别出现的最多,这个样本就属于哪个类别
"""
# 类型转换
X = np.array(X)
# 基本校验
if X.ndim != 2:
raise ValueError("输入参数必须是二维的!!!")
# 求距离
results = []
for x in X:
# 求出待测样本跟训练集中所有样本的距离
distances = ((self.X - x) ** 2).sum(axis=1)
# 求出距离最近(最相似)的 n_neighbors 个邻居,返回的是邻居标签
indices = distances.argsort(axis=0)[:self.n_neighbors]
labels = self.y[indices]
# 投票机制 top 1
label = Counter(labels).most_common(1)[0][0]
results.append(label)
return np.array(results)
# 构建模型
my_knn = MyKNeighborsClassifier(n_neighbors=5)
# 训练模型
my_knn.fit(X=X_train, y=y_train)
# 测试模型
y_pred = my_knn.predict(X=X_test)
# 评价
(y_pred == y_test).mean()