当前位置: 首页 > news >正文

机器学习 Day09 KNN算法

1.knn算法的简介

算法本质 KNN 算法是机器学习中的经典分类算法 ,由 Cover 和 Hart 提出。它基于实例的学习,不依赖于对数据分布的先验假设,属于懒惰学习算法,即训练阶段仅仅存储训练样本,在预测阶段才进行计算。

定义原理  核心思想是根据样本在特征空间中的 “邻居” 情况来判断其类别。如果一个样本在特征空间中的 k 个最相似(最邻近)样本中的大多数属于某一个类别,那么该样本就被划分到这个类别。例如在一个二维平面的点集分类问题中,要判断一个新点的类别,就找出离它最近的 k 个点,看这些点中占比最多的类别,将新点归为该类别 。

案例:

当k=5时,最相似的5个样本中喜剧片最多,所以预测该电影为喜剧片。

KNN 算法流程详解

  1. 计算距离:使用合适的距离度量(如欧氏距离),计算已知类别数据集中的每个点与待分类的当前点之间的距离。这一步是为了衡量样本点之间的相似程度,距离越近表示越相似。

  2. 排序:将计算得到的距离按照递增顺序进行排序。这样能清晰地知道哪些点离当前点更近。

  3. 选取 k 个点:从排好序的距离列表中,选取距离当前点最小的 k 个点。k 是 KNN 算法中的一个关键超参数,它的取值会影响算法的分类效果。

  4. 统计频率:对选取的 k 个点,统计它们各自所属类别的出现频率。也就是看这 k 个点中,每个类别分别有多少个点。

  5. 预测分类:将出现频率最高的类别作为当前点的预测分类。即认为当前点与 k 个近邻点中占比最多的类别是同一类。

2.API实现

以下是完整实现 K - 近邻算法(KNN)的 Python 代码及详细解释

from sklearn.neighbors import KNeighborsClassifier
# 构造数据集
x = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
# 实例化API
estimator = KNeighborsClassifier(n_neighbors=2)
# 使用fit方法进行训练
estimator.fit(x, y)
# 进行预测
result = estimator.predict([[1]])
print("预测结果为:", result)

代码解释

  1. 导入模块
from sklearn.neighbors import KNeighborsClassifier

从 scikit - learn 库的neighbors子模块中导入KNeighborsClassifier类,该类实现了 K - 近邻分类算法,后续将使用这个类来构建和训练 KNN 模型。
2. 构造数据

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

这里构造了一个简单的数据集。x是特征数据集,它是一个列表,其中每个元素(如[0][1]等)也是一个列表,代表一个样本的特征向量。在这个例子中,每个样本只有一维特征。y是标签数据集,它是一个普通列表,元素01分别对应x中样本的类别标签 ,y中的元素与x中的样本按顺序一一对应。
3. 实例化 API

estimator = KNeighborsClassifier(n_neighbors=2)

创建KNeighborsClassifier类的实例对象estimator ,并通过参数n_neighbors指定 KNN 算法中的 k 值为 2。这意味着在进行分类预测时,模型会寻找与待预测样本距离最近的 2 个邻居样本,根据这 2 个邻居样本的类别来决定待预测样本的类别。
4. 使用 fit 方法进行训练

estimator.fit(x, y)

调用estimator对象的fit方法,将特征数据集x和标签数据集y传入。这个过程是让 KNN 模型从给定的数据中学习样本的特征与类别之间的关系,本质上是存储训练数据,以便后续预测时进行距离计算和邻居查找。
5. 进行预测

result = estimator.predict([[1]])
print("预测结果为:", result)

使用训练好的estimator模型对象的predict方法对新数据[[1]]进行预测。predict方法会根据模型在训练阶段学到的知识(即存储的训练数据),计算新样本[[1]]与训练集中样本的距离,找到距离最近的 2 个邻居样本,然后根据这 2 个邻居样本的类别标签(在本案例中,与[1]距离最近的 2 个样本对应的标签都是0 ),按照 KNN 算法规则,将出现频率最高的类别作为预测结果返回。最后使用print函数输出预测结果。

3.距离度量

