美文网首页
2020-05-20 第十一章 kNN模型的应用

2020-05-20 第十一章 kNN模型的应用

作者: 程凉皮儿 | 来源:发表于2020-05-20 10:26 被阅读0次

第十一章 kNN模型的应用

内容目录

[TOC]

01 kNN算法的思想

模型介绍

KNN模型仍然为有监督的学习算法,它的中文名称为K最近邻算法。它属于“惰性”学习算法,即不会预先生成一个分类或预测模型,用于新样本的预测,而是将模型的构建与未知数据的预测同时进行。
该算法既可以针对离散因变量做分类,又可以对连续因变量做预测,其核心思想就是比较已知y值的样本与未知y值样本的相似度,然后寻找最相似的k个样本用作未知样本的预测。

算法示意图

image.png

如图所示,模型的本质就是寻找k个最近样本,然后基于最近样本做“预测”。对于离散型的因变量来说,从k个最近的已知类别样本中挑选出频率最高的类别用于未知样本的判断;对于连续型的因变量来说,则是将k个最近的已知样本均值用作未知样本的预测。

算法步骤

  • 确定未知样本近邻的个数k值。
  • 根据某种度量样本间相似度的指标(如欧氏距离)将每一个未知类别样本的最近k个已知样本搜寻出来,形成一个个簇。
  • 对搜寻出来的已知样本进行投票,将各簇下类别最多的分类用作未知样本点的预测。

02 最佳k值的选择

k值对模型的影响

根据经验发现,不同的k值对模型的预测准确性会有比较大的影响,如果k值过于偏小,可能会导致模型的过拟合;反之,又可能会使模型进入欠拟合状态。


image.png

k值选择方案

  • 一种是设置k近邻样本的投票权重,假设读者在使用KNN算法进行分类或预测时设置的k值比较大,担心模型发生欠拟合的现象,一个简单有效的处理办法就是设置近邻样本的投票权重,如果已知样本距离未知样本比较远,则对应的权重就设置得低一些,否则权重就高一些,通常可以将权重设置为距离的倒数。


    image.png
  • 采用多重交叉验证法,该方法是目前比较流行的方案,其核心就是将k取不同的值,然后在每种值下执行m重的交叉验证,最后选出平均误差最小的k值。
  • 当然,还可以将两种方法的优点相结合,选出理想的k值。

示例结果如下:最佳K值为5

# 导入第三方包
import pandas as pd
import numpy as np
# 导入数据
Knowledge = pd.read_excel('Knowledge.xlsx')
# 返回前5行数据
Knowledge.head()
image.png
# 构造训练集和测试集
# 导入第三方模块
from sklearn import model_selection
# 将数据集拆分为训练集和测试集
predictors = Knowledge.columns[:-1]
X_train, X_test, y_train, y_test = model_selection.train_test_split(Knowledge[predictors], Knowledge.UNS, 
                                                                    test_size = 0.25, random_state = 1234)
np.ceil(np.log2(Knowledge.shape[0]))
9.0
# 导入第三方模块
import numpy as np
from sklearn import neighbors
import matplotlib.pyplot as plt

# 设置待测试的不同k值
K = np.arange(1,np.ceil(np.log2(Knowledge.shape[0])))
# 构建空的列表,用于存储平均准确率
accuracy = []
for k in K:
    # 使用10重交叉验证的方法,比对每一个k值下KNN模型的预测准确率
    cv_result = model_selection.cross_val_score(neighbors.KNeighborsClassifier(n_neighbors = int(k), weights = 'distance'), 
                                                X_train, y_train, cv = 10, scoring='accuracy')
    accuracy.append(cv_result.mean())

# 从k个平均准确率中挑选出最大值所对应的下标    
arg_max = np.array(accuracy).argmax()
# 中文和负号的正常显示
plt.rcParams['font.sans-serif'] = ['Helvetica']
plt.rcParams['axes.unicode_minus'] = False
# 绘制不同K值与平均预测准确率之间的折线图
plt.plot(K, accuracy)
# 添加点图
plt.scatter(K, accuracy)
# 添加文字说明
plt.text(K[arg_max], accuracy[arg_max], 'The best k value is %s' %int(K[arg_max]))
# 显示图形
plt.show()
output_4_0.png

03 样本间相似度的度量方法

