knn【K-Nearest-Neighbors】算法是机器学习中很常见的一个算法,主要用于数据分类,属于有监督学习。
knn算法核心思想
- 百度的解释
-
如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别
- 自己的理解
-
从k众心理,即找到离自己最近的k个数据,选择其中大多数数据所属类别,那么自己也属于这个类别
knn算法demo【python手写实现iris数据集分类】
from sklearn import datasets
from sklearn.model_selection import train_test_split
import numpy as np
from collections import Counter
iris = datasets.load_iris()
x = iris.data
y = iris.target
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=40, test_size=0.3)
#设置random_state是为了固定每次的训练数据和测试数据
#设置test_size是为了控制训练集和测试集的比例
def eucli_dis(d1, d2):
'''
:param d1: 第一个样本数据
:param d2: 第二个样本数据
:return: 两个样本数据之间的欧氏距离
'''
return np.sqrt(np.sum(pow(d1 - d2, 2)))
def knn_cluster(x_train, y_train, x_test, k):
'''
:param x_train: 训练集特征
:param y_train: 训练集标签
:param x_test: 测试样本
:param K: 选择的邻居数目
:return: 样本数据的分类结果
'''
dis = [eucli_dis(x, x_test) for x in x_train]
#找到最近邻k个数据的索引
knn_index = np.argsort(dis)[:k]
y = y_train[knn_index]
return Counter(y).most_common(1)[0][0]
y_predict = [knn_cluster(x_train, y_train, x, k=3) for x in x_test]
predict_right = np.count_nonzero((y_predict==y_test)==True)
print('y_test ground true:')
print(y_test)
print('y_test prediction:')
print(y_predict)
print('Prediction Accuracy: {:.2f}'.format(predict_right / len(x_test)))
python实现数据可视化
import matplotlib.pyplot as plt
import pandas as pd
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
colms = pd.DataFrame(data=iris.data, columns=iris.feature_names)
colms['target'] = y
print(colms)
iris_0 = colms[colms['target'] == 0].values
iris_1 = colms[colms['target'] == 1].values
iris_2 = colms[colms['target'] == 2].values
ax.scatter(iris_0[:, 0], iris_0[:, 1], iris_0[:, 2], label='sepal length')
ax.scatter(iris_1[:, 0], iris_1[:, 1], iris_1[:, 2], label='sepal width')
ax.scatter(iris_2[:, 0], iris_2[:, 1], iris_2[:, 2], label='petal length')
plt.legend()
plt.show()
对超参数k的思考
- K值的设定
-
此处实现的代码中K值是人为设定的,具有主观性
- K值对实验结果的影响
-
对于二分类来说,K值一般设置成奇数,防止TIE
-
对于多分类来说,K值一般从1开始try,但是时间消耗很大
knn算法优缺点分析
- 优点
-
实现起来特别简单,对于小样本数据准确率较高
- 缺点
-
效率低
-
对训练集依赖度过高
-
对于高纬度数据处理不友好,容易陷入维数灾难