# KNN: 通过计算待分类数据点，与已有数据集中的所有数据点距离
# 取距离最小的前 K个点，根据“少数服从 多数“的原则
# 将这个数据点划分为出现次数最多的那个类别

from sklearn.neighbors import KNeighborsClassifier  # 导入k近邻分类器算法包

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]

# 参数n_neighbors设置为3，即使用最近的3个邻居作为分类的依据
# 其他参数保持默认值，并将创建好的实例赋给变量neigh
neigh = KNeighborsClassifier(n_neighbors=3)
# sklearn.neighbors.KNeighborsClassifier创建一个K近邻分类器
# 主要参数有：
# • n_neighbors：用于指定分类器中K的大小(默认值为5，注意与kmeans的区别)
# • weights：设置选中的 K个点对分类结果影响的权重
# （默认值为平均权重"uniform"，可以选择"distance"代表越近的点权重高,
#  或者传入自己编写的以距离为参数的权重计算函数)
# • algorithm：设置用于计算临近点的方法
# 因为当数据量很大情况下计算当前点和所有的距离再选出最近k各点
# 这个计算量是很费时的, 所以选项中有ball_tree 、kd_tree和brute
# 分别代表不同的寻找邻居优化算法，默认值为auto，根据训练数自动选择

# 调用fit()函数，将训练数据X和标签y送入分类器进行学习
neigh.fit(X, y)

# 调用predict()函数，对未知分类样本[1.1]分类
# 可以直接将需要分类的的数据构造为数组形式作为参数传入，得到分类标签作为返回值

print(neigh.predict([[1.1]]))

# 样例输出值是0，表示K近邻分类器通过计算样本[1.1]与训练数据的距离
# 取0,1,2这3个邻居作为依据，根据“投票法”最终将样本分类别0

# 在实际使用时，我们可以使用所有训练数据构成特征X和标签y，使用fit()函数进行训练
# 在正式分类时，通过一次性构造测试集或者一个一个输入样本的方式，得到对应分类结果。
# 有关 K 的取值 ：
# • 如果较大，相当于使用较大邻域中的训练实例进行预测
# 可以减小估计误差，但是距离较远的样本也会对预测起作用，导致错误
# • 相反地，如果K较小，相当于使用较小的邻域进行预测，如果居恰好是噪声点，会导致过拟合
# • 一般情况下， K会倾向选取较小的值，并使用交叉验证法选取最优K值
