python数据离散化代码_数据离散化与Python实现

本文介绍了数据离散化的概念和常见方法,包括等宽分组、等频分组、单变量分组及基于信息熵的分组,并通过Python代码展示了基于信息熵的数据离散化过程。
摘要由CSDN通过智能技术生成

一、原理

数据离散化(也称,数据分组),指将连续的数据进行分组,使其变为一段离散化的区间。

根据离散化过程中是否考虑类别属性,可以将离散化算法分为:有监督算法和无监督算法。事实证明,由于有监督算法充分利用了类别属性的信息,所以再分类中能获得较高的正确率。

常用的数据离散化方法:

等宽分组

等频分组

单变量分组

基于信息熵分组

数据离散化所使用的方法需要事先对数据进行排序,且假设待离散化的数据是按照升序排序。

1、等宽分组

原理:根据分组的个数得出固定的宽度,分到每个组中的变量的宽度是相等的。

如:现在有一个待离散化的数组[1, 7, 12, 12, 22, 30, 34, 38, 46],需要分成三组,

那么,

,即宽度 =( 46 - 1)/3 = 15

分组后结果范围:[1,16],(16, 31],(31, 46],第一个分组取的是全闭区间,

分组后结果:[1, 7, 12, 12],[22, 30],[34, 38, 46]

2、等频分组

原理:等频分组也叫分位数分组,即分组后,每个分组的元素个数是一样的。

如:现在有一个待离散化的数组[1, 7, 12, 12, 22, 30, 34, 38, 46],需要分成三组,

那么,

,即每组元素的个数 = 9 / 3 = 3

分组后的结果:[1, 7, 12],[12, 22, 30],  [34, 38, 46]

3、单变量分组

原理:单变量分组,也叫秩分组。将所有元素按照降序或者升序排序,排序名次即为排序结果,即将相同的元素划分到同一个组。

如:现在有一个待离散化的数组[1, 7, 12, 12, 22, 30, 34, 38, 46],

分组后的结果:[1], [7], [12, 12], [22], [30], [34], [38], [46]

4、基于信息熵分组

概念:

(1)信息量

Shannon认为,信息是用来消除随机不确定性的东西。即,衡量信息量大小就看这个消息消除不确定性的程度。

信息量的大小和事件发生的概率成反比。可以用公式表示为:

式中,p(x)表示x发生的概率。

(2)熵

熵,是在结果出来之前对可能产生的信息量的期望——考虑该随机变量的所有可能取值,即所有可能发生事件所带来的信息量的期望。

可以表示为:

按照随机变量的所有可能取值划分数据的总熵E是所有事件的熵的加权平均:

式中,

是第x个事件出现的比例,是第个可能取值出现的次数,是所有取值出现的总次数。

熵表示的是样本集合的不确定性。熵越大,则样本的不确定性越大。

所以,基于信息熵进行数据分组的具体做法是:

对属性A的所有取值从小到大进行排序;

遍历属性A的每个值,将属性A的值分为两个区间、,使得将其作为分隔点划分数据集后的熵最小;

当划分后的熵大于设置的阈值且小于指定的数据分组个数时,递归对、执行步骤2中的划分。

总结:

上述分组方法中,等宽分组和等频分组实现起来比较简单,但需要人为指定分组个数。

等宽分组的缺点:对离散值比较敏感,将属性值不均匀地分布到各个区间。有些区间的元素个数较多,有些则较少,容易导致数据倾斜。

等频分组虽然能避免等宽分组的缺点,但是会将相同的元素分到不同的组,如例子中的“12”元素。

二、基于信息熵的数据离散化实现

importnumpy as npimportmathclassDiscreateByEntropy:def __init__(self, group, threshold):

self.maxGroup= group #最大分组数

self.minInfoThreshold = threshold #停止划分的最小熵

self.result =dict()defloadData(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],

[2398,1],[592,1],[561,1],[764,0],[121,1]

]

)returndata#计算按照数据指定数据分组后的Shannon熵

defcalEntropy(self, data):

numData=len(data)

labelCounts={}for feature indata:#获得标签,这里只有0或者1

oneLabel = feature[-1]#设置字典中,标签的默认值

if labelCounts.get(oneLabel,-1) == -1:

labelCounts[oneLabel]=0#统计同类标签的数量

labelCounts[oneLabel] += 1shannoEnt= 0.0

for key inlabelCounts:#同类标签出现的概率,某一标签出现的次数除以所有标签的数量

prob = float(labelCounts[key])/numData#求熵,以2为底,取对数

shannoEnt -= prob *math.log2(prob)returnshannoEnt#按照调和信息熵最小化原则分割数据集

defsplit(self, data):#inf为正无穷

minEntropy =np.inf#记录最终分割的索引

index = -1

#按照第一列对数据进行排序

sortData =data[np.argsort(data[:,0])]#print(sortData)

#初始化最终分割数据后的熵

lastE1,lastE2 = -1, -1

#返回的数据区间,包括数据和对应的熵

S1 =dict()

S2=dict()for i inrange(len(data)):

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=entropy

index=i

lastE1=entropy1

lastE2=entropy2

S1["entropy"] =lastE1

S1["data"] = sortData[:index+1]

S2["entropy"] =lastE2

S2["data"] = sortData[index+1:]returnS1, S2, entropydeftrain(self,data):#需要遍历的key

needSplitKey =[0]

self.result.setdefault(0,{})

self.result[0]["entropy"] =np.inf

self.result[0]["data"] =data

group= 1

for key inneedSplitKey:

S1, S2, entropy= self.split(self.result[key]["data"])if entropy > self.minInfoThreshold and group

self.result[key]=S1

newKey= max(self.result.keys()) + 1self.result[newKey]=S2

needSplitKey.extend([key])

needSplitKey.extend([newKey])

group+= 1

else:break

if __name__ == '__main__':

dbe= DiscreateByEntropy(group=6,threshold=0.5)

data=dbe.loadData()

dbe.train(data)print("result is {}".format(dbe.result))

运行结果:

可见,将商品价格分为了5份,下标分别对应了0,1,2,3,4.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值