机器学习——KNN算法实例

这篇具有很好参考价值的文章主要介绍了机器学习——KNN算法实例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.项目背景

2.流程步骤 

3.代码部分

3.1导入可能需要用的包 

3.2准备数据:从文本文件中解析数据

 3.3分析数据:用Matplotlib创建散点图

 3.4准备数据:数据归一化

3.5 测试算法:作为完整程序验证分类器

 【关于K值的选择】

3.6使用算法:构建完整可用系统

4.总结 

 文章来源地址https://www.toymoban.com/news/detail-500313.html


关于KNN算法的简单理解在我的上一篇博客机器学习——K-近邻算法_装进了牛奶箱中的博客-CSDN博客

1.项目背景

近期集美大学在进行贫困生评定工作,先根据学生的家庭人均年收入,使用手机价格以及每月外出吃饭次数简单判断该学生是否贫困。根据以上三个特征,借助KNN分类,将学生家庭情况分为贫困,普通,富裕三类。

2.流程步骤 

(1)收集数据:使用Excel表格列出数据,并将其另存为.txt文件。

(2)准备数据:使用python解析文本文件。

(3)分析数据:使用Matplotlib画二维扩散图。

(4)训练算法:此步骤不适用于k近邻算法。

(5)测试算法:选定文本文件中的部分数据作为测试样本。

测试样本与非测试样本的区别:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。

(6) 使用算法:产生简单的命令行程序,输入某位学生的家庭人均年收入,使用手机价格以及每月外出吃饭次数,然后系统可以判断该学生的家庭情况。

3.代码部分

3.1导入可能需要用的包 

import cv2
import pandas as pd
import numpy as np
from numpy import *
from matplotlib.font_manager import FontProperties
import matplotlib
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.interpolate import interp1d
import operator
import matplotlib as mpl

 有些包可能用不到,我在解决matplotlib不能显示中文的问题时,尝试多种解决办法导入了许多可能用不到的包

3.2准备数据:从文本文件中解析数据

学生个人情况数据集存放在KNNdata1.txt中,每个样本数据占据一行,总共有1101行。样本主要包含以下三个特征:

  1. 家庭人均年收入
  2. 使用手机价格
  3. 每月外出吃饭次数 

创建fileMatrix函数,将输入为文件名字符串,输出为训练样本矩阵和类标签向量

def fileMatrix(filename):
    file = open(filename) #打开文件
    arrayOLines = file.readlines() #读取文件所有内容
    numberOfLines = len(arrayOLines) #得到文件行数
    returnMat = zeros((numberOfLines, 3)) #返回给定形状和类型的新数组,用0填充
    classLabelVector = []#返回的分类标签向量
    index = 0 #行的索引值
    for line in arrayOLines:
        line = line.strip()#用于移除字符串头尾指定的字符,默认删除空白符(包括'\n','\t','\r',' ')
        listFromLine = line.split('\t')#通过指定分隔符对字符串进行切片,返回分割后的字符串列表
        returnMat[index,:] = listFromLine[0:3]#将数据前三列提取出来,存放到returnMat的numpy矩阵中
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector

运行结果 

机器学习——KNN算法实例 

 

 3.3分析数据:用Matplotlib创建散点图

