• 基于信息熵的数据离散化


    1、准备数据

      基于信息熵的数据离散化算法是由监督学习算法,在使用该方法对数据进行离散化时,需要数据有对应的标签。
      下面是一份用户最近点击的20个商品的价格与是否加入购物车对应关系:
    
            价格 标签 价格 标签 价格 标签 价格 标签
            56 1 641 1 10 1 2398 1
            87 1 63 0 9 0 592 1
            129 0 2764 1 88 1 561 1
            23 0 2323 0 222 0 764 0
            342 1 453 1 97 0 121 1
    

    对该份数据进行离散化:新建DiscreteByEntropy类,然后初始化相关函数,并加载数据。对应如下基于信息熵的数据离散化--新建类并加载数据:

    import numpy as np                                                                                                                                                                                                                                                          
    import math                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                          
    class DiscreteByEntropy:                                                                                                                                                                                         
          def __init__(self,group,threshold):
              self.maxGroup = group	#最大分组数
              self.minInfoThreshold = threshold		#停止划分的最小熵
              self.result = dict()		#保存划分结果
        
          #准备数据
          def loadData(self):
              data = np.array(
                  [
                      [56,1],[87,1],[129,0],[23,0],[342,1],
                      [641,1],[63,0],[2764,1],[2323,0],[453,1],
                      [10,1],[9,0],[88,1],[222,0],[97,0],
                  ]
              )
              return data
    

    2、计算数据的信息熵
    该步骤是计算数据的信息熵,是为下一步分割数据集做准备。对应如下基于信息熵的数据离散化--计算数据的信息熵

     #计算按照数据指定数据分组后的香农熵
     def calEntropy(self,data):
          numData = len(data)
          labelCounts = {}
          for feature in data:
              #获得标签
              oneLabel = feature[-1]
              #如果标签步骤新定义的字典里则创建该标签
              labelCounts.setdefault(oneLabel,0)
              #该类标签下含有数据的个数
              labelCounts[oneLabel] += 1
          shannonEnt = 0.0
          for key in labelCounts:
              #同类标签出现的概率
              prob = float(labelCounts[key]) / numData
              #以2为底求对数
              shannonEnt -= prob * math.log(prob,2)
          return shannonEnt
    

    3、分割数据集
    寻找一组数据最佳分割点的方法是:遍历所有属性值,数据按照该属性分割,使得平均熵最小。对应基于信息熵的数据离散化--分割数据集:

    按照调和信息熵最小化原则分割数据集

    def split(self,data):
        #inf为正无穷大
        minEntropy = np.inf
        #记录最终分割索引
        index = -1
        #按照第一列对数据进行排序
        sortData = data[np.argsort(data[:,0])]
        #初始化最终分割数据后的熵
        lastE1,lastE2 = -1,-1
        #返回的数据结构,包含数据和对应的熵
        S1 = dict()
        S2 = dict()
        for i in range(len(sortData)):
            #分割数据集
            splitData1,splitData2 = sortData[: i + 1],sortData[i + 1 :]
            entropy1,entropy2 = (
                self.calEntropy(splitData1),
                self.calEntropy(splitData2),
            ) #计算信息熵
            entropy = entropy1 * len(splitData1) / len(sortData) + 
                    entropy2 * len(splitData2) / len(sortData)
            #如果调和平均熵小于最小值
            if entropy < minEntropy:
                minEntropy = entropy
                index = i
                lastE1 = entropy1
                lastE2 = entropy2
    s1["entropy"] = lastE1
    s1["data"] = sortData[: index + 1]
    s1["entropy"] = lastE2
    s2["data"] = sortData[index + 1 :]
    return S1,S2,minEntropy
    

    4、数据离散化
    按照上面基于信息熵分组的内容,对数据做离散化处理。对应基于信息熵的数据离散化--数据离散化:

    #对数据进行分组
    def train(self,data):
        #需要遍历的key
        needSplitKey = [0]
        #将整个数据作为一组
        self.result.setdefault(0,{})
        self.result[0]["entropy"] = np.inf
        self.result[0]["data"] = data
        group = 1
        for key in needSplitKey:
            S1,S2,entropy = self.split(self.result[key]["data"])
            #如果满足条件
            if entropy > self.minInfoThreshold and group < self.maxGroup:
                self.result[key] = S1
                newKey = max(self.result.keys()) + 1
                self.result[newKey] = S2
                needSplitKey.extend([key])
                needSplitKey.extend([newKey])
                group += 1
            else:
                break
    if __name__ == "__main__":
        dbe = DiscreteByEntropy(group=6,threshold=0.5)
        data = dbe.loadData()
        dbe.train(data)
    print("result is {}".format(dbe.result))
    

    运行结果如下:

    可见这里将商品价格分为了3份,分别为{9,10,23,56,63,87,88}、{342,453,641,2323,2764}、{97,129,222}

  • 相关阅读:
    在sql语句中使用 xml for path 格式化字符串的方法总结
    Android handler的使用简单示例
    easyui datagrid中 多表头方法总结
    使用ICSharpCode.SharpZipLib.Zip类库解压zip文件的方法
    ThreadPoolExecutor 优雅关闭线程池的原理.md
    ThreadPoolExecutor 几个疑惑与解答
    如何在运行时(Runtime)获得泛型的真正类型
    为什么 EXISTS(NOT EXIST) 与 JOIN(LEFT JOIN) 的性能会比 IN(NOT IN) 好
    Spring MVC 上下文(ApplicationContext)初始化入口
    Tomcat生成的session持久化到MySQL
  • 原文地址:https://www.cnblogs.com/zhaop8078/p/13701093.html
Copyright © 2020-2023  润新知