以上距离的缺点

  1. 量纲问题:闵氏距离将各属性分量量纲同等看待,忽略了不同属性实际度量单位和尺度差异。如上述身高和体重,一个是长度单位,一个是质量单位,直接计算距离不合理。
  2. 分布问题:未考虑各属性分量的分布情况(期望、方差等 ) 。不同属性在数据集中分布特征可能不同,有的属性数据波动大(方差大 ),有的波动小(方差小 ),闵氏距离不考虑这些差异,会使距离计算不能准确反映样本间真实差异程度。

4.K值选择

  1. K 值过小
    • 易受异常点影响:K 值小意味着仅依据离待预测样本极近的少数样本分类。若这些近邻样本中有异常点(如数据录入错误等导致的特殊样本 ),会使预测结果严重偏离真实类别。例如在上述电影例子中,若 K 值为 1,恰好最近的电影是因特殊原因(如镜头统计错误 )导致类型不符的,就会错误预测 “唐人街探案” 类型。
    • 模型复杂易过拟合:从学习角度看,用较小领域训练实例预测,近似误差减小,但估计误差增大,模型对训练数据过度适配,在新数据上泛化能力差 。(估计误差好才是真的好)
  2. K 值过大
    • 受样本均衡问题影响:K 值大时,参与预测的邻居样本多,若各类别样本数量不均衡,占比大的类别会主导预测结果,忽略小类样本特征。比如电影数据中,若动作片样本数远超其他类型,K 值大时很多电影可能被误判为动作片。特别的当K=N时无论什么样本都会预测为样本中类型最多的一类。
    • 近似误差增大欠拟合:用较大领域训练实例预测,虽估计误差减小,但很多与待预测样本不相似的样本参与,使预测结果偏离真实值,模型变得简单,无法捕捉数据复杂模式 。
  3. K 值选择理论及方法
    • 理论依据:如《统计学习方法》所述,K 值选择影响模型近似误差和估计误差。K 值小近似误差小、估计误差大,易过拟合;K 值大则相反,近似误差大、估计误差小 。
    • 实际方法:实际常取较小数值,通过网格搜索和交叉验证法(后会讲)选最优 K 值。即将训练数据分训练集和验证集,多次调整 K 值训练模型,在验证集上评估性能,选性能最佳(如准确率最高等 )时对应的 K 值 。
  4. 近似误差与估计误差
    • 近似误差:关注训练集,是对现有训练集的训练误差。近似误差过小,模型可能过度适应训练数据,对测试样本预测偏差大,不是最佳模型 。
    • 估计误差:关注测试集,是对测试集的测试误差。估计误差小表明模型对未知数据预测能力强,更接近最佳模型 。

5.KD树

1. kd 树简介

  • 背景与目的:在 KNN 算法中,当数据集很大时,线性扫描(穷举搜索)计算输入实例与每个训练实例的距离非常耗时。kd 树是为解决 KNN 快速 k 近邻搜索问题而引入的特殊数据结构 ,通过保存距离信息,减少距离计算次数,提升搜索效率,优化后算法复杂度可降低到O(DNlog (N)) 。
  • 原理:kd 树是一种平衡二叉树 (子树深度差不超过1),对 k 维空间中的实例点进行存储以便快速检索。它不断用垂直于坐标轴的超平面(相当于切开空间的一个东西)将 k 维空间切分,构成一系列 k 维超矩形区域 ,每个结点对应一个 k 维超矩形区域。如在一维中,分割超平面是点;二维中是线;三维中是面 。利用 kd 树可跳过距离远的点,省去对大部分数据点的搜索,减少计算量。 例如类比二分查找,对数据进行合理划分,避免不必要的查找。其基本思想是:如果A距离B很远,B距离C很近,那么A距离C也很远,这一点在搜索上可以体现(不搜索未相交的那一侧)。