def showdatas(datingDataMat, datingLabels):
    #设置汉字格式
    # sans-serif就是无衬线字体,是一种通用字体族。
    mpl.rcParams['font.sans-serif'] = ['Songti SC']  # 用来正常显示中文标签
    mpl.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
    #将fig画布分隔成2行2列,不共享x轴和y轴,fig画布的大小为(13,8)
    #当nrow=2,nclos=2时,代表fig画布被分为四个区域,axs[0][0]表示第一行第一个区域
    fig, axs = plt.subplots(nrows=2, ncols=2,sharex=False, sharey=False, figsize=(13,9))
 
    LabelsColors = []
    for i in datingLabels:
        if i == 0:
            LabelsColors.append('green')
        if i == 1:
            LabelsColors.append('red')
        if i == 2:
            LabelsColors.append('blue')
 
    #画出散点图,以datingDataMat矩阵的第一(家庭人均年收入)、第二列(使用手机价格)数据画散点数据,散点大小为15,透明度为0.5
    axs[0][0].scatter(x=datingDataMat[:,0], y=datingDataMat[:,1], color=LabelsColors,s=15, alpha=.5)
    #设置标题,x轴label,y轴label
    axs0_title_text = axs[0][0].set_title('家庭人均年收入与使用手机价格')
    axs0_xlabel_text = axs[0][0].set_xlabel('家庭人均年收入')
    axs0_ylabel_text = axs[0][0].set_ylabel('使用手机价格')
    plt.setp(axs0_title_text, size=12, weight='bold', color='red')
    plt.setp(axs0_xlabel_text, size=10, weight='bold', color='black')
    plt.setp(axs0_ylabel_text, size=10, weight='bold', color='black')
 
    #画出散点图,以datingDataMat矩阵的第一(家庭人均年收入)、第三列(每月外出吃饭次数)数据画散点数据,散点大小为15,透明度为0.5
    axs[0][1].scatter(x=datingDataMat[:,0], y=datingDataMat[:,2], color=LabelsColors,s=15, alpha=.5)
    #设置标题,x轴label,y轴label
    axs1_title_text = axs[0][1].set_title('家庭人均年收入与每月外出吃饭次数',)
    axs1_xlabel_text = axs[0][1].set_xlabel('家庭人均年收入')
    axs1_ylabel_text = axs[0][1].set_ylabel('每月外出吃饭次数')
    plt.setp(axs1_title_text, size=12, weight='bold', color='red')
    plt.setp(axs1_xlabel_text, size=10, weight='bold', color='black')
    plt.setp(axs1_ylabel_text, size=10, weight='bold', color='black')
 
    #画出散点图,以datingDataMat矩阵的第二(使用手机价格)、第三列(每月外出吃饭次数)数据画散点数据,散点大小为15,透明度为0.5
    axs[1][0].scatter(x=datingDataMat[:,1], y=datingDataMat[:,2], color=LabelsColors,s=15, alpha=.5)
    #设置标题,x轴label,y轴label
    axs2_title_text = axs[1][0].set_title('使用手机价格与每月外出吃饭次数')
    axs2_xlabel_text = axs[1][0].set_xlabel('使用手机价格')
    axs2_ylabel_text = axs[1][0].set_ylabel('每月外出吃饭次数')
    plt.setp(axs2_title_text, size=12, weight='bold', color='red')
    plt.setp(axs2_xlabel_text, size=10, weight='bold', color='black')
    plt.setp(axs2_ylabel_text, size=10, weight='bold', color='black')
 
    #设置图例
    impoverished = mlines.Line2D([], [], color='green', marker='.', markersize=6, label='贫困')
    ordinary = mlines.Line2D([], [], color='red', marker='.',markersize=6, label='普通')
    affluent = mlines.Line2D([], [], color='blue', marker='.',markersize=6, label='富裕')
    #添加图例
    axs[0][0].legend(handles=[impoverished,ordinary,affluent])
    axs[0][1].legend(handles=[impoverished,ordinary,affluent])
    axs[1][0].legend(handles=[impoverished,ordinary,affluent])
    #显示图片
    plt.show()

datingDataMat, datingLabels = fileMatrix('KNNdata1.txt')
showdatas(datingDataMat,datingLabels)
 

 遇到的问题matplotlib不能显示中文

解决办法macos或windows中 matplotlib中文显示(matplotlib字体常见使用)_吨吨不打野的博客-CSDN博客_mac matplotlib 显示中文

不同系统的字体可能不一样,windows大多用simhei,macOS用Songti SC 或STFangsong,一定一定要根据自己的系统查找解决方法 

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

plt.rcParams['font.sans-serif']=['Songti SC'] #用来正常显示中文标签
# 或者是下面这个,宋体和仿宋字体,都可以用。
plt.rcParams['font.sans-serif']=['STFangsong'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

运行结果 

机器学习——KNN算法实例

 3.4准备数据:数据归一化

在处理不同取值范围的特征值时,我们通常采用的方法是将数值归一化,创建autoNorm函数,自动的将数字特征值转化为0到1的区间

使用 newValue = (oldValue - min) / (max - min) 将任意取值范围的特征值转化为0到1区间内的值

def autoNorm(dataSet):
    #获得每列数据的最小值和最大值
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals #最大值和最小值范围
    normDataSet = zeros(shape(dataSet)) 
    m = dataSet.shape[0] #返回dataset的行数
    normDataSet = dataSet - tile(minVals, (m, 1))  #原始值减去最小值
    normDataSet = normDataSet/tile(ranges, (m, 1)) #除以最大和最小值的差,得到归一化数据
    return normDataSet, ranges, minVals #返回归一化数据结果,数据范围,最小值

datingDatMat, datingLabels = fileMatrix('KNNdata1.txt')
normData, ranges, minVals = autoNorm(datingDatMat)
print('normData')
print(normData)
print('ranges')
print(ranges)
print('minVals')
print(minVals)

运行结果

机器学习——KNN算法实例

3.5 测试算法:作为完整程序验证分类器

提供已有数据的80%作为训练样本来训练分类器,而其余的20%数据去测试分类器,检测分类算法的正确率。

def datingClassTest():
    hoRatio = 0.2 #20%的测试数据
    datingDatMat, datingLabels = fileMatrix('KNNdata1.txt')  #从文件读数据
    normMat, ranges, minVals = autoNorm(datingDatMat)              #数据的归一化
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)                                   #测试数据数量
    errorCount = 0.0                                               #错误数量统计
    for i in range(numTestVecs):
        classifierResult = classify(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 1)
        print("分类器返回的结果是:%d,真实结果是:%d"%(classifierResult, datingLabels[i]))
        if(classifierResult != datingLabels[i]):
            errorCount += 1.0
    print('分类器处理约会数据集的错误率是:%f'%(errorCount/float(numTestVecs)))

 这里还调用了分类器函数classify

