- KNN:K-Nearest Neighbors
- K个最近的邻居
- 近邻思想是人工智能的核心思想
- 物以类聚人以群分
- 近朱者赤近墨者黑
- 这种算法:
- 惰性计算
- 临阵磨枪
- 推理速度很慢
- 几乎没有什么训练
- 非典型人工智能算法
- 算法流程:
- 代码举例:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
#加载数据
X, y = load_iris(return_X_y=True)
#切分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, shuffle=True, test_size=0.2)
X_train.shape
#构建模型
knn = KNeighborsClassifier(n_neighbors=5)
#训练模型
knn.fit(X=X_train, y=y_train)
#预测
y_pred = knn.predict(X=X_test)
acc = (y_pred == y_test).mean()
acc
#自定义KNN模型
class MyKneighborsClassifier(object):
"""
自定义KNN分类起
"""
def __init__(self, n_neighbors=5):
"""
初始化方法
"""
self.n_neighbors = n_neighbors
def fit(self, X, y):
"""
模型训练
"""
#引入numpy
import numpy as np
#类型转换
X = np.array(X)
y = np.array(y)
#数据校验
if X.ndim != 2 or y.ndim != 1 or X.shape[0] != y.shape[0]:
raise ValueError("数据格式有误")
#把数据集挂到模型上
self.X = X
self.y = y
def _get_vec_similarity(self, vec1, vec2):
"""
内部辅助函数
- 计算两个向量的余弦相似度
"""
return vec1 @ vec2 / np.linalg.norm(vec1)/ np.linalg.norm(vec2)
def predict(self, X):
"""
推理过程
"""
from collections import Counter
#类型转换
X = np.array(X)
#数据校验
if X.ndim != 2 or X.shape[1] != self.X.shape[1]:
raise ValueError("输入数据有误")
#第一步:找k个好友
#第二部:投票机制(回归:求平均,分类:少数服从多数)
results = []
for x in X:
# 使用欧式距离
distance = np.sqrt(((x - self.X) ** 2).sum(axis=1))
idxes = np.argsort(distance[:self.n_neighbors]
#使用余弦相似度
cosine_similarity = np.array([self._get_vec_similarity(x, vec) for vec in self.X])
idxes = np.argsort(cosine_similarity)[::-1][:self.n_neighbors]
labels = self.y[idxes]
final = Counter(labels).most_common(1)[0][0]
results.append(final)
return np.array(results)
#构建模型
my_knn = MyKneighborsClassifier(n_neighbors=5)
#训练模型
my_knn.fit(X=X_train, y=y_train)
#预测模型
my_knn.predict(X=X_test)