python数据挖掘笔记】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取

#2018-04-06 07:57:00 April Friday the 14 week, the 096 day SZ SSMR
python数据挖掘笔记】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取 
  1.KNN算法基础原理知识
    2.最近邻分类算法分析预测坐标类型
    3.Pandas读取TXT数据集
    4.KNN分析平衡秤数据集
    5.算法优化
一. KNN算法基础原理知识

K最近邻(K-Nearest Neighbor,简称KNN)分类算法是数据挖掘分类技术中最简单常用的方法之一。所谓K最近邻,就是寻找K个最近的邻居的意思,
每个样本都可以用它最接近的K个邻居来代表。本小节主要讲解KNN分类算法的基础知识及分析实例。
KNN分类算法是最近邻算法,字面意思就是寻找最近邻居.引用了鸭子分类的例子解释。

所以,KNN分类算法的核心思想是从训练样本中寻找所有训练样本X中与测试样本距离(欧氏距离)最近的前K个样本(作为相似度),
再选择与待分类样本距离最小的K个样本作为X的K个最邻近,并检测这K个样本大部分属于哪一类样本,则认为这个测试样本类别属于这一类样本。
KNN分类算法的具体步骤如下:
  1.计算测试样本点到所有样本点的欧式距离dist,采用勾股定理计算。
  2.用户自定义设置参数K,并选择离带测点最近的K个点。
  3.从这K个点中,统计各个类型或类标的个数。
  4.选择出现频率最大的类标号作为未知样本的类标号,反馈最终预测结果。
KNN在Sklearn机器学习包中,实现的类是neighbors.KNeighborsClassifier,简称KNN算法。构造方法为:
KNeighborsClassifier(algorithm='ball_tree', 
    leaf_size=30, 
    metric='minkowski',
    metric_params=None, 
    n_jobs=1, 
    n_neighbors=3, 
    p=2, 
    weights='uniform')
KNeighborsClassifier可以设置3种算法:brute、kd_tree、ball_tree,设置K值参数为n_neighbors=3。
调用方法如下:
    from sklearn.neighbors import KNeighborsClassifier  
    knn = KNeighborsClassifier(n_neighbors=3, algorithm="ball_tree")

它也包括两个方法:
    训练:nbrs.fit(data, target)
    预测:pre = clf.predict(data)
下面这段代码是简单调用KNN分类算法进行预测的例子,代码如下。
# -*- coding: utf-8 -*-
import numpy as np  
from sklearn.neighbors import KNeighborsClassifier  

X = np.array([[-1,-1],[-2,-2],[1,2], [1,1],[-3,-4],[3,2]])
Y = [0,0,1,1,0,1]
x = [[4,5],[-4,-3],[2,6]]
knn = KNeighborsClassifier(n_neighbors=3, algorithm="ball_tree")
knn.fit(X,Y)
pre = knn.predict(x)
print(pre)

定义了一个二维数组用于存储6个点,其中x和y坐标为负数的类标定义为0,x和y坐标为正数的类标定义为1。调用knn.fit(X,Y)函数训练模型后,再调用predict()函数预测[4,5]、[-4,-3]、[2,6]三个点的坐标,输出结果分别为:[1, 0, 1],其中x和y坐标为正数的划分为一类,负数的一类。

解释:它相当于分别计算[4,5]点到前面X变量六个点的距离,采用欧式距离,然后选择前3个(K=3)最近距离的点,看这三个点中属于0和1类的个数,则该[4,5]点预测的类型则属于较多的那个类别,即为1(正数)。

同时也可以计算K个最近点的下标和距离,代码和结果如下,返回距离k个最近的点和距离指数,indices可以理解为表示点的下标,distances为距离。
distances, indices = knn.kneighbors(X)  
print(indices  )
print (distances) 

三. Pandas读取TXT数据集
wine.txt该数据集者来自于UCI网络公开数据集,成为Balance Scale Dataset平衡表数据集。
下载地址为:http://archive.ics.uci.edu/ml/datasets/Balance+Scale。
import os 
import numpy as np
data = np.loadtxt("wine.txt",dtype=str,delimiter=",")
print (data)
由于数据中存在“B”、“R”、“L”三类字母,故需要转换为字符类型(string)。同时该数据集存在一个特点,第一列为类标,
后面四列为对应的数据集,则使用split()划分第一列和剩余4列数据,代码如下:
# -*- coding: utf-8 -*-
import os 
import numpy as np
data = np.loadtxt("wine.txt",dtype=str,delimiter=",")
#print (data)


yy, x = np.split(data, (1,), axis=1)
print ("yy.shape, x.shape are:\n",yy.shape, x.shape)
print ("x[:5] is:\n",x[:5])
print ("yy[:5] is:",yy[:5])  

同时这里的类标为“B”、“R”、“L”,我也将其转换为数字,其中“L”表示0,“B”表示1,“R”表示2。

