(self, datas , labels , attrs, dense_data)
return sorted(gains, key=lambda x: x[1], reverse=True)
通过算法获得最好分类的属性 ；
        思想：
            1.  信息增益 
            2.  信息增益率
        参数：
            datas 训练的数据
            attrs 属性列表
            dense_data 是否为密集型数据 ， == True [[v1 , v2 ,v3 ,v4 .... vn , label]]
                                         == False [({f1 : v1 , f2:v2...fn:vn} , label1)]
通过算法获得最好分类的属性 ；
        思想：
            1.  信息增益 
            2.  信息增益率
        参数：
            datas 训练的数据
            attrs 属性列表
            dense_data 是否为密集型数据 ， == True [[v1 , v2 ,v3 ,v4 .... vn , label]]
                                         == False [({f1 : v1 , f2:v2...fn:vn} , label1)]
通过算法获得最好分类的属性 ； 思想： 1 . 信息增益 2 . 信息增益率 参数： datas 训练的数据 attrs 属性列表 dense_data 是否为密集型数据 ， == True [[ v1 v2 v3 v4 .... vn label ]] == False [ ( { f1 : v1 f2 : v2 ... fn : vn } label1 ) ]
def get_best_feature(self, datas , labels , attrs, dense_data):
        '''
        通过算法获得最好分类的属性 ；
        思想：
            1.  信息增益 
            2.  信息增益率
        参数：
            datas 训练的数据
            attrs 属性列表
            dense_data 是否为密集型数据 ， == True [[v1 , v2 ,v3 ,v4 .... vn , label]]
                                         == False [({f1 : v1 , f2:v2...fn:vn} , label1)]
        '''
        label_dict = Counter(labels)
        data_num = float(len(datas))  # 计算此次计算信息增益的数据长度 ， 样本大小
        label_entropy = DecisionTree.entropy(
            [label_count / data_num for label_count in label_dict.values()])  # 计算整个系统的熵
        # 计算每个属性的熵
        # 声明一个属性列表 ， {属性 ： {属性值 ： 出现的次数}}
        attr_value_count = {attr: defaultdict(float) for attr in attrs}
        # 声明属性->属性值->类别->数量
        attr_value_class_count = {attr: defaultdict(lambda : defaultdict(float)) for attr in attrs}
        iter_index = range(len(attrs))
        for i in range(len(datas)):
            for j in iter_index:
                    # 计算每个属性下不同值数量 ， 此处必要转换为离散变量
                    data = datas[i]
                    attr_value_count[attrs[j]][data[j]] += 1
                    attr_value_class_count[attrs[j]][data[j]][labels[i]] += 1.0
        # 信息增益计算公式分析
        #     H(D) - H(D|A)
        #     系统熵 - 每个属性下 ， 存在这个类别的信息熵
        #
        # gains = [(属性名称 ， 信息增益 ， (属性值))......(属性名称n , 信息增益n ， (f1 ...fn))]
        # 以上运算是这样的；
        #   当查看每个属性 ， 在各个值中是否很大概率偏向一方 ， 这样造成整体信息增益最大 ， 因为整体的信息增益肯定为正的 ，
        #   减去一个越小的数 ， 数值反而越大 ， 就是说明属性是比较稳定的（比较有分类信息的）
        gains = [(attr,
                  label_entropy - 
                  sum(
                      [
                          attr_value_count[attr][value] / data_num * 
                          DecisionTree.entropy(
                              [
                                  # 计算每个属性在特定属性值时 ， 发生的概率
                                  # p(DA1)/A
                                  attr_value_class_count[attr][value][
                                      label] / attr_value_count[attr][value]
                                  # 循环每个属性值在特定label产生
                                  for label in attr_value_class_count[attr][value].keys()
                              ]
                          )
                          for value in attr_value_count[attr].values() if attr_value_class_count[attr].has_key(value)]
                  ),
                  attr_value_count[attr].keys())
                 for attr in attr_value_count.keys()]
        # return attr_name , gains , attr value 
        return sorted(gains, key=lambda x: x[1], reverse=True)
def get_best_feature ( self , datas , labels , attrs , dense_data ) : label_dict = Counter ( labels ) data_num = float ( len ( datas ) ) # 计算此次计算信息增益的数据长度 ， 样本大小 label_entropy = DecisionTree . entropy ( [ label_count / data_num for label_count in label_dict . values ( ) ] ) # 计算整个系统的熵 # 计算每个属性的熵 # 声明一个属性列表 ， {属性 ： {属性值 ： 出现的次数}} attr_value_count = { attr : defaultdict ( float ) for attr in attrs } # 声明属性->属性值->类别->数量 attr_value_class_count = { attr : defaultdict ( lambda : defaultdict ( float ) ) for attr in attrs } iter_index = range ( len ( attrs ) ) for i in range ( len ( datas ) ) : for j in iter_index : # 计算每个属性下不同值数量 ， 此处必要转换为离散变量 data = datas [ i ] attr_value_count [ attrs [ j ] ] [ data [ j ] ] += 1 attr_value_class_count [ attrs [ j ] ] [ data [ j ] ] [ labels [ i ] ] += 1.0 # 信息增益计算公式分析 #     H(D) - H(D|A) #     系统熵 - 每个属性下 ， 存在这个类别的信息熵 # # gains = [(属性名称 ， 信息增益 ， (属性值))......(属性名称n , 信息增益n ， (f1 ...fn))] # 以上运算是这样的； #   当查看每个属性 ， 在各个值中是否很大概率偏向一方 ， 这样造成整体信息增益最大 ， 因为整体的信息增益肯定为正的 ， #   减去一个越小的数 ， 数值反而越大 ， 就是说明属性是比较稳定的（比较有分类信息的） gains = [ ( attr , label_entropy - sum ( [ attr_value_count [ attr ] [ value ] / data_num * DecisionTree . entropy ( [ # 计算每个属性在特定属性值时 ， 发生的概率 # p(DA1)/A attr_value_class_count [ attr ] [ value ] [ label ] / attr_value_count [ attr ] [ value ] # 循环每个属性值在特定label产生 for label in attr_value_class_count [ attr ] [ value ] . keys ( ) ] ) for value in attr_value_count [ attr ] . values ( ) if attr_value_class_count [ attr ] . has_key ( value ) ] ) , attr_value_count [ attr ] . keys ( ) ) for attr in attr_value_count . keys ( ) ] # return attr_name , gains , attr value  return sorted ( gains , key = lambda x : x [ 1 ] , reverse = True )