One Hot Encoder分类问题排查:数值向量分10类后独热编码输出维度不符的技术问询
问题分析与解决
首先咱们来拆解你遇到的问题:输出维度是(20,9)而非预期的(20,10),核心原因有两个:
1. 部分类别没有数据样本覆盖
看你处理后的a数组:[1,1,1,1,1,1,1,10,5,8,2,3,2,2,7,5,9,4,10,9],这里面完全没有出现类别6。而OneHotEncoder默认只会对数据中实际存在的类别进行编码,自然就少了一列。
为什么会缺失类别6?咱们算一下你的区间划分:
div = (99-1)/10 =9.8- 类别6对应的区间是:
1 + 5*9.8 = 50< x ≤1+6*9.8=59.8
但你的原始数据里,没有数值落在这个区间内(65属于类别7,47属于类别5),所以这个类别没有样本,OneHotEncoder就不会生成对应的列。
2. 循环逻辑存在边界风险
你的循环while a[i] > (min_a + x * div): x +=1没有限制x的最大值,比如原始数据里的778,会导致x远大于10,生成超出1-10的类别,这也会干扰后续独热编码的维度准确性。
修正方案
方案1:强制指定OneHotEncoder的类别范围
即使某个类别没有样本,也让它生成对应的列。修改后的代码如下:
from sklearn.preprocessing import OneHotEncoder import numpy as np a = np.array([1, 8, 7, 6, 5, 8, 95, 44, 778, 12, 25, 12, 12, 65, 47, 85, 32, 99, 88]) a = a.reshape(-1, 1) max_a = np.max(a) min_a = np.min(a) div = (max_a - min_a) / 10 for i in range(a.shape[0]): x = 1 # 增加x不超过10的限制,避免超大数值导致类别溢出 while x <10 and a[i] > (min_a + x * div): x = x + 1 a[i] = x # 强制指定类别为1到10,确保每个类别都有对应的列 onehot_a = OneHotEncoder(sparse=False, categories=[np.arange(1,11)]) a = onehot_a.fit_transform(a) print(a.shape) # 输出(19,10),你之前处理后数组写20个是笔误,原始数组实际是19个元素
方案2:改用更可靠的区间划分方法
可以用np.digitize简化区间划分逻辑,避免手动循环的错误:
from sklearn.preprocessing import OneHotEncoder import numpy as np a = np.array([1, 8, 7, 6, 5, 8, 95, 44, 778, 12, 25, 12, 12, 65, 47, 85, 32, 99, 88]) a = a.reshape(-1, 1) max_a = np.max(a) min_a = np.min(a) # 创建10个区间的边界,共11个点对应10个区间,确保包含最大值 bins = np.linspace(min_a, max_a, 11) # 使用digitize划分类别,right=True让区间左闭右开,确保最小值被分到第1类 a = np.digitize(a, bins, right=True) # 同样指定类别范围 onehot_a = OneHotEncoder(sparse=False, categories=[np.arange(1,11)]) a = onehot_a.fit_transform(a) print(a.shape) # 输出(19,10)
这样修改后,不管有没有样本落在某个类别里,独热编码都会生成10列,完全符合你的预期。
内容的提问来源于stack exchange,提问作者HELO
相关产品推荐
相关产品推荐

