python之k-近邻算法(sklearn版)

Python014

python之k-近邻算法(sklearn版),第1张

上文借用了numpy和pandas等模块自编了k-近邻算法 python之k-近邻算法(非sklearn版) ,这次借用sklearn轮子来实现一下

数据还是用上篇文章的数据来 https://pan.baidu.com/s/1zIGz6GtEU20UeT6hemP4MQ

上篇文章我们是利用KNN.py中的自编函数panduan在读取数据的过程中来实现的,而这种转变在sklearn中已经有轮子调用了

这里再补充一点:对于类别数据(对于特征值也是适用的),可以分为 标称特征(nominal feature) 有序特征(ordinal feature) .

对于我们这里的数据largeDoses,smallDoses,didntLike应该是对应着有序特征

如果在这里'喜欢的类别'本身不带有有序的含义的话,即largeDoses,smallDoses,didntLike三个类别没有序别之分,可以借用sklearn里的功能

可以看到借用sklearn是比较方便的

但是。。。。。但是。。。。以上的0,1,2在算法看来依然是有顺序的,所以我们可以利用 独热编码(one-hot encoding) ,即创建一个新的虚拟特征(dummy feature)

也可以利用pandas里的功能

————————————————————————————————————

特征缩放(feature scaling)对于除了决策树和随机森林两个算法没用以外,对其他算法和优化算法来讲都是必不可少的

即上篇文章所涉及到的

对于线性模型来讲,标准化更加好,一是符合线性模型对权重的处理,二是保留了异常值的信息

———————————————————————————————————

上篇文章对于此类问题的处理见 datingClassTest 函数

K-近邻算法被称之为 惰性算法 ,和其他机器学习算法不一样,因为他仅仅是对训练数据集有记忆功能,而不是从训练集中通过学习得到一个判别函数,即不需要训练,看过上篇文章的小伙伴应该会有体会。 缺点是计算复杂度会随着样本数量的增长而呈线性增长,除非数据集中特征数量有限

import numpy as np

def read_data(filename):

'''读取文本数据,格式:特征1特征2 …… 类别'''

f=open(filename,'rt')

row_list=f.readlines() #以每行作为列表

f.close()

data_array=[]

labels_vector=[]

while True:

if not row_list:

break

row=row_list.pop(0).strip().split('\t') #去除换行号,分割制表符

temp_data_row=[float(a) for a in row[:-1]] #将字符型转换为浮点型

data_array.append(temp_data_row) #取特征值

labels_vector.append(row[-1]) #取最后一个作为类别标签

return np.array(data_array),np.array(labels_vector)

def classify(test_data,dataset,labels,k):

'''分类'''

diff_dis_array=test_data-dataset#使用numpy的broadcasting

dis_array=(np.add.reduce(diff_dis_array**2,axis=-1))**0.5 #求距离

dis_array_index=np.argsort(dis_array) #升序距离的索引

class_count={}

for i in range(k):

temp_label=labels[dis_array_index[i]]

class_count[temp_label]=class_count.get(temp_label,0)+1 #获取类别及其次数的字典

sorted_class_count=sorted(class_count.items(), key=lambda item:item[1],reverse=True)#字典的值按降序排列

return sorted_class_count[0][0]#返回元组列表的[0][0]

def normalize(dataset):

'''数据归一化'''

return (dataset-dataset.min(0))/(dataset.max(0)-dataset.min(0))

k=3 #近邻数

test_data=[0,0] #待分类数据

data,labels=read_data('testdata.txt')

print('数据集:\n',data)

print('标签集:\n',labels)

result=classify(test_data,normalize(data),labels,k)

print('分类结果:',result)