这篇博客是在KNN实现之后,对实现过程中用到的知识的一些总结,这些知识非常基础且重要,但是竟然同时出现在KNN的实现过程中,比较有意思。

排序

argsort()函数

在ML模型的实现中,经常遇到需要根据某值排序,获取该值对应索引,最后根据该索引取另一个数据。

x = np.array([2,1,3])

np.argsort(x)#默认升序排列

得到: array([1,0,2]),降序的实现,

np.argsort(-x)

利用索引排序数组,

x[np.argsort(-x)]

sort()函数

sort()是list的函数,list.sort()会改变list中值的顺序,此处大坑!

a = [2,1,3]
a.sort()

sorted()函数

如果不想改变list中值的顺序,可以使用sorted,

a = [2,1,3]
sorted(a)

sorted是一个很丰富的函数,其声明如下:

sorted(iterable, cmp, key, reverse)

在KNN的实现中,最后一步根据K个样本的label值统计出现次数最多的label,代码如下:

print(sorted(label_dict, key=lambda x:label_dict[x])[-1])

其中label_dict是字典。看另外一个例子:

data = [('sara', 80), ('david', 90), ('mary', 90), ('lily', 95)]

sorted(data, key = lambda data:data[0])#按照元组的第一个元素排序

sorted(data, key = lambda data:data[1])#按照元组的第二个元素排序

此外也可以结合cmp和reverse进行排序,如下:

sorted(data,reverse=True)

其中关于cmp的用法也相对灵活,此处不谈。

TopN问题

基于heapq的实现

对列表操作:

import heapq

data = [2,3,8,2,1]
N = 3
lData = heapq.nlargest(N, data)
sData = heapq.nsmallest(N, data)

对字典操作:

import heapq
dictData = {'a':1, 'b':2, 'c':3}
N = 2
lData = heapq.nlargest(N, dictData.values())#得到k, v需要两个for循环实现
sData = heapq.nsmallest(N, dictData.keys())#得到k, v只需要一个for循环实现

元素统计

这个需求同样出现在KNN中,测试样本的类别由K个最近邻决定,这就需要对K个近邻的标签进行统计。

第一种:

data = [1,2,2,3,3,3,3,5,3]
_data = set(data)
for item in _data:
    print(data.count(item))

第二种:

from collections import Counter
data = [1,2,2,3,3,3,3,5,3]
_dict = Counter(data)

总结:这篇博客是基于KNN的实现过程中的总结,涉及排序和查找,TopN问题,词频统计等,博客列举问题在面试中也是屡见不鲜,将问题规模推广到大数据场景下,上述问题需要更具深度的思考。

补充一段词频统计的代码(在决策树的实现中,当确定叶子节点的类别时需要由叶子节点样本投票得出):

import operator
def majorityCnt(classList):
    classCount = {}
    for vote in classList:
        if vote not in classCount.keys():
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

注意:在Python3.7版本中,使用classCount.items();但是在Python2.7版本中,则需要classCount.iteritems()。