#KNN算法分类器

#inX 用于分类的数据(测试集)

#dataSet 用于训练的数据(训练集)

#labes 训练数据的分类标签

#k KNN算法的参数,选择距离最小的k个点

#sortedClassCount[0][0] 分类结果

def classify(inX, dataSet, labels, k):
    #dataSetSize是训练样本集数量
    dataSetSize = dataSet.shape[0]
 
    #距离计算——欧式距离公式
    #tile函数,把inX变成能与dataSet相减的二维数组
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    #axis=1是列相加求和,即得到(x1-x2)^2+(y1-y2)^2的值
    sqDistances = sqDiffMat.sum(axis = 1)     
    distances = sqDistances ** 0.5
 
    #按照距离递增次序排序,返回下标
    sortedDistIndicies = distances.argsort()
 
    #选择距离最小的k个点
    classCount = {}
    for i in range(k):
        voteILabel = labels[sortedDistIndicies[i]]
        classCount[voteILabel] = classCount.get(voteILabel,0) + 1
 
    #按照字典里的关键字的值排序,reverse=True降序排序
    sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
    
    #返回类别最多的标签
    return sortedClassCount[0][0]

 运行结果

当k=1,hoRatio=0.2时,分类器处理数据集的错误率是2.3%

这是一个还算不错的结果,但是我们可以通过改变数据集和训练集的比例以及k的值,来检测错误率随着变量值的变化而变大或变小

机器学习——KNN算法实例

 当k=1,hoRatio=0.1时,分类器处理数据集的错误率是0.9%

机器学习——KNN算法实例

 当k=1,hoRatio=0.3时,分类器处理数据集的错误率是2.4% 

机器学习——KNN算法实例

  当k=3,hoRatio=0.2时,分类器处理数据集的错误率接近0

机器学习——KNN算法实例 

 当k=7,hoRatio=0.2时,分类器处理数据集的错误率是1.4% 

机器学习——KNN算法实例 

 

 【关于K值的选择】

 李航博士《统计学说明方法》

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

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

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

