我在使用scikit-learn预处理缩放来处理稀疏矩阵。
我的目标是通过取每一特征列的最大值作为对数底来“缩放”每一特征列。我的表达可能不够准确,我尝试解释一下。
假设某一特征列的值为:0, 8, 2
:
- 最大值 = 8
- 特征值0的对数8应为0.0 =
math.log(0+1, 8+1)
(加1是为了处理零值;所以实际上,我们是在取以9为底的对数) - 特征值8的对数8应为1.0 =
math.log(8+1, 8+1)
- 特征值2的对数8应为0.5 =
math.log(2+1, 8+1)
是的,我可以轻松地使用FunctionTransformer应用任何基于函数的转换器,但我希望对数的底数能根据每一列(特别是最大值)变化。也就是说,我想做类似于MaxAbsScaler的事情,只是取对数。
我看到MaxAbsScaler
首先获取一个包含每一列最大值的向量(scale
)(代码),然后将原始矩阵乘以1 / scale
(代码)。
但是,如果我想基于scale
向量取对数,我不知道该怎么做。是否有可能将对数操作转换为乘法(?),还是有其他有效的scipy稀疏操作的可能性?
我希望我的意图是清晰的(并且是可能的)。
回答:
x在底b下的对数等同于log(x)/log(b),其中log是自然对数。因此,你描述的过程相当于首先对所有值应用log(x+1)变换,然后按最大绝对值进行缩放。方便的是,log(x+1)是一个内置函数,log1p
。示例:
from sklearn.preprocessing import FunctionTransformer, maxabs_scalefrom scipy.sparse import csc_matriximport numpy as nplogtran = FunctionTransformer(np.log1p, accept_sparse=True)X = csc_matrix([[ 1., 0, 8], [ 2., 0, 0], [ 0, 1., 2]])Y = maxabs_scale(logtran.transform(X))
输出(稀疏矩阵Y):
(0, 0) 0.630929753571 (1, 0) 1.0 (2, 1) 1.0 (0, 2) 1.0 (2, 2) 0.5