連續特徵離散化和歸一化
阿新 • • 發佈:2019-02-04
RT,尤其在logistic regression上,需要把一些連續特徵進行離散化處理。離散化除了一些計算方面等等好處,還可以引入非線性特性,也可以很方便的做cross-feature。
連續特徵離散化處理有什麼好的方法, 有時候為什麼不直接歸一化?
這裡主要說明監督的變換方法;
連續性變數轉化成離散型變數大致有兩類方法:
(1)卡方檢驗方法;
(2)資訊增益方法;
一: 卡方檢驗方法
1.1 分裂方法
1.2 合併方法
分裂方法,就是找到一個分裂點看,左右2個區間,在目標值上分佈是否有顯著差異,有顯著差異就分裂,否則就忽略。這個點可以每次找差異最大的點。合併類似,先劃分如果很小單元區間,按順序合併在目標值上分佈不顯著的相鄰區間,直到收斂。
二:資訊增益方法
2.1 分裂方法
2.2 合併方法
這個和決策樹的學習很類似。分裂方法,就是找到一個分裂點看,左右2個區間,看分裂前後資訊增益變化閾值,如果差值超過閾值(正值,分列前-分裂後資訊熵),則分裂。每次找差值最大的點做分裂點,直到收斂。合併類似,先劃分如果很小單元區間,按順序合併資訊增益小於閾值的相鄰區間,直到收斂。參考文獻:
1 : csdn部落格:
http://www.cnblogs.com/emanlee/archive/2008/10/25/1319569.html2. 論文:連續值的離散化. 許文烈. 成均館大學。http://stat.skku.ac.kr/myhuh/homepage/specialLectures/SDULecture(Chinese).pdf
附件:採用資訊增益合併方法的連續特徵離散化程式:
''' Created on 2014/12/12 @author: dylanfan ''' import numpy as np class Feature_Discretization(object): def __init__(self): self.min_interval = 1 self.min_epos = 0.05 self.final_bin = [] def fit(self, x, y, min_interval = 1): self.min_interval = min_interval x = np.floor(x) x = np.int32(x) min_val = np.min(x) bin_dict = {} bin_li = [] for i in range(len(x)): pos = (x[i] - min_val)/min_interval * min_interval + min_val target = y[i] bin_dict.setdefault(pos,[0,0]) if target == 1: bin_dict[pos][0] += 1 else: bin_dict[pos][1] += 1 for key ,val in bin_dict.iteritems(): t = [key] t.extend(val) bin_li.append(t) bin_li.sort(cmp=None, key=lambda x : x[0], reverse=False) print bin_li L_index = 0 R_index = 1 self.final_bin.append(bin_li[L_index][0]) while True: L = bin_li[L_index] R = bin_li[R_index] # using infomation gain; p1 = L[1]/ (L[1] + L[2] + 0.0) p0 = L[2]/ (L[1] + L[2] + 0.0) if p1 <= 1e-5 or p0 <= 1e-5: LGain = 0 else: LGain = -p1*np.log(p1) - p0 * np.log(p0) p1 = R[1]/ (R[1] + R[2] + 0.0) p0 = R[2]/ (R[1] + R[2] + 0.0) if p1 <= 1e-5 or p0 <= 1e-5: RGain = 0 else: RGain = -p1*np.log(p1) - p0 * np.log(p0) p1 = (L[1] + R[1])/ (L[1] + L[2] + R[1] + R[2] + 0.0) p0 = (L[2] + R[2])/ (L[1] + L[2] + R[1] + R[2] + 0.0) if p1 <= 1e-5 or p0 <= 1e-5: ALLGain = 0 else: ALLGain = -p1*np.log(p1) - p0 * np.log(p0) if np.absolute(ALLGain - LGain - RGain) <= self.min_epos: # concat the interval; bin_li[L_index][1] += R[1] bin_li[L_index][2] += R[2] R_index += 1 else: L_index = R_index R_index = L_index + 1 self.final_bin.append(bin_li[L_index][0]) if R_index >= len(bin_li): break print 'feature bin:',self.final_bin def transform(self,x): res = [] for e in x: index = self.get_Discretization_index(self.final_bin, e) res.append(index) res = np.asarray(res) return res def get_Discretization_index(self ,Discretization_vals, val ): index = -1 for i in range(len(Discretization_vals)): e = Discretization_vals[i] if val <= e: index = i break return index