导读:机器学习算法中KNN属于比较简单的典型算法,既能够作聚类又能够作分类使用。本文经过一个模拟的实际案例进行讲解。整个流程包括:采集数据、数据格式化处理、数据分析、数据归一化处理、构造算法模型、评估算法模型和算法模型的应用。(本文原创,转载必须注明出处: 一步步教你轻松学KNN模型算法)javascript
什么是KNN?css
k-近邻(kNN,k-NearestNeighbor)算法是一种基本分类与回归方法,咱们这里只讨论分类问题中的 k-近邻算法。k-近邻算法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,能够取多类。k-邻算法假设给定一个训练数据集,其中的实例类别已定。分类时,对新的实例,根据其 k 个最近邻的训练实例的类别,经过多数表决等方式进行预测。所以,k近邻算法不具备显式的学习过程即属于有监督学习范畴。k近邻算法实际上利用训练数据集对特征向量空间进行划分,并做为其分类的“模型”。k值的选择、距离度量以及分类决策规则是k近邻算法的三个基本要素。html
KNN算法思想java
1 计算已知类别中数据集的点与当前点的距离。[即计算全部样本点跟待分类样本之间的距离] 2 按照距离递增次序排序。[计算完样本距离进行排序] 3 选取与当前点距离最小的k个点。[选取距离样本最近的k个点] 4 肯定前k个点所在类别的出现频率。[针对这k个点,统计下各个类别分别有多少个] 5 返回前k个点出现频率最高的类别做为当前点的预测分类。[k个点中某个类别最多,就将样本划归改点]
KNN工做原理python
1 假设有一个带有标签的样本数据集(训练样本集),其中包含每条数据与所属分类的对应关系。 2 输入没有标签的新数据后,将新数据的每一个特征与样本集中数据对应的特征进行比较。 3 计算新数据与样本数据集中每条数据的距离。 4 对求得的全部距离进行排序(从小到大,越小表示越类似)。 5 取前 k (k 通常小于等于 20 )个样本数据对应的分类标签。 6 求 k 个数据中出现次数最多的分类标签做为新数据的分类。
KNN算法流程jquery
1 搜集数据:数据采集过程,其分为非结构化数据,半结构化数据和数据化数据。诸如:网络爬取,数据库,文件等。 2 准备数据:格式化处理,对不一样类别的数据进行统一的格式化处理。诸如:将pdf,word,excel,sql等等统一转化为txt文本。 3 分析数据:主要看看数据特色,有没有缺失值,数据连续性仍是离散型,进而选择不一样模型。诸如:可视化数据分析 4 训练数据:不适用于KNN,可是在其余一些监督学习中会常常遇到,诸如:朴素贝叶斯分类等。 5 测试算法:评价指标,如计算错误率,准确率,召回率,F度量值等。 6 应用算法:针对完善的模型进行封装重构,而后进行实际应用。
KNN优缺点git
优势:精度高、对异常值不敏感、无数据输入假定 缺点:计算复杂度高、空间复杂度好 适用数据范围:数值型和标称型
建立模拟数据集github
描述:如今你来了一个新的任务,任务其实很是简单,就是根据吃冰淇淋和喝水的数量判断成都天气冷热程度。你如今要作的就是去成都春熙路街头采访记录一些游客吃了多少冰淇淋,又喝了几瓶水,他以为成都天气怎么样(这里只考虑二分类问题,假设只有‘很是热’和‘通常热’)。其中特征向量包括两个分别是冰激凌数t1和喝水数t2,标签类别分别是很是热A和通常热B。web
如今咱们开始行动,随机采访4个游客(暂时不考虑样本数量问题),询问每一个游客吃多少冰淇淋和喝多少水(两个整型的特征向量,不考虑特征重要程度),并记录下他们口中的成都天气感觉(很是热A与通常热B)。而后经过采访数据训练一个KNN分类器,新的游客只须要说出特征向量自动判别成都天气冷热程度。建立模拟数据集代码以下:算法
'''KNN建立数据源,返回数据集和标签''' def create_dataset(): group = array(random.randint(0,10,size=(4,2))) # 数据集 labels = ['A','A','B','B'] # 标签 return group,labels
运行查看数据集的特征向量和分类标签:
'''1 KNN模拟数据分类算法''' dataset,labels = create_dataset() print('特征集:\n'+str(dataset)) print('标签集:\n'+str(labels))
运行结果:
特征集: [[8 4] [7 1] [1 4] [3 0]] 标签集: ['A', 'A', 'B', 'B']
分析解读:
本段代码没有实际意义,只是帮助读者理解特征向量和分类标签。能够这么理解,A表明很是热,B表明通常热,属性1表明吃冰淇淋数量,属性2表明喝水的数量。那么样本数据能够解读为:
游客 冰淇淋 喝水 冷热程度 判断描述 小王 8 4 A 小王吃了8个冰淇淋喝了4瓶水,成都天气很是热 小张 7 1 A 小张吃了7个冰淇淋喝了1瓶水,成都天气很是热 小李 1 4 B 小王吃了1个冰淇淋喝了4瓶水,成都天气通常热 小赵 3 0 B 小王吃了3个冰淇淋喝了0瓶水,成都天气通常热
思考:
计算机是不能直接处理天然语言,每每须要将天然语言转化成特征向量,再经过计算机处理。好比这里不是吃喝看天气状况了,而是垃圾邮件自动识别,咱们就须要对邮件转化成数值型特征向量再输入计算机进行处理。
规范文件数据集处理
以下是一个规范文件的数据集(已经通过数采集、数据格式化、数据预处理等),特征向量包括3个,样本属于一个多分类的状况。即咱们经过周飞行里程数、玩游戏占比、吃冰激凌数量判断一我的的优秀程度。假设1表明普通,2表明比较优秀,3表明很是优秀。(ps:一我的一周都在飞机上度过忙碌的工做,又不太玩游戏,关键还注意饮食,说明优秀是有道理的。)
周飞行里程数(km) 周玩游戏占比(%) 周消耗冰激凌(公升) 样本分类 40920 8.326976 0.953952 3 14488 7.153469 1.673904 2 26052 1.441871 0.805124 1 ... ... ... ... 75136 13.147394 0.428964 1 38344 1.669788 0.134296 1 72993 10.141740 1.032955 1
上面是处理好保存在txt文本的数据,计算机如何去识别并处理这些数据呢?这里咱们分别提取特征向量和标签向量。数据集处理代码以下:
'''对文件进行格式处理,便于分类器能够理解''' def file_matrix(filename): f = open(filename) arrayLines = f.readlines() returnMat = zeros((len(arrayLines),3)) # 数据集 classLabelVactor = [] # 标签集 index = 0 for line in arrayLines: listFromLine = line.strip().split(' ') # 分析数据,空格处理 returnMat[index,:] = listFromLine[0:3] classLabelVactor.append(int(listFromLine[-1])) index +=1 return returnMat,classLabelVactor
代码说明:
1 zeros(Y,X):填充矩阵,须要导入NumPy包。Y向量表明样本行数,X向量表明样本特征数即列数。 2 returnMat[index,:]:遍历样本特征向量
运行查看数据集的特征向量和分类标签:
''' KNN针对文件的分类算法''' filename = os.path.abspath(r'./datasource/datingTestSet2.txt') dataset,labels = file_matrix(filename) print('特征集:\n'+str(dataset)) print('标签集:\n'+str(labels))
运行结果:
特征集: [[4.0920000e+04 8.3269760e+00 9.5395200e-01] [1.4488000e+04 7.1534690e+00 1.6739040e+00] [2.6052000e+04 1.4418710e+00 8.0512400e-01] ... [2.6575000e+04 1.0650102e+01 8.6662700e-01] [4.8111000e+04 9.1345280e+00 7.2804500e-01] [4.3757000e+04 7.8826010e+00 1.3324460e+00]] 标签集: [3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 2, 1, 2, 3, 2, 3, 2, 3, 2, 1, 3, 1, 3, 1, 2, 1, 1, 2, 3, 3, 1, 2, 3, 3, 3, ... 3, 3, 1, 2, 3, 1, 3, 1, 2, 2, 1, 1, 1, 1, 1]
不规范数据集处理
这里咱们只是提供一个思路。好比作文本分类算法,如何将一篇篇新闻转化为规范的数值型数据集呢。假设Z政治新闻100篇,T体育新闻100篇,Y娱乐新闻100篇,K科技新闻100篇。咱们进行分类:
1 遍历全部文本转化统一的txt格式文件(2.2节会讲到) 2 对所有ZTYK文本进行分词和停用词处理。 3 统计所有样本词频尺寸(能够采用TF-IDF或者深度学习方法处理)。 4 每一个样本进行词频统计
最终模拟效果以下:
样本 词1 词2 词3 词4 ... 词n 标签 p1 200 0 100 50 ... 20 Z p2 100 0 80 40 ... 10 Z p3 0 100 5 5 ... 200 T p4 6 230 40 12 ... 670 T p5 0 2 110 57 ... 234 Y ... ... ... ... ... ... ... ... pn 123 45 0 580 ... 24 K
数据文件转化
天然语言处理、数据挖掘、机器学习技术应用越发普遍。针对大数据的预处理工做是一项庞杂、棘手的工做。首先数据采集和存储,尤为高质量数据采集每每不是那么简单。采集后的信息文件格式不一,诸如pdf,doc,docx,Excel,ppt等多种形式。然而最多见即是txt、pdf和word类型的文档。这里所谓格式转化主要对pdf和word文档进行文本格式转换成txt。格式一致化之后再进行后续预处理工做。具体详情请参照以前写的数据分析:基于Python的自定义文件格式转换系统一文。
文件格式化处理
这里能够采用多种方式,诸如上文提到的矩阵填充法,固然也能够采用现成的工具。好比百度的Echarts中表格数据转换工具。其支持纯数组的转换,数组+对象,地理坐标等方式,还支持json数据的转化,这对使用百度EChart可视化是很是友好的,也有助于可视化数据分析。文本数据格式效果以下图:
图2-1 文本数据表格转化
[ ['40920 8.326976 0.953952 3'], ['14488 7.153469 1.673904 2'], ['26052 1.441871 0.805124 1'], ['75136 13.147394 0.428964 1'], ['38344 1.669788 0.134296 1'], ['72993 10.141740 1.032955 1'], ... ['35948 6.830792 1.213192 3'], ['42666 13.276369 0.543880 3'], ['67497 8.631577 0.749278 1'], ['35483 12.273169 1.508053 3'], ['50242 3.723498 0.831917 1'], ['63275 8.385879 1.669485 1'], ['5569 4.875435 0.728658 2'], ['15669 0.000000 1.250185 2'], ['28488 10.528555 1.304844 3'], ['6487 3.540265 0.822483 2'], ['37708 2.991551 0.833920 1'] ]
数据归一化
机器学习、数据挖掘、天然语言处理等数据科学工做中,数据前期准备、数据预处理过程、特征提取等几个步骤比较花费时间。同时,数据预处理的效果也直接影响了后续模型可否有效的工做。然而,目前的不少研究主要集中在模型的构建、优化等方面,对数据预处理的理论研究甚少,不少数据预处理工做仍然是靠工程师的经验进行的。也不是全部数据都须要归一化,诸如
1. 数据类型一致且分布均匀。 2. 几率模型能够不作归一化,如决策树。
数据归一化优势
1. 归一化后加快了梯度降低求最优解的速度; 2. 归一化有可能提升精度;
归一化方法
1 sklearn线性归一化
# 线性函数将原始数据线性化的方法转换到[0, 1]的范围 min_max_scaler = preprocessing.MinMaxScaler() X_train_minmax = min_max_scaler.fit_transform(X_train) X_test_minmax = min_max_scaler.transform(X_test)
2 标准差标准化
# 通过处理的数据符合标准正态分布,即均值为0,标准差为1,其转化函数为: scaler = preprocessing.StandardScaler().fit(X_train) scaler.transform(X_test)
3 非线性归一化
常常用在数据分化比较大的场景,有些数值很大,有些很小。经过一些数学函数,将原始值进行映射。该方法包括 log、指数,正切等。须要根据数据分布的状况,决定非线性函数的曲线,好比log(V, 2)仍是log(V, 10)等。
线性归一化方法代码实现
'''数值归一化:特征值转化为0-1之间:newValue = (oldValue-min)/(max-min)''' def norm_dataset(dataset): minVals = dataset.min(0) # 参数0是取得列表中的最小值,而不是行中最小值 maxVals = dataset.max(0) ranges = maxVals - minVals normdataset = zeros(shape(dataset)) # 生成原矩阵同样大小的0矩阵 m = dataset.shape[0] # tile:复制一样大小的矩阵 molecular = dataset - tile(minVals,(m,1)) # 分子: (oldValue-min) Denominator = tile(ranges,(m,1)) # 分母:(max-min) normdataset = molecular/Denominator # 归一化结果。 return normdataset,ranges,minVals
数据归一化前:
归一化的数据结果: [[4.0920000e+04 8.3269760e+00 9.5395200e-01] [1.4488000e+04 7.1534690e+00 1.6739040e+00] [2.6052000e+04 1.4418710e+00 8.0512400e-01] ... [2.6575000e+04 1.0650102e+01 8.6662700e-01] [4.8111000e+04 9.1345280e+00 7.2804500e-01] [4.3757000e+04 7.8826010e+00 1.3324460e+00]]
展开第一条信息“40920 8.326976 0.953952 3”,其中里程40000多,而公升数才0.9.二者根本不在同一个数量级上面,也就是说,若是特征属性相同的状况下,公升数即便变更100倍对里程数的影响也微乎其微。而里程数轻微变化就直接影响公升数的结果。因此咱们将其放在同一尺度下进行处理,也就是本文采用的线性缩放方,数据归一化后结果以下:
归一化的数据结果: [[0.44832535 0.39805139 0.56233353] [0.15873259 0.34195467 0.98724416] [0.28542943 0.06892523 0.47449629] ... [0.29115949 0.50910294 0.51079493] [0.52711097 0.43665451 0.4290048 ] [0.47940793 0.3768091 0.78571804]]
分析:
通过上述归一化处理后,各个特征指标都是0-1这样一个范畴中进行比较。固然实际工做中不一样特征的权重不一样,这个能够经过增长权重方法处理便可,本文不在进行深刻讨论。
基于matplotlib的可视化分析
咱们对数据处理后,很不容易进行数据分析。毕竟密密麻麻的数字略显冰冷无趣。咱们能够将其可视化展现出来,进而查看数据稀疏程度,离散程度等等。咱们查看'玩游戏所耗时间百分比','每周消耗在冰淇淋的公升数'两个属性的散点图,实现代码以下:
''' 散列表分析数据: dataset:数据集 datingLabels:标签集 Title:列表,标题、横坐标标题、纵坐标标题。 ''' def analyze_data_plot(dataset,datingLabels,Title): fig = plt.figure() # 将画布划分为1行1列1块 ax = fig.add_subplot(111) ax.scatter(dataset[:,1],dataset[:,2],15.0*array(datingLabels),15.0*array(datingLabels)) # 设置散点图标题和横纵坐标标题 plt.title(Title[0],fontsize=25,fontname='宋体',fontproperties=myfont) plt.xlabel(Title[1],fontsize=15,fontname='宋体',fontproperties=myfont) plt.ylabel(Title[2],fontsize=15,fontname='宋体',fontproperties=myfont) # 设置刻度标记大小,axis='both'参数影响横纵坐标,labelsize刻度大小 plt.tick_params(axis='both',which='major',labelsize=10) # 设置每一个坐标轴取值范围 # plt.axis([-1,25,-1,2.0]) # 截图保存图片 # plt.savefig('datasets_plot.png',bbox_inches='tight') # 显示图形 plt.show()
这里注意一个问题,横纵坐标是乱码显示,解决这个问题,添加以下代码:
#加入中文显示 import matplotlib.font_manager as fm # 解决中文乱码,本案例使用宋体字 myfont=fm.FontProperties(fname=r"C:\\Windows\\Fonts\\simsun.ttc")
调用可视化数据分析方法以下:
''' 文件数据图形化分析数据 ''' dataset,labels = file_matrix(filename) noredataset = norm_dataset(dataset)[0] # 数据归一化 title = ['约会数据游戏和饮食散列点','玩游戏所耗时间百分比','每周消耗在冰淇淋的公升数'] visualplot.analyze_data_plot(noredataset,labels,title)
游戏占比与冰淇淋公升数关系散点图可视化:
图2-2 游戏占比与冰淇淋公升数关系散点图
折线图代码实现以下:
'''折线图''' def line_chart(xvalues,yvalues): # 绘制折线图,c颜色设置,alpha透明度 plt.plot(xvalues,yvalues,linewidth=0.5,alpha=0.5,c='red') # num_squares数据值,linewidth设置线条粗细 # 设置折线图标题和横纵坐标标题 plt.title("Python绘制折线图",fontsize=30,fontname='宋体',fontproperties=myfont) plt.xlabel('横坐标',fontsize=20,fontname='宋体',fontproperties=myfont) plt.ylabel('纵坐标',fontsize=20,fontname='宋体',fontproperties=myfont) # 设置刻度标记大小,axis='both'参数影响横纵坐标,labelsize刻度大小 plt.tick_params(axis='both',labelsize=14) # 显示图形 plt.show()
游戏占比与冰淇淋公升数关系折线图可视化:(此处折线图明显不合适,只是突出另外一种分析方式。)
图2-3 游戏占比与冰淇淋公升数关系折线图
扩展:
更多matplotlib可视化实现效果图参考文章 70个注意的Python小Notes:完整的matplotlib可视化
基于Echart的可视化分析
咱们上面采用的matplotlib可视化效果,采用该方式主要是结合python数据分析绑定比较方便。有些时候咱们为了取得更加漂亮的可视化效果,能够选择百度echart进行分析,百度Echart使用简单且文档规范容易上手。咱们对原数据进行分析并转化为json代码:
'''array数据转化json''' def norm_Json(dataset): noredataset = norm_dataset(dataset)[0] # 数据归一化 number1 = np.around(noredataset[:,1], decimals=4) # 获取数据集第二列 number2 = np.around(noredataset[:,2], decimals=4) # 获取数据集第三列 returnMat=zeros((dataset.shape[0],2)) # 二维矩阵 returnMat[:,0] = number1 returnMat[:,1] = number2 file_path = os.path.abspath(r"./datasource/test.json") json.dump(returnMat.tolist(), codecs.open(file_path, 'w', encoding='utf-8'), separators=(',', ':'), sort_keys=True, indent=4)
生成json数据保存在指定文件中,打开文件查看数据以下:
[ [ 0.3981, 0.5623 ], [ 0.342, 0.9872 ], [ 0.0689, 0.4745 ], [ 0.6285, 0.2525 ] ... [ 0.4367, 0.429 ], [ 0.3768, 0.7857 ] ]
从百度Echart实例中选择一种散点图并绑定json文件,其html代码以下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>图案例</title> <script src="https://cdn.bootcss.com/jquery/2.2.0/jquery.min.js"></script> <script type="text/javascript" src="./js/echarts.js"></script> </head> <body> <div id="chartmain" style="width:800px; height: 400px; margin:auto; "> </div> <script type="text/javascript"> //初始化echarts实例 var myChart = echarts.init(document.getElementById('chartmain')); $.getJSON('game-food.json', function (data) { var option = { title: { text: '玩游戏时间占比和饮食数据描述', left: 'center', top: 0 }, visualMap: { min: 15202, max: 159980, dimension: 1, orient: 'vertical', right: 10, top: 'center', text: ['优秀', '通常'], calculable: true, inRange: { color: ['#f2c31a', '#24b7f2'] } }, tooltip: { trigger: 'item', axisPointer: { type: 'cross' } }, xAxis: [{ type: 'value' }], yAxis: [{ type: 'value' }], series: [{ name: 'price-area', type: 'scatter', symbolSize: 5, data: data }] }; myChart.setOption(option); }); </script> </body> </html>
json文件读取须要在web运行环境中,单纯的运行效果以下图所示:
图2-4 游戏占比与冰淇淋公升数Echarts关系散点图
数据转化工具
本文采用本身构建的方式进行json文件生成,此外咱们也能够采用现有的数据转化工具进行处理。好比百度的表格数据转化工具(2.2节已经介绍了)。
另外一个即是在线json验证格式工具:http://www.bejson.com/
经过数据分析,咱们查看数据样本是否偏态分别,数据规模状况等等。针对性进行数据预处理后,编写具体算法模型。本文主要是KNN分类器,其代码以下:
''' 构造KNN分类器 vecX:输入向量,待测数据 filename: 特征集文件路径 isnorm:是否进行归一化处理 k:k值的选择,默认选择3 ''' def knn_classifier(vecX,dataset,labels,isnorm='Y',k=3): # 距离计算(方法1) if isnorm == 'Y': normMat,ranges,minVals = norm_dataset(dataset) # 对数据进行归一化处理 normvecX = norm_dataset(vecX) else: normMat = dataset normvecX = vecX m = normMat.shape[0] # tile方法是在列向量vecX,datasetSize次,行向量vecX1次叠加 diffMat = tile(normvecX,(m,1)) - normMat sqDiffMat = diffMat ** 2 sqDistances = sqDiffMat.sum(axis=1) # axis=0 是列相加,axis=1是行相加 distances = sqDistances**0.5 # print('vecX向量到数据集各点距离:\n'+str(distances)) sortedDistIndexs = distances.argsort(axis=0) # 距离排序,升序 # print(sortedDistIndicies) classCount = {} # 统计前k个类别出现频率 for i in range(k): votelabel = labels[sortedDistIndexs[i]] classCount[votelabel] = classCount.get(votelabel,0) + 1 #统计键值 # 类别频率出现最高的点,itemgetter(0)按照key排序,itemgetter(1)按照value排序 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) print(str(vecX)+'KNN的投票决策结果:\n'+str(sortedClassCount[0][0])) return sortedClassCount[0][0]
基本知识
混淆矩阵:正元组和负元组的合计
图3-1 混淆矩阵表
评估度量:(其中P:正样本数 N:负样本数 TP:真正例 TN:真负例 FP:假正例 FN:假负例)
图3-2 评估信息度量表
注意:学习器的准确率最好在检验集上估计,检验集的由训练集模型时未使用的含有标记的元组组成数据。
各参数描述以下:
TP(真正例/真阳性):是指被学习器正确学习的正元组,令TP为真正例的个数。
TN(真负例/真阴性):是指被学习器正确学习的负元组,令TN为真负例的个数。
FP(假正例/假阳性):是被错误的标记为正元组的负元组。令FP为假正例的个数。
FN(假负例/假阴性):是被错误的标记为负元组的正元组。令FN为假负例的个数。
准确率:正确识别的元组所占的比例。
评价指标优势
通常采用精确率和召回率做为度量的方法具备如下几个优势:
(1) 准确率数值对于小数据不是特别敏感,而精确率和召回率对于这样数据比较敏感。 (2) 在相同实验环境下,F度量这种倾向和咱们直观感受是一致的,咱们对目标事件很敏感,甚至返回一些垃圾数据也在所不惜。 (3) 经过精确率和找回来衡量目标事件和垃圾事件的差别。
模型评估拓展
本文只是对错误率进行评估,其也是knn分类器核心指标,实现代码以下:
'''测试评估算法模型''' def test_knn_perfor(filename): hoRatio = 0.1 dataset,label = file_matrix(filename) # 获取训练数据和标签 normMat,ranges,minVals = norm_dataset(dataset) # 对数据进行归一化处理 m = normMat.shape[0] numTestVecs = int(m*hoRatio) # 10%的测试数据条数 errorCount = 0.0 # 统计错误分类数 for i in range(numTestVecs): classifierResult = knn_classifier(normMat[i,:],normMat[numTestVecs:m,:],label[numTestVecs:m],3) # 此处分类器能够替换不一样分类模型 print('分类结果:'+str(classifierResult)+'\t\t准确结果:'+str(label[i])) if classifierResult != label[i]: errorCount += 1.0 Global.all_FileNum += 1 print('总的错误率为:'+str(errorCount/float(numTestVecs))+"\n总测试数据量: "+str(Global.all_FileNum))
运行效果以下:
[0.44832535 0.39805139 0.56233353]KNN的投票决策结果: 分类结果:3 准确结果:3 [0.15873259 0.34195467 0.98724416]KNN的投票决策结果: 分类结果:2 准确结果:2 ... 分类结果:3 准确结果:3 [0.19385799 0.30474213 0.01919426]KNN的投票决策结果: 分类结果:2 准确结果:2 [0.24463971 0.10813023 0.60259472]KNN的投票决策结果: 分类结果:1 准确结果:1 [0.51022756 0.27138082 0.41804137]KNN的投票决策结果: 分类结果:3 准确结果:1 总的错误率为:0.05 总测试数据量: 100 耗时:0.0300 s
评估结果分析:
本文采用封闭评估的方法,前100条数据做为测试集,后900条数据做为训练集。如上结果最后一条信息代表knn分类器的结果是3,而标准结果是1.knn分类存在错误。将全部错误占比分析出来即错误率。本文错误率5%,即准确率95%.
读者能够选取200:800、300:700等等数据进行测试查看错误率。
knn分类器应用
通过如上的改进最终造成实际应用的算法模型API开发给外部程序使用,调用knn算法代码以下:
'''调用可用算法''' def show_classifyPerson(filename): resultlist = ['不喜欢','还能够','特别喜欢'] ffMiles = float(input('每一年飞行的历程多少千米?\n')) percentTats = float(input('玩游戏时间占百分比多少?\n')) # [751,13,0.4][40920 ,8.326976,0.953952] iceCream = float(input('每周消费冰淇淋多少公升?\n')) dataset,labels = file_matrix(filename) # 数据格式化处理 inArr = array([ffMiles,percentTats,iceCream]) classifierResult = knn_classifier(inArr,dataset,labels,3) # 数据归一化并进行分类 print('预测的约会结果是:'+resultlist[classifierResult-1])
运行结果以下:
每一年飞行的历程多少千米? 10000 玩游戏时间占百分比多少? 10 每周消费冰淇淋多少公升? 0.5 KNN的投票决策结果: 2 预测的约会结果是:还能够
展望
咱们还能够采用knn分类器进行实际应用,好比新闻分类系统。大体思路以下:
1 采集数据:选用复旦大学的文本分类新闻语料 2 准备数据:数据格式化、分词、停用词处理等 3 分析数据:看看数据特色,有没有缺失值,数据连续性仍是离散型,进而选择不一样模型。诸如:可视化数据分析 4 数据转化:采用IF-IDF或者神经网络的方法对词频进行处理,最终转化为机器能够处理的数值型矩阵。 5 构建模型:KNN新闻分类器模型构建。 6 测试算法:评价指标,如计算错误率,准确率,召回率,F度量值等。 7 应用算法:针对完善的模型进行封装重构,而后进行实际的新闻分类应用。
机器学习和天然语言QQ群:436303759。 微信公众号:datathinks
源码请进QQ群文件下载:
本文版权归做者全部,旨在技术交流使用。未经做者赞成禁止转载,转载后需在文章页面明显位置给出原文链接,不然相关责任自行承担。转载必须注明出处【伏草唯存】:一步步教你轻松学KNN模型算法