1.介绍

  • 分类算法
  • 原理:为待分类个体寻找K个最近的邻居,邻居中频次最多的种类几即为待分类个体的种类。
  • sklearn.neighbors.KNeighborsCalssifier(n_neighbors=n) # 参数为K值
  • 优点:1.简单有效 2.重新训练代价低 3.适合类域交叉样本 4.适合大样本自动分类
  • 缺点:1.惰性学习 2.类别评分非规范化 3.输出可解释性不强 4.不擅长不均衡样本 5.计算量大

    2.细节

  • n维空间求距离方法

    • 欧式距离
    • 曼哈顿距离
    • 切比雪夫距离
    • 闵可夫斯基距离
      • p=1,曼哈顿
      • p=2,欧氏距离
      • p->∞,切比雪夫距离
    • 标准化欧式距离,其中为方差
    • 余弦距离
    • 汉明距离:两个等长字符串相同位置不同字符的个数
    • 杰卡德距离
    • 马氏距离,判断属于哪个正态分布(距离哪个正态分布近)
  • k值选择

    • k值过小欠拟合,k值过大过拟合
    • kd树查找最近点
      • 构建树
      • 最近邻域搜索

        3.交叉验证和网格搜索

  • 交叉验证

    • 将拿到的训练数据分为训练集和验证集
      • 分割方式:
        • 训练集:训练集+验证集
        • 测试集:测试集
    • 为什么要交叉验证:
      • 为了让评估模型更加准确可信(交叉验证不能提高模型准确率)
  • 网格搜索(Grid Search)
    • 超参数:sklearn中,需要手动指定的参数,叫做超参数
    • 网格搜索将超参数通过字典传递,然后进行最优质选择

image.png
四折交叉验证

4.KNN鸢尾花分类代码

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. import pandas as pd
  4. from sklearn.datasets import load_iris
  5. from sklearn.model_selection import train_test_split, GridSearchCV
  6. from sklearn.preprocessing import MinMaxScaler, StandardScaler # 归一化,标准化
  7. from sklearn.neighbors import KNeighborsClassifier
  8. # 加载数据集
  9. iris = load_iris()
  10. # 将数据集封装成DataFrame
  11. iris_data = pd.DataFrame(data=iris.data, columns=['Swpal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width'])
  12. iris_data['target'] = iris.target
  13. # 封装绘图函数
  14. def plot_iris(iris, col1, col2):
  15. sns.lmplot(x=col1, y=col2, data=iris, hue='target', fit_reg=False) # hue:目标值 fit_reg:是否线性回归
  16. plt.title("鸢尾花数据展示")
  17. plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文标签
  18. plt.rcParams['axes.unicode_minus'] = False
  19. plt.show()
  20. # 预览数据分布
  21. plot_iris(iris_data, 'Sepal_Width', 'Petal_Width')
  22. # 分割数据集 test_size测试集比例 random_state随机数种子(取相同的随机数种子可以得到相同的测试集-训练集划分)
  23. x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)
  24. # 数据预处理--标准化数据
  25. x_train = StandardScaler().fit_transform(x_train)
  26. x_test = StandardScaler().fit_transform(x_test)
  27. # KKN训练algorithm默认为auto,自动选择使用ball_tree(高维),kd_tree,brute
  28. KNN = KNeighborsClassifier(n_neighbors=5, algorithm='auto')
  29. # 交叉验证网格搜索:param_grid字典设置参数列表,cv设置交叉验证折数,n_jobs并行数(-1开启全部核心)
  30. KNN = GridSearchCV(KNN, param_grid={"n_neighbors": [1, 3, 5]}, cv=10, n_jobs=-1) # 若不使用交叉验证网格搜索注释这行
  31. KNN.fit(x_train, y_train)
  32. # 模型评估
  33. print("准确率为:", KNN.score(x_test, y_test)) # 输出:“准确率为: 0.9”
  34. print("最好的模型:", KNN.best_estimator_) # "最好的模型: KNeighborsClassifier(n_neighbors=1)"
  35. print("最好的结果:", KNN.best_score_) # "最好的结果: 0.9666666666666666"
  36. print("整体模型结果:", KNN.cv_results_)
  37. # "整体模型结果:
  38. # {'mean_fit_time': array([0.00140276, 0.00119739, 0.00109811]),
  39. # 'std_fit_time': array([0.00048949, 0.00039933, 0.00029917]),
  40. # 'mean_score_time': array([0.002197 , 0.00215209, 0.00230212]),
  41. # 'std_score_time': array([0.00040177, 0.00054972, 0.00078119]),
  42. # 'param_n_neighbors': masked_array(data=[1, 3, 5],mask=[False, False, False],fill_value='?',dtype=object),
  43. # 'params': [{'n_neighbors': 1}, {'n_neighbors': 3}, {'n_neighbors': 5}],
  44. # 'split0_test_score': array([1. , 1. , 1. ]),
  45. # 'split1_test_score': array([1. , 1. , 1. ]),
  46. # 'split2_test_score': array([1. , 1. , 1. ]),
  47. # 'split3_test_score': array([1. , 1. , 1. ]),
  48. # 'split4_test_score': array([0.91666667, 0.91666667, 0.91666667]),
  49. # 'split5_test_score': array([1. , 0.91666667, 1. ]),
  50. # 'split6_test_score': array([1. , 1. , 1. ]),
  51. # 'split7_test_score': array([1. , 0.91666667, 0.91666667]),
  52. # 'split8_test_score': array([0.91666667, 0.91666667, 0.91666667]),
  53. # 'split9_test_score': array([0.83333333, 0.83333333, 0.83333333]),
  54. # 'mean_test_score': array([0.96666667, 0.95 , 0.95833333]),
  55. # 'std_test_score': array([0.05527708, 0.05527708, 0.0559017 ]),
  56. # 'rank_test_score': array([1, 3, 2])}"

Figure_1.png