1. 导读
本文将带领大家实现写两种选择器。所谓选择器,指的是,给定一个元素容器,从该容器种依据一定的策,选取某类或某个特定的元素返回,以作为选择的结果
【note】这几个挑选器可供实现"决策树"算法中,当使用预剪枝策略停止分裂时,挑选出一个提前结束决策树叶节点的lable。
(1)一种称之为“众数投票器”,顾名思义是按照以容器(Collection)中不同元素出现的次数作为依据,选出现次数最多的那一个元素返回。
(2)第二种为“随机挑选器”
- 首先是简单随机挑选器,就是不论各个元素在容器中的出现频率如何,随机返回其中的一个元素。应该指出这是一种“按元素类权重的随机挑选器”。当容器不进行去重时,以各个元素所占的比重为它们在一次随机抽取中被抽中的概率,随机地挑选一个值出来。但实际上这种就是第二种。因为在第二种挑选器中,由于是随机选取一个元素,占比大的元素拥有更大的被选中的可能性,并且在没有附加条件的前提下,即只要元素是随机分布的一类元素被选中的概率和它在容器中出现次数成正比,因此对于非去重随机选取的本质就是按照比重选取。
- 进一步,然后是完全随机挑选器。与上面的简单随机挑选器不同之处在于完全随机挑选器所有元素类等可能地被挑选出,而上面直接简单地对所有元素进行随机挑选是不用考虑到元素出现权重不同所带来地干扰地。之所以我称之为完全随机,因为这样挑选对于一类而言,它随机得更彻底。
2.众数挑选器
2.1 collections.Counter
简介
为了方便,我们使用Python内建模块collections
中的计数器对象Counter
。
它的most_common()方法可以计算出各个元素的出现次数,并按照出现次数的大小顺序返回。
比如由列表(List)转为Counter
对象:
from collections import Counter label = ['A',6,'B','A',6,'A'] Counter(label)
Out[i]:
Counter({‘A’: 3, 6: 2, ‘B’: 1})
获取Counter对象中的按顺序排列列表:
Counter(label).most_common()
Out[i]:
[(‘A’, 3), (6, 2), (‘B’, 1)]
可以看到,这个列表是由若干个元组构成的,每个元组的前一个元素即为原列表中的元素,元组的第二个元素为对应在原列表中的出现次数。并且所有元组在most_common()方法返回的列表中是按照出现次数由多到少排列的。
Counter对象在本质上它也是一个容器。我们也可以使用出栈方法popitem()
弹出其栈顶元素,也就是出现次数最少的,比如:
Counter(label).popitem(label)
Out[i]:
(‘B’, 1)
不过popitem()
方法与pop
方法是不同的,pop()
方法用于获取指定元素的出现次数:
Counter(label).pop(6)
Out[i]:
2
再了解了Counter
计数器这个知识点之后,我们就来看统计容器中的总数吧。
2.2 众数挑选器的Python代码
from collections import Counter def majorityLabel(labels): """ 众数投票器 求取某个节点出现次数最多的标签 Parameters ---------- labels: an Array-like object Return ------ result: labels中出现次数最多的那个成员 """ return Counter(list(labels)).most_common()[0][0]
3.随机挑选器
3.1 简单随机挑选器(元素随机挑选器)
——(所有元素等可能地被挑选出)
在数理统计中,所谓随机是没有任何理由或信息认为任意一个元素的出现概率比其它元素大。实际上不论一个元素里面的值是如何排列的,有序也好无需也罢,只要产生一个随机数任意选出一个元素即可让所有元素等可能地被选出来。如此挑选,一类元素被选中的概率只取决于该类元素在容器中的数量。
import random # random.seed(RANDOM_SEED) # 如果向固定随机种子让“随机”不再随机,则取消本条注释并给定RANDOM_SEED的值 def maxProbability_elem(labels): """ 按比重随机投票器 从以标签容器labels中随机返回一个元素 Parameters ---------- labels: an Array-like object Return ------ result: labels 中的某个成员 """ return labels[int(random.random()* len(labels))]
3.2 完全随机挑选器(类随机挑选器)
——(所有元素类等可能地被挑选出)
相比于2.1,为了使得元素种所有类别被挑选出来地概率相同,需要做的不过是使得所有元素都拥有相同地权重。做到这一点嘴贱但地方式就是对元素进行去重,使得所有元素地权重值都为1。而去重地最简单方式就是转为"集合(set)"。
实现入下:
import random # random.seed(RANDOM_SEED) # 如果向固定随机种子让“随机”不再随机,则取消本条注释并给定RANDOM_SEED的值 def maxProbability_class(label): """ 按比重随机投票器 对标签容器labels的元素进行去重,再随机返回一个其中的一个元素 Parameters ---------- labels: an Array-like object Return ------ result: labels 中的某个成员 """ return list(set(listlabel))[int(random.random()* len(listlabel))]
4. 小结
from collections import Counter class Selector(object): """选择器""" def __init__(self): """ Parameters ---------- labels: an Array-like object """ self.labels = labels def majorityLabel(self): """ 选择出现次数最多的元素 Return ------ result: labels中出现次数最多的那个成员 """ return Counter(list(self.labels)).most_common()[0][0] def maxProbability_elem(self): """ 有元素权重随机选择(元素随机) Return ------ result: labels 中的某个成员 """ return self.labels[int(random.random()* len(self.labels))] def maxProbability_class(self): """ 无元素权重随机选择(元素类随机) Return ------ result: labels 中的某个成员 """ return list(set(self.labels))[int(random.random()* len(self.labels))]
如果喜欢,记得一赞三连噢!