2. 构造方法

  • 步骤
    • 构造根结点:根结点对应 k 维空间中包含所有实例点的超矩形区域 。
    • 递归切分:通过递归,在超矩形区域选择一个坐标轴和切分点确定超平面,将区域切分为左右子区域(子结点 ),实例被分到相应区域 。
    • 终止条件:当子区域内没有实例时终止,此时结点为叶结点 ,实例保存在相应结点上。
    • 构建平衡树:通常循环选择坐标轴(一般选数据分散程度大,如方差大的维度 ),以训练实例点在坐标轴上的中位数为切分点进行空间切分,构建平衡 kd 树(左右子树深度差绝对值不超 1 )。
  • 关键问题
    • 维度选择:可随机或按顺序选某一维,但更好的是选数据比较分散(方差大 )的维度划分,这样能使划分更有效。
    • 数据划分:选好维度后,选择合适切分点(中位数 )划分数据,使构建的树平衡,提升搜索效率。

3.搜索方法与案例:

比如查找点(2.1,3.1)就是先找到搜索路径,让它们依次进入队列(从根路径开始直到叶子节点结束),如下图:下图已经得到了划分图与树图,我们先找到该点的路径依次放入一个队列中:

然后从队列中依次取出点,比如先取(2,3)出队列,看作最近节点,求最短距离,以该距离为半径,圆心为要查找的点做超球,再去回溯队列里第二个点(5,4):

不相交说明这个超球没有跨过这个点对应的超平面,即这个范围内没有比当前最近点和半径更近的点,所以还是这个点和这个半径,因为和(5,4)不最近,所以在另一个超平面上的点距离(5,4)近,但(5,4)距离要查找点远,所以由上基本原理,认为这些点也很远,所以就不需要考虑了,这是队列里还有最后一个元素(7,2),递归如上步骤直到全部出队列即可:

但是如果相交的话怎么办:

注意观察队列里的元素:就是如果相交,这意味着在另一边子树中可能存在更近的点,则把另一边的超矩形里的点入队列,然后依次回溯即可,下面的例子是另一个超矩形内只有一个叶子结点,如果还有其他点怎么办,按照深度优先遍历所有点?(这个问题我也不清楚)

对 sklearn.neighbors.KNeighborsClassifier API 的解读

  1. 类的功能sklearn.neighbors.KNeighborsClassifier 是 scikit - learn 库中用于实现 K - 近邻分类算法的类。K - 近邻算法基于样本间的距离,通过寻找与待分类样本距离最近的k个邻居样本,依据这些邻居样本的类别来预测待分类样本的类别。
  2. 参数说明
    • n_neighbors:该参数用于指定在 K - 近邻查询时默认使用的邻居数量,是一个整数类型,可选,默认值为5 。比如在对一个新样本进行分类时,算法会找出距离该样本最近的\(n_neighbors\)个样本(这里默认是5个 ),然后根据这5个样本中占多数的类别来确定新样本的类别。
    • algorithm:用于指定快速k近邻搜索算法,默认参数为 'auto' ,表示算法会自动决定合适的搜索算法。此外,用户还可手动指定以下几种算法:
      • 'brute':即蛮力搜索,本质是线性扫描。它会计算待查询样本与训练集中所有样本的距离,然后找出最近的k个邻居。当训练集规模较小时,该方法可行;但训练集很大时,计算量剧增,耗时会非常长 。
      • 'kd_tree':通过构造 kd 树来存储数据,以实现快速检索。kd 树是一种二叉树结构,以中值切分来构造,每个结点对应一个超矩形区域。在维数小于20时,这种结构能有效提高搜索效率,快速定位到与查询样本相近的样本区域 。
      • 'ball_tree':为克服 kd 树在高维空间失效的问题而设计。它以质心C和半径r来分割样本空间,每个节点是一个超球体。在高维数据场景下,相较于 kd 树,它能更有效地进行近邻搜索 。

6.案例,鸢尾花种类预测:

6.1导入数据

数据来自于一个库,我们要怎么样使用该库中数据集呢?其实可以使用如下API来得到数据:

sklearn.datasets是一个库,这个库里的load_数据集和fetch_数据集方法可以得到相关数据集,只不过一个是大规模,一个是小规模

 比如:

数据返回值的介绍:一个类字典数据,访问数据你得用[data],还有其他属性用.访问就行,注意data没有要预测的数据,仅仅是一些特征值,你要预测值,就是target得到

总体代码:

# 导入所需的数据集加载函数
from sklearn.datasets import load_iris, fetch_20newsgroups

