K-近邻算法之K值的选择(带案例)

三、K值的选择

K值选择问题,李航博士的一书「统计学习方法」上所说:

  1. 选择较小的K值,就相当于用较小的领域中的训练实例进行预测,“学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;

  2. 选择较大的K值,就相当于用较大领域中的训练实例进行预测,其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单。

  3. K=N(N为训练样本个数),则完全不足取,因为此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单,忽略了训练实例中大量有用信息。

实际应用中,K值一般取一个比较小的数值,例如采用交叉验证法(简单来说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值。

  • 近似误差:
    • 对现有训练集的训练误差,关注训练集
    • 如果近似误差过小可能会出现过拟合的现象,对现有的训练集能有很好的预测,但是对未知的测试样本将会出现较大偏差的预测。
    • 模型本身不是最接近最佳模型。
  • 估计误差:
    • 可以理解为对测试集的测试误差,关注测试集,
    • 估计误差小说明对未知数据的预测能力好,
    • 模型本身最接近最佳模型。

KNN中K值大小选择对模型的影响

  • k值过小:
    • 容易受到异常点的影响
    • 容易过拟合
    • 模型过于复杂
  • k值过大:
    • 受到样本均衡的问题
    • 容易欠拟合
    • 模型过于简单

四、案例1:鸢尾花种类预测

1)scikit-learn数据集API介绍
  • sklearn.datasets
    • 加载获取流行数据集
    • datasets.load_*()
      • 获取小规模数据集,数据包含在datasets中
    • datasets.fetch_*(data_home=None)
      • 获取大规模数据,需要从网上下载,函数的第一个参数就是data-Home表示数据集的下载目录。默认是~/scikit_learn_data/
2)scikit-learn小数据集
  • sklearn.datasets.load_iris()

    加载并返回鸢尾花数据集

3)scikit-learn大数据集
  • sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)

    • subset:“train"或者"test”,"all"可选,选择需要加载的数据集
    • 训练集的"训练",测试集的”测试“,两者的"全部"
4)sklearn数据集返回值介绍
  • load_fetch返回的数据类型都是datasets.base.Bunch(字段格式)
    • data:特征数据数组
    • target:标签数组
    • DESCR:数据描述
    • feature_names:特征名字
    • target_names:标签名字
from sklearn.datasets import load_iris

# 获取鸢尾花数据集
iris = load_iris()
print("鸢尾花数据集的返回值:\n", iris)
# 返回值是一个继承自字典的Bench
print("鸢尾花的特征值:\n", iris.data)
print("鸢尾花的目标值:\n", iris.target)
print("鸢尾花特征的名字:\n", iris.feature_names)
print("鸢尾花目标值的名字:\n", iris.target_names)
print("鸢尾花的描述:\n", iris.DESCR)


5)查看数据分布
  • seaborn介绍
    • Seaborn是基于Matplotlib核心库对其进行了更高级的API封装,可以轻松画出更漂亮的图形。而Seabor的漂亮主要体现在配色更加舒服以及图形元素的样式更加细腻。
    • 安装pip3 install seaborn
    • seaborn.Implot()是一个非常有用的方法,它在绘制二维散点图的时候,自动完成回归拟合。
      • sns.Implot(x,y): x,y分别代表横纵坐标的列名
      • data 关联的数据集
      • hut 代表按照什么分类方式显示
      • fit_reg 是否进行线性拟合
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

iris = load_iris()
iris_d = pd.DataFrame(iris.data,columns=['Sepal_Length', 'Sepal_Width', 'Petal_Length', 'Petal_Width'])
iris_d['Species'] = iris.target

def plot_iris(iris,col1,col2):
    sns.lmplot(x = col1, y = col2,data=iris,hue='Species',fit_reg=False)
    plt.xlabel(col1)
    plt.ylabel(col2)
    plt.title("鸢尾花种类分布图!!")
    plt.show()
    
    
    
plot_iris(iris_d,'Petal_Width','Sepal_Length')

6)数据集的划分

一般数据集划分为两个部分:

  • 训练数据:用于训练,构建模型
  • 测试数据:用于模型检验,评估模型是否有效

划分比例:

  • 训练集:70%~80%
  • 测试集:20%~30%
数据集划分的API
  • sklearn.model_selection.train_test_split(arrays,*options)
    • 参数:
      • x 数据集的特征值
      • y 数据集的标签值
      • test_size 测试继的大小,一般为float
      • random_state 随机数种子。不同的种子会造成不同的随机结果,相同的种子结果相同
    • return
      • x_train,x_test,y_train,y_test
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# 1.获取鸢尾花数据集
iris = load_iris()
# 对鸢尾花数据集进行分割
# 训练特征值、测试特征值、训练目标值、测试目标值
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=22)
print("x_train:\n", x_train.shape)

你可能感兴趣的:(机器学习算法,K-近邻算法,K值的选择)