数据分箱

### 数据分箱(分箱后需要编码) 连续值经常离散化或者分离成“箱子”进行分析, **为什么要做数据分箱呢?** >- 离散后稀疏向量内积乘法运算速度更快,计算结果也方便存储,容易扩展; >- 离散后的特征对异常值更具鲁棒性,如 age>30 为 1 否则为 0,对于年龄为 200 的也不会对模型造成很大的干扰; >- LR 属于广义线性模型,表达能力有限,经过离散化后,每个变量有单独的权重,这相当于引入了非线性,能够提升模型的表达能力,加大拟合; >- 离散后特征可以进行特征交叉,提升表达能力,由 M+N 个变量编程 M*N 个变量,进一步引入非线形,提升了表达能力; >- 特征离散后模型更稳定,如用户年龄区间,不会因为用户年龄长了一岁就变化 当然还有很多原因,LightGBM 在改进 XGBoost 时就增加了数据分箱,增强了模型的泛化性。现在介绍数据分箱的方式: - 等频分箱 - 等距分箱 - [Best-KS分箱](https://blog.csdn.net/hxcaifly/article/details/84593770)(类似利用基尼指数进行二分类) - [卡方分箱](https://www.jianshu.com/p/a4f3142bcf5e) (好像只能用于分类模型) **最好将数据分箱的特征作为新一列的特征,不要把原来的数据给替换掉**。这里放一个数据分箱的其他例子(迁移之用) ```python # 连续值经常离散化或者分离成“箱子”进行分析。 # 假设某项研究中一组人群的数据,想将他们进行分组,放入离散的年龄框中 ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] # 如果按年龄分成18-25, 26-35, 36-60, 61以上的若干组,可以使用pandas中的cut bins = [18, 25, 35, 60, 100] # 定义箱子的边 cats = pd.cut(ages, bins) print(cats) # 这是个categories对象 通过bin分成了四个区间, 然后返回每个年龄属于哪个区间 # codes属性 print(cats.codes) # 这里返回一个数组,指明每一个年龄属于哪个区间 print(cats.categories) print(pd.value_counts(cats)) # 返回结果是每个区间年龄的个数 # 与区间的数学符号一致, 小括号表示开放,中括号表示封闭, 可以通过right参数改变 print(pd.cut(ages, bins, right=False)) # 可以通过labels自定义箱名或者区间名 group_names = ['Youth', 'YonngAdult', 'MiddleAged', 'Senior'] data = pd.cut(ages, bins, labels=group_names) print(data) print(pd.value_counts(data)) # 如果将箱子的边替代为箱子的个数,pandas将根据数据中的最小值和最大值计算出等长的箱子 data2 = np.random.rand(20) print(pd.cut(data2, 4, precision=2)) # precision=2 将十进制精度限制在2位 # qcut是另一个分箱相关的函数, 基于样本分位数进行分箱。取决于数据的分布,使用cut不会使每个箱子具有相同数据数量的数据点,而qcut,使用 # 样本的分位数,可以获得等长的箱 data3 = np.random.randn(1000) # 正太分布 cats = pd.qcut(data3, 4) print(pd.value_counts(cats)) ``` 结果如下: ![20891914a5fac61651369c36.png](https://cos.easydoc.net/17082933/files/kgn7351n.png) [对连续特征一定要进行分箱处理吗?](http://sofasofa.io/forum_main_post.php?postid=1005469)