# 加载鸢尾花数据集
iris = load_iris()
print("鸢尾花数据集的返回值: \n", iris)
print("鸢尾花的特征值:\n", iris["data"])
print("鸢尾花的目标值: \n", iris.target)
print("鸢尾花特征的名字: \n", iris.feature_names)
print("鸢尾花目标值的名字: \n", iris.target_names)
print("鸢尾花的描述: \n", iris.DESCR)

# 加载20新闻组数据集(这里加载全部数据,实际可按需选择subset参数)
news = fetch_20newsgroups(subset='all')
print("20新闻组数据集的返回值: \n", news)
print("20新闻组的特征值:\n", news["data"])
print("20新闻组的目标值: \n", news.target)
print("20新闻组特征的名字: \n", news.feature_names)
print("20新闻组目标值的名字: \n", news.target_names)
print("20新闻组的描述: \n", news.DESCR)

6.2 数据预处理——划分数据集:

API就是在sklearn.model_selection库里边的train_test_split()函数,注意需要承接返回值,注意返回值顺序。

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
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=2)
print("x_train:\n", x_train.shape)

# 随机数种子
x_train1, x_test1, y_train1, y_test1 = train_test_split(iris.data, iris.target, random_state=1)
x_train2, x_test2, y_train2, y_test2 = train_test_split(iris.data, iris.target, random_state=1)
print("如果随机数种子不一致: \n", x_train == x_train1)
print("如果随机数种子一致: \n", x_train1 == x_train2)
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=2)

使用 train_test_split 函数将鸢尾花数据集的特征数据 iris.data 和标签数据 iris.target 划分为训练集和测试集。random_state=2 是设置随机数种子,保证每次运行代码时划分结果一致。然后打印训练集特征值 x_train 的形状。.

7.特征工程——特征预处理(无需对目标值进行处理)(归一化,标准化)

7.1. 特征预处理

  • 定义通过一些转换函数将原始特征数据转换成更适合算法模型的特征数据,目的是解决特征单位、大小差异大或方差数量级差异大等问题,避免影响算法学习。
  • 原因:当特征单位或大小差异大,或某特征方差远大于其他特征时,会干扰算法对特征的学习,导致一些算法无法有效学习其他特征。

7.2. 归一化

  • 定义:把原始数据变换映射到默认为[0, 1]之间。
  • 公式:其实就是等比转化到我想要的区间上,x‘就是在原来数据中的占比位置,然后可以用一个等比等式就可以自然求出x‘’了。
  • APIsklearn.preprocessing库里的函数可以实现:
    • sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)...) ,用于实例化归一化转换器,可指定映射区间,默认为[0, 1]。指定参数可以改变范围。即这是一个实例化,类似与KNN算法一样,先实例化,再调用实例化对象的方法或者属性。
    • MinMaxScaler.fit_transform(X) ,X为 numpy array 格式的数据,该方法对数据进行拟合和转换,返回转换后形状相同的数组。
  • 数据计算示例: 
    import pandas as pd
    from sklearn.preprocessing import MinMaxScaler
    
    
    def minmax_demo():
        """
        归一化演示
        :return: None
        """
        data = pd.read_csv("./data/dating.txt")
        print(data)
        # 1、实例化一个转换器类
        transfer = MinMaxScaler(feature_range=(2, 3))
        # 2、调用fit_transform
        data = transfer.fit_transform(data[['milage', 'Liters', 'Consumtime']])
        print("最小值最大值归一化处理的结果: \n", data)
        return None
    
    if __name__ == '__main__':
        minmax_demo()
  • 异常点影响及总结: 归一化中最大值和最小值易受异常点影响,若数据中异常点较多,会使归一化结果偏离正常范围,鲁棒性较差,适用于传统精确小数据场景 。所以有标准化:

7.3标准化:

  1. 定义:标准化是将原始数据进行变换,使数据变换到均值为0、标准差为1的范围内 。通过这种变换,能让不同特征的数据在同一尺度下进行比较和分析,避免因特征的量纲、数值范围差异影响机器学习模型效果。
  2. 公式
  3. 可以解决异常点的影响,所以适合于嘈杂大数据场景(所以一般情况下都用标准化)
  4. API:和归一化一样,还是那个库,只不过方法不一样了
    • sklearn.preprocessing.StandardScaler() :用于实例化标准化转换器。经其处理后,每列数据都将聚集在均值0附近,标准差为1 。
    • StandardScaler.fit_transform(X) :X为 numpy array 格式数据,该方法对数据进行拟合和转换,返回转换后形状相同的数组。
  5. 代码示例解释
    import pandas as pd
    from sklearn.preprocessing import StandardScaler
    
    
    def stand_demo():
        """
        标准化演示
        :return: None
        """
        # 读取数据
        data = pd.read_csv("./data/dating.txt")
        print("原始数据为:\n", data)
    
        # 1. 实例化
        transfer = StandardScaler()
    
        # 2. 进行转换,使用fit_transform
        ret_data = transfer.fit_transform(data[["milage", "Liters", "Consumtime"]])
        print("标准化之后的数据为:\n", ret_data)
    
        # 补充打印每列数据标准化时使用的均值
        print("每一列的均值为:\n", transfer.mean_)
        # 补充打印每列数据标准化时使用的方差
        print("每一列的方差为:\n", transfer.var_)
    
    
    if __name__ == '__main__':
        stand_demo()

 8.继续鸢尾花预测,看流程实现:

一个完整的流程是:

1.获取数据2.数据基本处理(分割数据集,空值处理,异常值处理等)3.特征工程(目前只学过标准化和归一化)4.机器学习(实例化,训练(交叉验证和网格收缩))5.模型评估

from sklearn.datasets import load_iris  #加载数据
from sklearn.model_selection import train_test_split #分割数据
from sklearn.preprocessing import StandardScaler  #特征预处理,标准化
from sklearn.neighbors import KNeighborsClassifier  #机器学习

# 1. 获取数据集
iris = load_iris()

# 2. 数据基本处理
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)

# 3. 特征工程:标准化,注意不需要对标签值进行特征工程
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)#这样就是默认使用上一行的mean与方差。

# 4. 机器学习(模型训练)
estimator = KNeighborsClassifier(n_neighbors=9)
estimator.fit(x_train, y_train)

# 5. 模型评估
# 方法1: 比对真实值和预测值
y_predict = estimator.predict(x_test)
print("预测结果为:\n", y_predict)
print("比对真实值和预测值: \n", y_predict == y_test)

# 方法2: 直接计算准确率
score = estimator.score(x_test, y_test)
print("准确率为: \n", score)

9.交叉验证和网格搜索(一般在技巧学习那里用,很简单,把实例的模型传进去,再传超参数,指定几折交叉验证即可) 。

交叉验证

  • 定义:将训练数据(并不包括测试数据)进一步划分为训练集和验证集。常见如将数据分成n份,每次取其中1份作为验证集,其余n - 1份为训练集,进行n次测试,得到n组模型结果后取平均值。如 4 折交叉验证,就是把数据分成 4 份,依次更换验证集测试 4 次 。
  • 分析:传统数据分为训练集和测试集,而交叉验证让训练集进一步包含验证集部分,通过多轮划分训练和验证,使从训练得到的模型结果更可信。
  • 目的:让被评估的模型更加可信,避免因训练集和验证集划分方式不同导致模型评估偏差 。注意交叉验证并不能使模型结果变得更加准确,只不过是更加可信。。

网格搜索

  • 定义:对于模型中需手动指定的超参数(如 K - 近邻算法中的K值 ),手动指定繁琐。网格搜索预设多种超参数组合,对每组超参数采用交叉验证评估,选出最优参数组合建立模型 。因为有的算法中超参数不止一个。
  • 示例:以 K - 近邻算法为例,预设K = 3、K = 5、K = 7 等不同K值,分别构建模型进行评估。