#从字符型转换为Int整型
X = x.astype(int)
#print X
#字母转换为数字
y = []
i = 0
print(len(yy))
while i<len(yy):
    if yy[i]=="L":
        y.append(0)
    elif yy[i]=="B":
        y.append(1)
    elif yy[i]=="R":
        y.append(2)
    i = i + 1
print (y[:5])
四. KNN分析平衡秤数据集
接下来开始进行KNN算法分类分析,其中KNN核心算法主要步骤包括五步:
  1.为了判断未知实例的类别,以所有已知类别的实例为参照
  2.选择参数K
  3.计算未知实例与所有已知实例的距离
  4.选择最近K个已知实例
  5.根据少数服从多数的投票法则,让未知实例归类为K个最近邻样本中最多数的类标
调用SKlearn机器学习扩展包的核心代码如下所示:

from sklearn import neighbors
knn = neighbors.KNeighborsClassifier()
print (knn)
输出算法原型如下:
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=5, p=2,
           weights='uniform')
[Finished in 6.2s]

接下来调用fit()函数对数据集进行训练,再调用predict函数对数据集进行预测,完整代码如下所示:

# -*- coding: utf-8 -*-
import os 
import numpy as np
data = np.loadtxt("wine.txt",dtype=str,delimiter=",")
#print (data)


yy, x = np.split(data, (1,), axis=1)
'''
print ("yy.shape, x.shape are:\n",yy.shape, x.shape)
print ("x[:5] is:\n",x[:5])
print ("yy[:5] is:",yy[:5])  
'''
#从字符型转换为Int整型
X = x.astype(int)
#print X
#字母转换为数字
y = []
i = 0
#print(len(yy))
while i<len(yy):
    if yy[i]=="L":
        y.append(0)
    elif yy[i]=="B":
        y.append(1)
    elif yy[i]=="R":
        y.append(2)
    i = i + 1
#print (y[:5])


#KNN分析
from sklearn import neighbors
knn = neighbors.KNeighborsClassifier()
knn.fit(X,y)
pre = knn.predict(X)

#可视化分析
import matplotlib.pyplot as plt 
L1 = [x[0] for x in X]    
L2 = [x[2] for x in X]  
plt.scatter(L1, L2, c=pre, marker='s',s=20)    
plt.show() 

#预测结果与真实结果比对  
print(sum(pre == y)  )
#输出准确率 召回率 F值  
from sklearn import metrics  
print(metrics.classification_report(y,pre))  
print('break')
print(metrics.confusion_matrix(y,pre)) 


#其中625组数据中,共预测正确540组,Precision值为83%,召回率Recall为86%,F1特征为84%,
五. 代码优化
最后提供一段优化后的代码,提取其中的两列绘制相关的背景图。


import os 
import numpy as np

#第一步 导入数据集
data = np.loadtxt("wine.txt",dtype=str,delimiter=",")
#print data
#print type(data)
yy, x = np.split(data, (1,), axis=1)

#print yy.shape, x.shape
#从字符型转换为Int整型
X = x.astype(int)
#获取x两列数据,方便绘图 对应x、y轴
X = X[:, 1:3]  
#print X
#字母转换为数字
y = []
i = 0
#print len(yy)
while i<len(yy):
    if yy[i]=="L":
        y.append(0)
    elif yy[i]=="B":
        y.append(1)
    elif yy[i]=="R":
        y.append(2)
    i = i + 1
#print y[:5]

#第二步 KNN分析
from sklearn import neighbors
knn = neighbors.KNeighborsClassifier()
#print knn
knn.fit(X,y)
pre = knn.predict(X)
#print pre

#第三步 数据评估  
from sklearn import metrics  
print (sum(pre == y) )  #预测结果与真实结果比对
print(metrics.classification_report(y,pre))   #输出准确率 召回率 F值  
print(metrics.confusion_matrix(y,pre)) 

#第四步 创建网格 
x1_min, x1_max = X[:,0].min()-0.1, X[:,0].max()+0.1  #第一列
x2_min, x2_max = X[:,1].min()-0.1, X[:,1].max()+0.1  #第二列
xx, yy = np.meshgrid(np.arange(x1_min, x1_max, 0.1),  
                     np.arange(x2_min, x2_max, 0.1))  #生成网格型数据
print (xx.shape, yy.shape )#(42L, 42L) (42L, 42L)
print (xx.ravel().shape, yy.ravel().shape)  #(1764L,) (1764L,)
print (np.c_[xx.ravel(), yy.ravel()].shape) #合并 (1764L, 2L)
#ravel()拉直函数
z = knn.predict(np.c_[xx.ravel(), yy.ravel()])    
#print z

#第五步 绘图可视化
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])   #颜色Map
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])
plt.figure()
z = z.reshape(xx.shape)                
plt.pcolormesh(xx, yy, z, cmap=cmap_light)
plt.scatter(X[:,0], X[:,1], c=y, cmap=cmap_bold, s=50)#X[:,0]表示X的所有行,0列。
plt.show()















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值