欧氏距离

image.png

曼哈顿距离

image.png

余弦相似度

image.png

杰卡德相似系数

杰卡德相似系数与余弦相似度经常被用于推荐算法,计算用户之间的相似性。例如,A用户购买了10件不同的商品,B用户购买了15件不同的商品,则两者之间的相似系数可以表示为:

image.png
其中,|A⋂B|表示两个用户所购买相同商品的数量,|A⋃B|代表两个用户购买所有产品的数量。例如,A用户购买的10件商品中有8件与B用户一致,且两个用户一共购买了17件不同的商品,则它们的杰卡德相似系数为8/17

04 KNN算法的应用实战

kNN模型的函数

neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', 
                       leaf_size=30, p=2, metric='minkowski', 
                       metric_params=None, n_jobs=1)

n_neighbors:用于指定近邻样本个数K,默认为5
weights:用于指定近邻样本的投票权重,默认为'uniform',表示所有近邻样本的投票权重一样;如果为'distance',则表示投票权重与距离成反比,即近邻样本与未知类别的样本点距离越远,权重越小,反之,权重越大
algorithm:用于指定近邻样本的搜寻算法,如果为'ball_tree',则表示使用球树搜寻法寻找近邻样本;如果为'kd_tree',则表示使用KD树搜寻法寻找近邻样本;如果为'brute',则表示使用暴力搜寻法寻找近邻样本。默认为'auto',表示KNN算法会根据数据特征自动选择最佳的搜寻算法
leaf_size:用于指定球树或KD树叶子节点所包含的最小样本量,它用于控制树的生长条件,会影响树的查询速度,默认为30
metric:用于指定距离的度量指标,默认为闵可夫斯基距离
p:当参数metric为闵可夫斯基距离时,p=1,表示计算点之间的曼哈顿距离;p=2,表示计算点之间的欧氏距离;该参数的默认值为2
metric_params:为metric参数所对应的距离指标添加关键字参数
n_jobs:用于设置KNN算法并行计算所需的CPU数量,默认为1表示仅使用1个CPU运行算法,即不使用并行运算功能

知识接受水平的判别

# 导入第三方模块
from sklearn import metrics

# 重新构建模型,并将最佳的近邻个数设置为6
knn_class = neighbors.KNeighborsClassifier(n_neighbors = 6, weights = 'distance')
# 模型拟合
knn_class.fit(X_train, y_train)
# 模型在测试数据集上的预测
predict = knn_class.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(predict,y_test)
cm
image.png
# 导入第三方模块
import seaborn as sns

# 将混淆矩阵构造成数据框,并加上字段名和行名称,用于行或列的含义说明
cm = pd.DataFrame(cm)
# 绘制热力图
sns.heatmap(cm, annot = True,cmap = 'GnBu')
# 添加x轴和y轴的标签
plt.xlabel(' Real Lable')
plt.ylabel(' Predict Lable')
# 图形显示
plt.show()
output_7_0.png
# 模型整体的预测准确率
metrics.accuracy_score(y_test, predict)
0.9108910891089109
# 分类模型的评估报告
print(metrics.classification_report(y_test, predict))
              precision    recall  f1-score   support

        High       1.00      0.97      0.98        30
         Low       0.81      1.00      0.89        34
      Middle       0.96      0.88      0.92        26
    Very Low       1.00      0.55      0.71        11

    accuracy                           0.91       101
   macro avg       0.94      0.85      0.88       101
weighted avg       0.93      0.91      0.91       101

高炉发电量预测

# 读入数据
ccpp = pd.read_excel('CCPP.xlsx')
ccpp.head()
image.png
# 返回数据集的行数与列数
ccpp.shape
(9568, 5)
# 导入第三方包
from sklearn.preprocessing import minmax_scale
# 对所有自变量数据作标准化处理
predictors = ccpp.columns[:-1]
X = minmax_scale(ccpp[predictors])
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, ccpp.PE, 
                                                                    test_size = 0.25, random_state = 1234)
# 设置待测试的不同k值
K = np.arange(1,np.ceil(np.log2(ccpp.shape[0])))
# 构建空的列表,用于存储平均MSE
mse = []
for k in K:
    # 使用10重交叉验证的方法,比对每一个k值下KNN模型的计算MSE
    cv_result = model_selection.cross_val_score(neighbors.KNeighborsRegressor(n_neighbors = int(k), weights = 'distance'), 
                                                X_train, y_train, cv = 10, scoring='neg_mean_squared_error')
    mse.append((-1*cv_result).mean())