相关 API(sklearn.model_selection.GridSearchCV )还是一样先实例化在使用方法

  • 功能:对估计器(如分类器、回归器 )的指定参数值进行详尽搜索,结合交叉验证寻找最优参数。
  • 参数
    • estimator:传入的估计器对象,如 KNeighborsClassifier 实例 。
    • param_grid:以字典形式指定估计器的参数及取值范围,如 {"n_neighbors":[1,3,5]} 表示对 K - 近邻算法的n_neighbors参数在1、3、5中搜索最优值 。因为有的算法中超参数不止一个。所以用字典来接收。
    • cv:指定交叉验证的折数 。
  • 方法
    • fit:输入训练数据,执行网格搜索和交叉验证过程 。
    • score:可用于获取模型准确率等评估指标 。
  • 结果分析
    • 对象.bestscore_:交叉验证中得到的最好结果 。
    • 对象.bestestimator:对应最好结果的最优参数模型 。
    • 对象.cvresults:记录每次交叉验证后验证集和训练集的准确率等结果 。

于是预测鸢尾花的完整代码如下(只需要增加算法那一部分即可):

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

# 1、获取数据集
iris = load_iris()

# 2、数据基本处理 -- 划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=2)

# 3、特征工程: 标准化
# 实例化一个转换器类
transfer = StandardScaler()
# 调用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

# 4、KNN预估器流程
# 4.1 实例化预估器类
estimator = KNeighborsClassifier()

# 4.2 模型选择与调优 -- 网格搜索和交叉验证
# 准备要调的超参数
param_dict = {"n_neighbors": [1, 3, 5]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)#3折交叉验证

# 4.3 fit数据进行训练
estimator.fit(x_train, y_train)

# 5、评估模型效果
# 方法a: 比对预测结果和真实值
y_predict = estimator.predict(x_test)
print("比对预测结果和真实值: \n", y_predict == y_test)

# 方法b: 直接计算准确率
score = estimator.score(x_test, y_test)
print("直接计算准确率: \n", score)

# 然后进行评估查看最终选择的结果和交叉验证的结果
print("在交叉验证中验证的最好结果: \n", estimator.best_score_)
print("最好的参数模型: \n", estimator.best_estimator_)
print("每次交叉验证后的准确率结果: \n", estimator.cv_results_)

其实机器学习中数据的预处理是耗时最长的,需要使用pandas等库进行处理。以下整体案例

10.Facebook位置预测案例:

可以看到大部分工作是在数据预处理那里,实现:

import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

# 1. 获取数据集
facebook = pd.read_csv("./data/FBlocation/train.csv")

# 2. 基本数据处理
# 2.1 缩小数据范围
facebook_data = facebook.query("x>2.0 & x<2.5 & y>2.0 & y<2.5")
# 2.2 选择时间特征
time = pd.to_datetime(facebook_data["time"], unit="s")
time = pd.DatetimeIndex(time)
facebook_data["day"] = time.day
facebook_data["hour"] = time.hour
facebook_data["weekday"] = time.weekday
# 2.3 去掉签到较少的地方
place_count = facebook_data.groupby("place_id").count()
place_count = place_count[place_count["row_id"] > 3]#就是把出现次数大于3的id找到了,并且是index
facebook_data = facebook_data[facebook_data["place_id"].isin(place_count.index)]
# 2.4 确定特征值和目标值
x = facebook_data[["x", "y", "accuracy", "day", "hour", "weekday"]]
y = facebook_data["place_id"]
# 2.5 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)

# 3. 特征工程--特征预处理(标准化)
# 3.1 实例化一个转换器
transfer = StandardScaler()
# 3.2 调用fit_transform
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)

# 4. 机器学习--knn+cv
# 4.1 实例化一个估计器
estimator = KNeighborsClassifier()
# 4.2 调用gridsearchCV
param_grid = {"n_neighbors": [1, 3, 5, 7, 9]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=5)
# 4.3 模型训练
estimator.fit(x_train, y_train)

# 5. 模型评估
# 5.1 基本评估方式
score = estimator.score(x_test, y_test)
print("最后预测的准确率为:\n", score)
y_predict = estimator.predict(x_test)
print("最后的预测值为:\n", y_predict)
print("预测值和真实值的对比情况:\n", y_predict == y_test)

# 5.2 使用交叉验证后的评估方式
print("在交叉验证中验证的最好结果:\n", estimator.best_score_)
print("最好的参数模型:\n", estimator.best_estimator_)
print("每次交叉验证后的验证集准确率结果和训练集准确率结果:\n", estimator.cv_results_)

