连续特征离散化

来源:互联网 发布:unity3d游戏开发 pdf 编辑:程序博客网 时间:2024/05/20 20:17

RT,尤其在logistic regression上,需要把一些连续特征进行离散化处理。离散化除了一些计算方面等等好处,还可以引入非线性特性,也可以很方便的做cross-feature。

连续特征离散化处理有什么好的方法, 有时候为什么不直接归一化?

这里主要说明监督的变换方法;


连续性变量转化成离散型变量大致有两类方法:

(1)卡方检验方法;

(2)信息增益方法;


一: 卡方检验方法

1.1 分裂方法

1.2 合并方法

分裂方法,就是找到一个分裂点看,左右2个区间,在目标值上分布是否有显著差异,有显著差异就分裂,否则就忽略。这个点可以每次找差异最大的点。合并类似,先划分如果很小单元区间,按顺序合并在目标值上分布不显著的相邻区间,直到收敛。


二:信息增益方法

2.1 分裂方法

2.2 合并方法

这个和决策树的学习很类似。分裂方法,就是找到一个分裂点看,左右2个区间,看分裂前后信息增益变化阈值,如果差值超过阈值(正值,分列前-分裂后信息熵),则分裂。每次找差值最大的点做分裂点,直到收敛。合并类似,先划分如果很小单元区间,按顺序合并信息增益小于阈值的相邻区间,直到收敛。



参考文献:

1 : csdn博客:

x2检验(chi-square test)或称卡方检验

http://www.cnblogs.com/emanlee/archive/2008/10/25/1319569.html


采用信息增益合并方法的连续特征离散化程序:


[python] view plain copy
 
 在CODE上查看代码片派生到我的代码片

  1. import numpy as np  
  2.   
  3.  
  4.   
  5. class Feature_Discretization(object):  
  6.       
  7.     def __init__(self):  
  8.           
  9.         self.min_interval = 1   
  10.         self.min_epos = 0.05         
  11.         self.final_bin = []  
  12.           
  13.       
  14.     def fit(self, x, y, min_interval = 1):  
  15.         self.min_interval = min_interval  
  16.         x = np.floor(x)  
  17.         x = np.int32(x)  
  18.         min_val = np.min(x)  
  19.         bin_dict = {}  
  20.         bin_li = []  
  21.         for i in range(len(x)):  
  22.             pos = (x[i] - min_val)/min_interval * min_interval  + min_val  
  23.             target = y[i]  
  24.             bin_dict.setdefault(pos,[0,0])             
  25.             if target == 1:  
  26.                 bin_dict[pos][0] += 1                  
  27.             else:  
  28.                 bin_dict[pos][1] += 1  
  29.           
  30.         for key ,val in bin_dict.iteritems():  
  31.             t = [key]  
  32.             t.extend(val)  
  33.             bin_li.append(t)  
  34.           
  35.         bin_li.sort(cmp=None, key=lambda x : x[0], reverse=False)  
  36.         print bin_li  
  37.               
  38.        
  39.         L_index = 0   
  40.         R_index = 1  
  41.         self.final_bin.append(bin_li[L_index][0])  
  42.         while True:             
  43.             L = bin_li[L_index]              
  44.             R = bin_li[R_index]  
  45.             # using infomation gain;  
  46.             p1 =  L[1]/ (L[1] + L[2] + 0.0)  
  47.             p0 =  L[2]/ (L[1] + L[2] + 0.0)  
  48.               
  49.             if p1 <= 1e-5 or p0 <= 1e-5:  
  50.                 LGain = 0   
  51.             else:  
  52.                 LGain = -p1*np.log(p1) - p0 * np.log(p0)  
  53.               
  54.             p1 =  R[1]/ (R[1] + R[2] + 0.0)  
  55.             p0 =  R[2]/ (R[1] + R[2] + 0.0)  
  56.             if p1 <= 1e-5 or p0 <= 1e-5:  
  57.                 RGain = 0   
  58.             else:  
  59.                 RGain = -p1*np.log(p1) - p0 * np.log(p0)  
  60.               
  61.             p1 = (L[1] + R[1])/ (L[1] + L[2] + R[1] + R[2] + 0.0)  
  62.             p0 = (L[2] + R[2])/ (L[1] + L[2] + R[1] + R[2] + 0.0)  
  63.               
  64.             if p1 <= 1e-5 or p0 <= 1e-5:  
  65.                 ALLGain = 0   
  66.             else:  
  67.                 ALLGain = -p1*np.log(p1) - p0 * np.log(p0)  
  68.               
  69.             if np.absolute(ALLGain - LGain - RGain) <= self.min_epos:  
  70.                 # concat the interval;  
  71.                 bin_li[L_index][1] += R[1]  
  72.                 bin_li[L_index][2] += R[2]  
  73.                 R_index += 1  
  74.               
  75.             else:                  
  76.                 L_index = R_index  
  77.                 R_index = L_index + 1  
  78.                 self.final_bin.append(bin_li[L_index][0])  
  79.               
  80.             if R_index >= len(bin_li):  
  81.                 break  
  82.           
  83.         print 'feature bin:',self.final_bin  
  84.           
  85.       
  86.     def transform(self,x):  
  87.         res = []  
  88.         for e in x:  
  89.             index = self.get_Discretization_index(self.final_bin, e)  
  90.             res.append(index)  
  91.           
  92.         res = np.asarray(res)  
  93.         return res  
  94.       
  95.     def get_Discretization_index(self ,Discretization_vals, val ):     
  96.         index = -1  
  97.         for i in range(len(Discretization_vals)):  
  98.             e = Discretization_vals[i]  
  99.             if val <= e:  
  100.                 index = i              
  101.                 break  
  102.                       
  103.         return index 
原创粉丝点击