# 从k个平均MSE中挑选出最小值所对应的下标  
arg_min = np.array(mse).argmin()
# 绘制不同K值与平均MSE之间的折线图
plt.plot(K, mse)
# 添加点图
plt.scatter(K, mse)
# 添加文字说明
plt.text(K[arg_min], mse[arg_min] + 0.5, 'The best k value is %s' %int(K[arg_min]))
# 显示图形
plt.show()
output_15_0.png
# 重新构建模型,并将最佳的近邻个数设置为7
knn_reg = neighbors.KNeighborsRegressor(n_neighbors = 7, weights = 'distance')
# 模型拟合
knn_reg.fit(X_train, y_train)
# 模型在测试集上的预测
predict = knn_reg.predict(X_test)
# 计算MSE值
metrics.mean_squared_error(y_test, predict)
12.814094947334913
# 对比真实值和实际值
pd.DataFrame({'Real':y_test,'Predict':predict}, columns=['Real','Predict']).head(10)
image.png
# 导入第三方模块
from sklearn import tree

# 预设各参数的不同选项值
max_depth = [19,21,23,25,27]
min_samples_split = [2,4,6,8]
min_samples_leaf = [2,4,8,10,12]
parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf}
# 网格搜索法,测试不同的参数值
grid_dtreg = model_selection.GridSearchCV(estimator = tree.DecisionTreeRegressor(), param_grid = parameters, cv=10)
# 模型拟合
grid_dtreg.fit(X_train, y_train)
# 返回最佳组合的参数值
grid_dtreg.best_params_
{'max_depth': 19, 'min_samples_leaf': 10, 'min_samples_split': 8}
# 构建用于回归的决策树
CART_Reg = tree.DecisionTreeRegressor(max_depth = 21, min_samples_leaf = 10, min_samples_split = 6)
# 回归树拟合
CART_Reg.fit(X_train, y_train)
# 模型在测试集上的预测
pred = CART_Reg.predict(X_test)
# 计算衡量模型好坏的MSE值
metrics.mean_squared_error(y_test, pred)
16.17598770280406

相关文章

  • 2020-05-20 第十一章 kNN模型的应用

    第十一章 kNN模型的应用 内容目录 [TOC] 01 kNN算法的思想 模型介绍 KNN模型仍然为有监督的学习算...

  • KNN近邻算法总结

    目录 一、KNN近邻算法思想 二、KNN模型三大要素 三、KNN算法实现步骤 四、KNN算法的KD树实现 五、总结...

  • knn 笔记

    经常把knn和kmeans搞混,knn是监督学习,用于分类或回归,kmeans是无监督的聚类模型。 对于knn,这...

  • SKIL/工作流程/KNN(K邻近值算法)

    K邻近值算法 除了部署转换和网络模型,SKIL还允许你部署KNN模型。 KNN (k邻近值算法) 是最简单的分类算...

  • 超参数

    超参数:在我们运行机器学习算法之前,需要指定的参数。模型参数:算法过程中学习的参数。 kNN算法没有模型参数kNN...

  • 机器学习

    经典模型 KNN KNN是一个non-parametric模型,可以用于分类和回归。通过选取k个最近的点,比较这k...

  • 第七节超参数

    超参数:在算法运行前需要决定的参数;模型参数:算法过程中学习的参数。KNN算法没有模型参数;KNN算法中的k是典型...

  • 纯numpy动手写K近邻模型

    简单清晰的的基于线性扫描实现的KNN模型

  • KNN

    1. KNN基本思想 KNN是一个基本而简单的分类算法,作为监督学习,那么KNN模型需要的是有标签的训练数据,对于...

  • 2017.11.05学习笔记1-k近邻算法原理

    目标 1、理解KNN算法的核心思想2、理解KNN算法的实现3、掌握KNN算法的应用步骤:数据处理、建模、运算和结果...

网友评论

      本文标题:2020-05-20 第十一章 kNN模型的应用

      本文链接:https://www.haomeiwen.com/subject/fqkgohtx.html