在实际应用中,K值一般取一个比较小的数值,例如采用交叉验证法(简单来说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值。对这个简单的分类器进行泛化,用核方法把这个线性模型扩展到非线性的情况,具体方法是把低维数据集映射到高维特征空间。

看了很多博客k值的选择他们大多用的是交叉验证,不过我没有很看懂,不太会用,所以在k值的选择问题上,我是用最简单的办法:一个一个数字试,发现在k=3时错误率最小

K值过小,容易受到异常点的影响,出现过拟合的问题;K值过大,容易受到样本均衡的影响,出现欠拟合的问题。

K值一般选择奇数3,5,7

因为我的数据是自己编造的,异常数据较少,所以实际上错误率随着k值的改变变化的较少,这个例子不能很好的说明k值的选择问题,只能体会精神

3.6使用算法:构建完整可用系统

使用分类器评定学生家庭情况,通过输入学生个人情况,程序会给出该学生的家庭情况

def classifyPerson():
    resultList = ['贫困', '普通', '富裕']
    precentTats = float(input('家庭人均年收入:'))           #用户输入三个特征
    ffMiles = float(input('使用手机价格:')) 
    iceCream = float(input('每月外出吃饭次数:'))
    datingDatMat, datingLabels = fileMatrix('KNNdata.txt')    #文件数据读入
    normMat, ranges, minVals = autoNorm(datingDatMat)               
    inArr = array([precentTats, ffMiles, iceCream])                  #生成测试集                
    norminArr = (inArr-minVals)/ranges                               #数据归一化
    classifierResult = classify(norminArr, normMat, datingLabels, 3) #分类器分类
    print('这位学生的家庭情况可能是%s'%(resultList[classifierResult]))

 运行结果

机器学习——KNN算法实例

机器学习——KNN算法实例 

机器学习——KNN算法实例 

机器学习——KNN算法实例 

4.总结 

通过改变函数datingClassTest内变量hoRatio和变量k的值,发现hoRatio的值越小,错误率越小;在hoRatio值不变的情况下,随着k值的变化,错误率会先变小后变大,而使得错误率最小的那个k值就是最优值。 

 

 

到了这里,关于机器学习——KNN算法实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【机器学习实战】K- 近邻算法(KNN算法)

    K-近邻算法 ,又称为  KNN 算法 ,是数据挖掘技术中原理最简单的算法。 KNN  的工作原理:给定一个已知类别标签的数据训练集,输入没有标签的新数据后,在训练数据集中找到与新数据最临近的 K 个实例。如果这 K 个实例的多数属于某个类别,那么新数据就属于这个类别。

    2023年04月20日
    浏览(57)
  • 机器学习KNN最邻近分类算法

    KNN (K-Nearest Neighbor) 最邻近分类算法,其核心思想“近朱者赤,近墨者黑”,由你的邻居来推断你的类别。 图中绿色圆归为哪一类? 1、如果k=3,绿色圆归为红色三角形 2、如果k=5,绿色圆归为蓝色正方形 参考文章 knn算法实现原理:为判断未知样本数据的类别,以所有已知样

    2024年04月10日
    浏览(68)
  • 机器学习——K近邻(KNN)算法

    目录 一、knn算法概述 1.简单介绍 2.工作原理 3.knn算法中常用的距离指标 4.knn算法优势 5.knn算法一般流程 二、knn算法经典实例——海伦约会网站 三、关于天气和旅行适合度的例子 四、总结 K近邻算法(KNN)是一种用于分类和回归的统计方法。k-近邻算法采用测量不同特征值之

    2024年01月16日
    浏览(38)
  • 机器学习——kNN算法之红酒分类

    目录 StandardScaler的使用 KNeighborsClassifier的使用 代码实现 数据集介绍 数据集为一份红酒数据,总共有 178 个样本,每个样本有 13 个特征,这里不会为你提供红酒的标签,你需要自己根据这 13 个特征对红酒进行分类。部分数据如下图: StandardScaler的使用 由于数据中有些特征的

    2024年02月11日
    浏览(38)
  • 机器学习——K最近邻算法(KNN)

    机器学习——K最近邻算法(KNN) 在传统机器学习中,KNN算法是一种基于实例的学习算法,能解决分类和回归问题,而本文将介绍一下KNN即K最近邻算法。 K最近邻(KNN)算法是一种基于实例的学习算法,用于分类和回归问题。它的原理是 根据样本之间的距离来进行预测 。 核

    2024年02月09日
    浏览(42)
  • 【机器学习】分类算法 - KNN算法(K-近邻算法)KNeighborsClassifier

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 is_array() 可以 「检测」 变量是不是 「数组」 类型。 语法 参数 $var :需要检

    2024年02月16日
    浏览(42)
  • 【机器学习】机器学习常见算法详解第4篇:KNN算法计算过程(已分享,附代码)

    本系列文章md笔记(已分享)主要讨论机器学习算法相关知识。机器学习算法文章笔记以算法、案例为驱动的学习,伴随浅显易懂的数学知识,让大家掌握机器学习常见算法原理,应用Scikit-learn实现机器学习算法的应用,结合场景解决实际问题。包括K-近邻算法,线性回归,逻

    2024年02月19日
    浏览(35)
  • 【机器学习】KNN算法-鸢尾花种类预测

    K最近邻(K-Nearest Neighbors,KNN)算法是一种用于模式识别和分类的简单但强大的机器学习算法。它的工作原理非常直观:给定一个新数据点,KNN算法会查找离这个数据点最近的K个已知数据点,然后基于这K个最近邻数据点的类别来决定新数据点的类别。简而言之,KNN算法通过周

    2024年02月07日
    浏览(42)
  • 机器学习-KNN算法(鸢尾花分类实战)

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 K近邻(K Nearest Neighbors,KNN)算法是最简单的分类算法之一,也就是根据现有训练数据判断输入样本是属于哪一个类别。 “近朱者赤近墨者黑\\\",所谓的K近邻,也就

    2023年04月08日
    浏览(72)
  • 头歌机器学习---sklearn中的kNN算法

    第1关 使用sklearn中的kNN算法进行分类 第2关 使用sklearn中的kNN算法进行回归

    2024年02月06日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包