代码解释

  1. 导入模块
    导入 pandas 用于数据读取和处理;train_test_split 用于划分数据集;GridSearchCV 用于网格搜索和交叉验证;StandardScaler 用于特征标准化;KNeighborsClassifier 作为 K - 近邻分类器。
  2. 获取数据集
    使用 pd.read_csv 读取指定路径下的 train.csv 数据集到 facebook 变量。
  3. 基本数据处理
    • 缩小数据范围:使用 query 方法筛选出满足 x 和 y 坐标范围条件的数据到 facebook_data 。
    • 选择时间特征:将时间戳数据转换为日期时间格式,提取出 day(日)、hour(小时)、weekday(星期几)等特征添加到数据集中。
    • 去掉签到较少的地方:按 place_id 分组统计数量,筛选出签到数大于 3 的 place_id ,再筛选出对应这些 place_id 的数据。
    • 确定特征值和目标值:确定特征矩阵 x 和目标向量 y 。
    • 分割数据集:将数据划分为训练集和测试集,random_state=22 保证划分结果可复现。
  4. 特征工程 - 标准化
    实例化 StandardScaler 对训练集和测试集的特征数据进行标准化处理。
  5. 机器学习 - knn + cv
    • 实例化估计器:实例化 KNeighborsClassifier 作为 K - 近邻分类模型。
    • 调用 gridsearchCV:设置要搜索的超参数 n_neighbors 的取值范围,使用 GridSearchCV 结合交叉验证寻找最优超参数。
    • 模型训练:使用训练集数据训练模型。
  6. 模型评估
    • 基本评估方式:计算模型在测试集上的准确率,进行预测并对比预测值和真实值。
    • 交叉验证评估方式:查看交叉验证中的最佳结果、最优参数模型以及每次交叉验证的准确率结果。

因为时间戳不能直接用于分析,得转换,我们看一下处理时间的步骤吧:

这是本来的数据:

这样可以转换为我们可以识别的数据,但是最后一行我们看不懂,

这样就能看懂了:

但是这样还不能使用,这样就可以使用了:可以通过.属性访问具体的内容

比如:

这样我们可以把日期,时等要用的加到数据集里边:

facebook_data["day"] = time.day
facebook_data["hour"] = time.hour
facebook_data["weekday"] = time.weekday

于是,处理好的就是这样

11.补充说明:

留出法其实就是我们接触到的数据分割

http://www.dtcms.com/a/121772.html

相关文章:

  • 大数据专业学习路线
  • 某团某点评mtgsig1.2 H5guard加密算法剖析
  • 深入解析Java中的栈:从JVM原理到开发实践
  • 基于IDEA+SpringBoot+Mave+Thymeleaf的系统实现
  • 量子计算入门:开启未来计算的次元之门
  • 华为数字芯片机考2025合集4已校正
  • 【安卓】APP生成器v1.0,生成属于你的专属应用
  • FRP练手:hello,world实现
  • JavaScript的可选链操作符 ?.
  • 【WPF】IOC控制反转的应用:弹窗但不互相调用ViewModel
  • 构建实时、融合的湖仓一体数据分析平台:基于 Delta Lake 与 Apache Iceberg
  • 基于机器视觉的多孔零件边缘缺陷检测(源码C++、opencv、凸包、凸缺陷检测)
  • eplan许可证的用户权限管理
  • 4.实战篇-延迟约束
  • 基于MCP协议调用的大模型agent开发02
  • 11. 盛最多水的容器
  • Linux系统之rm命令的基本使用
  • leetcode每日一题:子数组异或查询
  • 主键索引和唯一索引的区别
  • linux安装mysql常出现的问题
  • 【Linux】进程信号(下)
  • 显示背光发烫异常解析
  • SQL语法进阶篇(一),数据库复杂查询——子查询
  • Redis过期key处理、内存淘汰策略与缓存一致性策略实践方案
  • PG:数据库表年龄大和表大的解决方案
  • Vue 框架组件间通信方式
  • Matplotlib图表坐标轴中文标签显示问题
  • 打印大X | 第六届蓝桥杯省赛C++C组
  • TDengine 数据模型设计:多列模式与单列模式对比(二)
  • PowerBI之DAX 2:聚合、统计、关系、表操作函数