恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
SMILE 数据变换指南:可组合、可序列化的特征预处理管道(Transform / InvertibleTransform / 六种内置缩放器)
首页
资讯中心
/
SMILE 数据变换指南:可组合、可序列化的特征预处理管道(Transform / InvertibleTransform / 六种内置缩放器)
SMILE 数据变换指南:可组合、可序列化的特征预处理管道(Transform / InvertibleTransform / 六种内置缩放器)
发布时间:2026/10/9 2:07:57
人工智能机器学习深度学习NLP大模型模型推理服务数据可视化【免费下载链接】smileStatistical Machine Intelligence Learning Engine项目地址https://gitcode.com/gh_mirrors/smi/smile点击查看免费下载本篇技术指南完整讲解 SMILEStatistical Machine Intelligence Learning Engine中smile.data.transform与smile.feature.transform两个包构成的数据变换Data Transformation体系从Transform/InvertibleTransform接口、ColumnTransform/InvertibleColumnTransform实现到Scaler、Standardizer、RobustStandardizer、WinsorScaler、MaxAbsScaler、Normalizer六种内置预处理算子再到管道组合、逆变换、可空列处理、序列化与自定义变换。读者学完后将能够在 SMILE 中搭建训练集拟合、测试集套用的标准预处理管道并把经过变换的预测结果逆变换回原始单位用于业务解读。1. 架构总览从单行映射到列并行批量处理数据变换位于两个层次基础设施层smile.data.transform定义Transform、InvertibleTransform两个接口以及ColumnTransform、InvertibleColumnTransform两个实现类源码见 base/src/main/java/smile/data/transform业务算子层smile.feature.transform六个内置统计缩放器全部构建在上述基础设施之上返回InvertibleColumnTransform或普通Transform源码见 core/src/main/java/smile/feature/transform。整体类型关系如下Transform ────────────────────────────────────────────────────────── │ apply(Tuple) → Tuple (逐行) │ apply(DataFrame) → DataFrame (批量列并行) │ andThen(Transform)→ Transform (正向组合) │ compose(Transform)→ Transform (反向组合) │ ├── ColumnTransform (列名→lambda 映射按列处理) │ └── InvertibleColumnTransform (额外提供 invert() 正/逆两个映射) │ InvertibleTransform extends Transform │ invert(Tuple) → Tuple │ invert(DataFrame) → DataFrame所有内置缩放器Scaler、Standardizer、RobustStandardizer、WinsorScaler、MaxAbsScaler的fit均返回InvertibleColumnTransform只有Normalizer返回普通的Transform它按行归一化不可逆。2. Transform 接口一切预处理步骤的唯一入口Transform位于smile.data.transform包继承自java.util.function.FunctionTuple, Tuple并实现java.io.Serializable见 Transform.java。每个预处理步骤只需实现这一个接口。2.1 逐行应用Transform t /* 任意 transform */; Tuple outRow t.apply(inRow);2.2 批量应用接口的默认apply(DataFrame)实现将所有行stream().map(this)流式逐行变换后重新组装为DataFrame见 Transform.java。而ColumnTransform重写了这个默认实现走列并行的快速路径避免逐行产生对象分配DataFrame out t.apply(df);ColumnTransform.apply(DataFrame)内部用IntStream.range(0, schema.length()).parallel()按列并行处理每个被映射的列先取出doubleStream()套用 lambda 后重建为DoubleVector或NullableDoubleVector未映射的列则零拷贝直通直接复用原ValueVector对象见 ColumnTransform.java。2.3 静态工厂方法// 从已拟合的 transform 构建单步管道 Transform chain Transform.pipeline(step1, step2, step3); // 依序拟合多个数据依赖的 transform // 每个后续 trainer 拿到的是经过前面所有步骤变换后的数据 Transform pipeline Transform.fit(trainDf, Standardizer::fit, data - WinsorScaler.fit(data, 0.01, 0.99));pipeline与fit的源码实现值得注意pipeline(Transform...)从左到右逐级andThen若传入数组为空或为null则抛出IllegalArgumentException(At least one transform is required)fit(DataFrame, FunctionDataFrame,Transform...)先让第一个 trainer 在原始数据上拟合然后对每个后续 trainer 执行data pipeline.apply(data)即trainer 永远看到已被前序步骤变换过的数据见 Transform.java。传入空 trainer 列表同样抛IllegalArgumentException。3. InvertibleTransform 接口可逆变换InvertibleTransform在Transform之上增加两个逆操作见 InvertibleTransform.javapublic interface InvertibleTransform extends Transform { Tuple invert(Tuple x); DataFrame invert(DataFrame data); }逆变换的价值在于恢复原始特征空间解读模型输出模型在标准化后的目标变量上训练预测结果必须先反标准化才能呈现给用户重建误差度量自编码器或 PCA 异常检测可以在原始单位上度量重建保真度调试自检验证invert(apply(x)) ≈ x。InvertibleColumnTransform scaler Standardizer.fit(train); DataFrame scaled scaler.apply(test); DataFrame recovered scaler.invert(scaled); // 回到原始单位4. ColumnTransform所有列式变换的实体类ColumnTransform持有一个MapString, Function——列名到smile.util.function.Functionlambda 的映射构造参数为变换名称与映射表见 ColumnTransform.java。4.1 手动构造import smile.data.transform.ColumnTransform; import smile.util.function.Function; import java.util.Map; // 对 income 做对数变换其余列原样保留 MapString, Function transforms Map.of(income, Math::log); ColumnTransform ct new ColumnTransform(log-income, transforms); DataFrame out ct.apply(df);4.2 行为特征映射表中不存在的列直接透传复用同一ValueVector对象零拷贝被变换的列一律变为DoubleType输入可空则为NullableDoubleTypeapply(DataFrame)使用IntStream.range(...).parallel()按列并行处理可空列的空值掩码BitSet会被原样复制到输出向量。4.3 toString 输出System.out.println(ct); // log-income( // log(income) // )输出格式为name(\n function_toString(), ...\n)。内置缩放器为每个Function实现了语义化的toString()例如Scaler会输出形如(income - 1234.5000) / 5678.9000的公式见 Scaler.java而普通 lambda 若不覆写则打印默认的 JVM 引用。5. InvertibleColumnTransform正逆双映射InvertibleColumnTransform extends ColumnTransform implements InvertibleTransform额外保存一份逆 lambda 映射见 InvertibleColumnTransform.java。import smile.data.transform.InvertibleColumnTransform; MapString, Function transforms Map.of(price, v - Math.log1p(v)); MapString, Function inverses Map.of(price, v - Math.expm1(v)); InvertibleColumnTransform ict new InvertibleColumnTransform(log1p-price, transforms, inverses); DataFrame logPrices ict.apply(df); DataFrame original ict.invert(logPrices); // ≈ df5.1 逆变换行为出现在inverses 映射中的列用对应 lambda 逆变换不在逆映射中的列原样透传可空列在正向与逆向两条路径上都保留空值掩码——空值既不会被伪造也不会丢失。逆变换的invert(DataFrame)同样采用列并行实现见 InvertibleColumnTransform.java。6. 六种内置缩放器与标准化器所有内置变换遵循同一使用模式调用Xxx.fit(trainData)从训练数据学习参数调用.apply(anyData)对训练集和测试集一视同仁地变换可选调用.invert(transformedData)恢复原始尺度。训练/测试纪律永远只对训练数据fit再把拟合好的变换同时应用于训练集与测试集——这是避免数据泄漏data leakage的关键。此外所有列式fit()方法都接受可变的String... columns参数省略时自动变换全部数值列源码中通过schema.fields().stream().filter(StructField::isNumeric)筛选见 Scaler.java。6.1 Scaler — 最小-最大缩放将每个数值列映射到[0, 1]x_scaled (x - min) / (max - min)训练范围之外的值会被**钳制clamp**到[0, 1]。源码实现要点若列值跨度为零常数列缩放因子回退为1.0逆变换invert为x * scale lo见 Scaler.java。import smile.feature.transform.Scaler; // 在训练集上拟合变换全部数值列 InvertibleColumnTransform scaler Scaler.fit(train); DataFrame trainScaled scaler.apply(train); DataFrame testScaled scaler.apply(test); // 只拟合指定列 InvertibleColumnTransform partial Scaler.fit(train, age, income);注意Scaler的逆变换对落在训练[min, max]之外的测试值是有损的——因为这些值在正向阶段已被钳制到[0,1]见 Scaler.java 的类注释。适用场景对特征量级敏感的算法KNN、RBF 核 SVM、神经网络且数据没有严重离群值。避免场景存在大离群值——单个极端值会把所有正常值压缩到极小区间此时改用WinsorScaler。6.2 Standardizer — z-score 标准化将每个数值列缩放为零均值、单位方差x_std (x - μ) / σ实现要点见 Standardizer.java标准差采用**样本公式N−1 分母**计算MathEx.stdev若标准差为零常数列缩放因子回退为1.0只做中心化——训练集上输出全为 0单行 DataFrame 同样如此处理。import smile.feature.transform.Standardizer; InvertibleColumnTransform std Standardizer.fit(train); DataFrame trainStd std.apply(train); DataFrame testStd std.apply(test);适用场景算法假设特征服从高斯分布或使用距离/点积计算线性回归、逻辑回归、线性 SVM、PCA。避免场景重尾分布或离群值较多——单个大离群值会抬高 σ导致主体数据被欠压缩此时改用RobustStandardizer。6.3 RobustStandardizer — 中位数 / IQR 稳健标准化减去中位数并除以四分位距IQRx_robust (x - median) / IQRIQR 即第 75 与第 25 百分位之差IQR 为零时缩放因子回退为1.0。实现要点分位数通过smile.sort.IQAgent增量计算是近似结果——在极小数据集 20 行上可能与基于精确排序的分位数略有出入见 RobustStandardizer.java。import smile.feature.transform.RobustStandardizer; InvertibleColumnTransform robust RobustStandardizer.fit(train); DataFrame robustTrain robust.apply(train);适用场景数据含离群值或重尾分布。中位数与 IQR 对极端值的敏感度远低于均值与标准差。6.4 WinsorScaler — 百分位钳制缩放两步处理将训练分布[lower, upper]百分位范围之外的值钳制到边界将结果缩放到[0, 1]。import smile.feature.transform.WinsorScaler; // 默认5% 下界、95% 上界 InvertibleColumnTransform ws WinsorScaler.fit(train); // 自定义百分位——在 1% 与 99% 处钳制 InvertibleColumnTransform ws2 WinsorScaler.fit(train, 0.01, 0.99); // 只变换指定列 InvertibleColumnTransform ws3 WinsorScaler.fit(train, 0.05, 0.95, price, quantity);参数校验细节见 WinsorScaler.javalower 0抛Invalid lower: ...upper 1抛Invalid upper: ...lower upper抛Invalid lower... upper...默认fit(data, cols...)等价于fit(data, 0.05, 0.95, cols...)。分位数同样经IQAgent近似计算。适用场景训练集中存在有意义但不想让它们扭曲主体数据缩放的离群值常见于金融与传感器数据。6.5 MaxAbsScaler — 最大绝对值缩放每个特征除以自身的最大绝对值使所有值落在[-1, 1]。该缩放器不做中心化不减去均值因此不会破坏稀疏性x x / max(|x|)实现要点最大绝对值累加器初始化为 0.0因此全负列也能得到正确结果例如[-3,-2,-1]的缩放因子为 3.0全零列回退为1.0见 MaxAbsScaler.java。import smile.feature.transform.MaxAbsScaler; InvertibleColumnTransform mas MaxAbsScaler.fit(train); DataFrame scaled mas.apply(test);适用场景稀疏数据如 TF-IDF 向量或当数值符号有意义、且需要精确保留零值时。6.6 Normalizer — 逐行单位范数Normalizer与上述列式缩放器不同它按**行样本**缩放使整行向量的范数为 1支持三种范数范数约束L1Σ|xᵢ| 1L2√(Σxᵢ²) 1L_INFmax(|xᵢ|) 1实现要点见 Normalizer.java构造器要求norm非空、columns非空否则分别抛NullPointerException/IllegalArgumentException若行范数为零零向量缩放因子回退为1.0防止除零。import smile.feature.transform.Normalizer; import smile.feature.transform.Normalizer.Norm; // 归一化指定列 String[] features {f1, f2, f3}; Normalizer l2 new Normalizer(Norm.L2, features); DataFrame normed l2.apply(df); // 对单个 Tuple 逐行应用 Tuple row df.get(0); Tuple normRow l2.apply(row);Normalizer不可逆不是InvertibleTransform。适用场景文本分类TF-IDF、基于余弦相似度的算法或当行的方向特征比例比行的幅值更有意义时。7. 组合变换andThen、compose、pipeline 与 fit7.1 andThen 与 compose语义与java.util.function.Function完全一致见 Transform.java// a.andThen(b) ≡ b(a(x)) —— 先 a 后 b Transform aFirst a.andThen(b); // b.compose(a) ≡ b(a(x)) —— 同结果不同写法 Transform alsoAFirst b.compose(a);两者都返回一个新的Transform本质是一个 lambda而非具名类InvertibleColumnTransform scaler Scaler.fit(train); InvertibleColumnTransform std Standardizer.fit(train); // 先缩放再标准化 Transform both scaler.andThen(std); DataFrame out both.apply(test);注意组合结果是普通Transform即使两个输入都可逆也不再是InvertibleTransform。若需要对组合结果求逆使用Transform.fit见 7.3或按逆序分别对每一步求逆。7.2 pipelineTransform.pipeline(t1, t2, ..., tN)等价于连续andThen三步以上时更易读Transform pipeline Transform.pipeline( imputer, // 填充缺失值 scaler, // [0, 1] 缩放 std // z-score ); DataFrame train_prepped pipeline.apply(train); DataFrame test_prepped pipeline.apply(test);无变换参数调用时抛IllegalArgumentException。7.3 fit —— 数据依赖管道核心范式Transform.fit(data, trainer1, trainer2, ...)中每个 trainer 都是FunctionDataFrame, Transform它观察到的是当前已被前序步骤变换过的数据并返回下一步骤Transform pipeline Transform.fit(train, // 步骤 1在原始训练数据上拟合 imputer data - SimpleImputer.fit(data), // 步骤 2在插补后的训练数据上拟合 scaler data - Scaler.fit(data), // 步骤 3在缩放插补后的训练数据上拟合 standardizer data - Standardizer.fit(data) ); // 对测试数据一次性应用整个管道 DataFrame testOut pipeline.apply(test);这是构建多步预处理管道的规范方式每一步的参数都依赖于前序步骤的输出。trainer 列表为空时抛IllegalArgumentException。8. 逆变换Inverting TransformsInvertibleTransform.invert()把数据从变换空间映射回原始空间用途包括解读预测在标准化目标上训练的模型其输出必须先反标准化再展示给用户重建误差自编码器或 PCA 异常检测可在原始单位上度量重建保真度调试验证invert(apply(x)) ≈ x。InvertibleColumnTransform std Standardizer.fit(train); // 正向 DataFrame trainStd std.apply(train); double[] yStd model.predict(trainStd); // 恢复原始单位的预测值 // 构造单列 DataFrame 以便通过 invert() DataFrame predDf DataFrame.of(new DoubleVector(y, yStd)); DataFrame predOriginal std.invert(predDf);8.1 逐行逆变换Tuple row df.get(0); Tuple scaled std.apply(row); Tuple backToNormal std.invert(scaled);8.2 组合逆变换多个可逆变换叠加时求逆必须颠倒顺序InvertibleColumnTransform s1 Scaler.fit(train); InvertibleColumnTransform s2 Standardizer.fit(s1.apply(train)); // 正向先 s1 后 s2 DataFrame fwd s2.apply(s1.apply(test)); // 逆向先 s2⁻¹ 后 s1⁻¹顺序颠倒 DataFrame inv s1.invert(s2.invert(fwd));9. 可空列处理SMILE 支持由NullableDoubleVector及对应的其他基本类型向量支撑的可空列。本包所有变换都保持可空性可空输入列必然产生可空输出列——空值位掩码被完整复制变换 lambda 仍会被调用在空单元格对应的原始double值上约定为Double.NaN但结果会被忽略输出向量中以NaN/null 占位逆变换同样保留空值掩码。// 假设 income 存在部分空值 InvertibleColumnTransform scaler Scaler.fit(train); DataFrame scaled scaler.apply(train); // scaled.column(income).isNullable() → true (与输入一致) // scaled.column(income).isNullAt(k) → 与 train 一致 DataFrame restored scaler.invert(scaled); // restored.column(income).isNullable() → true (空值掩码被保留)空值掩码在 ColumnTransform.java 与 InvertibleColumnTransform.java 中均以BitSet显式复制实现。10. 序列化Transform继承java.io.Serializable。所有内置实现及其闭包捕获的 lambda 都可序列化因此拟合好的变换可以保存并重新加载// 保存 try (var out new ObjectOutputStream(new FileOutputStream(scaler.ser))) { out.writeObject(scaler); } // 加载 InvertibleColumnTransform loaded; try (var in new ObjectInputStream(new FileInputStream(scaler.ser))) { loaded (InvertibleColumnTransform) in.readObject(); } // 用加载的变换处理新数据 DataFrame newData loaded.apply(incoming);lambda 陷阱传给ColumnTransform/InvertibleColumnTransform的 lambda 若引用了一个不可序列化的宿主类保存时会抛NotSerializableException。因此只在宿主类本身Serializable时使用方法引用或匿名类或者选用内置缩放器其内部Function已实现可序列化。11. 编写自定义变换方案 A — 直接实现 Transform适用于非列式变换行归一化、降维等import smile.data.transform.Transform; import smile.data.Tuple; public class ClipTransform implements Transform { private final double min, max; private final SetString columns; public ClipTransform(double min, double max, String... columns) { this.min min; this.max max; this.columns new HashSet(Arrays.asList(columns)); } Override public Tuple apply(Tuple x) { StructType schema x.schema(); return new smile.data.AbstractTuple(schema) { Override public Object get(int i) { String name schema.field(i).name(); if (columns.contains(name)) { double v x.getDouble(i); return Math.max(min, Math.min(max, v)); } return x.get(i); } }; } }方案 B — 用 ColumnTransform lambda列式数值变换的最简做法// 把所有值钳制到 [-3, 3] MapString, Function clips new HashMap(); for (String col : numericColumns) { clips.put(col, x - Math.max(-3.0, Math.min(3.0, x))); } ColumnTransform clipper new ColumnTransform(clip±3, clips);方案 C — 用 InvertibleColumnTransform lambda需要同时提供正逆变换时// Box-Cox 幂变换λ 0.5即平方根变换 double lambda 0.5; MapString, Function fwd Map.of( revenue, x - (Math.pow(x, lambda) - 1.0) / lambda ); MapString, Function inv Map.of( revenue, y - Math.pow(y * lambda 1.0, 1.0 / lambda) ); InvertibleColumnTransform boxCox new InvertibleColumnTransform(BoxCox(0.5), fwd, inv);方案 D — 数据依赖的自定义变换配合 fit// 每个列除以自身训练中位数 static InvertibleColumnTransform fitMedianScaler(DataFrame data, String... cols) { MapString, Function transforms new HashMap(); MapString, Function inverses new HashMap(); for (String col : cols) { double[] vals data.column(col).toDoubleArray(); double median MathEx.median(vals); double scale MathEx.isZero(median) ? 1.0 : Math.abs(median); transforms.put(col, x - x / scale); inverses.put(col, y - y * scale); } return new InvertibleColumnTransform(MedianScaler, transforms, inverses); }这种fit风格的自定义变换可直接传入Transform.fit(data, ...)组成数据依赖管道。12. 端到端实战教程贷款数据集预处理教程目标预处理包含loan_amountdouble、annual_incomedouble可空、grade类别型、termint与标签defaultint的贷款数据集。步骤 1 — 划分数据DataFrame data Read.csv(loans.csv); // 80/20 训练/测试划分按索引 int n data.size(); int trainSize (int)(n * 0.8); DataFrame train data.slice(0, trainSize); DataFrame test data.slice(trainSize, n);步骤 2 — 插补缺失值import smile.feature.imputation.SimpleImputer; // 拟合学习每列填充值数值列取均值类别列取众数 Transform imputer SimpleImputer.fit(train); DataFrame trainImputed imputer.apply(train); DataFrame testImputed imputer.apply(test);步骤 3 — 缩放数值特征import smile.feature.transform.WinsorScaler; // 收入存在离群值用 Winsor 提升稳健性 InvertibleColumnTransform scaler WinsorScaler.fit(trainImputed, 0.01, 0.99, loan_amount, annual_income); DataFrame trainScaled scaler.apply(trainImputed); DataFrame testScaled scaler.apply(testImputed);步骤 4 — 组合为单一可复用管道Transform fullPipeline Transform.fit(train, SimpleImputer::fit, data - WinsorScaler.fit(data, 0.01, 0.99, loan_amount, annual_income) ); // 一次调用即可——结果与步骤 2-3 相同 DataFrame trainPrepped fullPipeline.apply(train); DataFrame testPrepped fullPipeline.apply(test);步骤 5 — 用 Formula 训练模型import smile.data.formula.Formula; Formula formula Formula.of(default, Terms.$(loan_amount), Terms.$(annual_income), Terms.$(term), Terms.$(grade)); // 提取设计矩阵与响应 var X formula.matrix(trainPrepped); var y formula.y(trainPrepped).toIntArray(); // … 用 X 与 y 拟合模型 …步骤 6 — 逆变换预测结果用于解读// 假设我们预测了一个连续分数并希望以原始收入单位理解它 double[] scores model.predict(formula.matrix(testPrepped)); DataFrame scoreDf DataFrame.of(new DoubleVector(annual_income, scores)); DataFrame inOriginalScale scaler.invert(scoreDf); System.out.println(inOriginalScale);步骤 7 — 检视并保存管道// 检视每一步学到了什么 System.out.println(fullPipeline); // 序列化用于生产环境复用 try (var out new ObjectOutputStream(new FileOutputStream(pipeline.ser))) { out.writeObject(fullPipeline); }13. 如何选择合适的变换场景推荐变换无明显离群值、量级区间重要Scaler高斯假设、基于距离/点积的算法Standardizer存在离群值、追求稳健性RobustStandardizer存在离群值、输出需要有界WinsorScaler稀疏数据、零必须保持为零MaxAbsScaler方向比例重要、量级无关Normalizer(L2)文本/计数向量Normalizer(L1 或 L2)自定义对数/幂变换InvertibleColumnTransform lambda缩放前有缺失值先SimpleImputer再缩放多步串联Transform.fit(...)管道列式缩放器横向对比给定一列值{1, 2, 3, 100}其中100是离群值变换123100Scaler0.0000.0100.0201.000Standardizer(μ≈26.5, σ≈48.0)−0.53−0.51−0.491.53RobustStandardizer(med2.5, IQR≈1.5)−1.00−0.330.3365.0WinsorScaler(5/95 pct)0.0000.5001.0001.000MaxAbsScaler(max100)0.0100.0200.0301.000Scaler因离群值把{1,2,3}压缩到接近 0WinsorScaler钳制离群值后让{1,2,3}在[0,1]内均匀铺开RobustStandardizer对离群值稳健但其输出无界。14. API 速查表Transform接口 —smile.data.transform成员说明apply(Tuple)变换一行抽象方法。apply(DataFrame)变换全部行默认逐行流式ColumnTransform覆写为列并行批量。andThen(Transform)组合先this后after。compose(Transform)组合先before后this。Transform.pipeline(Transform...)从左到右串联多个变换空输入抛异常。Transform.fit(DataFrame, FunctionDataFrame,Transform...)拟合数据依赖管道每个 trainer 看到已被前序步骤变换的数据空输入抛异常。InvertibleTransform接口 —smile.data.transform成员说明invert(Tuple)逆变换一行。invert(DataFrame)逆变换全部行保留可空列。ColumnTransform类 —smile.data.transform成员说明ColumnTransform(String name, MapString,Function transforms)构造函数。apply(Tuple)对匹配列套用 lambda其余列透传。apply(DataFrame)列并行批量变换保留空值掩码。toString()name(\n fn, ...\n)InvertibleColumnTransform类 —smile.data.transform成员说明InvertibleColumnTransform(String, MapString,Function, MapString,Function)构造函数名称、正向 lambdas、逆 lambdas。invert(Tuple)套用逆 lambdas未匹配列透传。invert(DataFrame)列并行求逆保留空值掩码。内置缩放器均在smile.feature.transform类工厂方法公式可逆ScalerScaler.fit(data, cols...)(x−min)/(max−min)钳制到[0,1]是StandardizerStandardizer.fit(data, cols...)(x−μ)/σ是RobustStandardizerRobustStandardizer.fit(data, cols...)(x−median)/IQR是WinsorScalerWinsorScaler.fit(data)或fit(data, lo, hi, cols...)先钳制再(x−pLo)/(pHi−pLo)是MaxAbsScalerMaxAbsScaler.fit(data, cols...)x / max(|x|)是Normalizernew Normalizer(Norm, cols...)逐行单位范数L1/L2/L∞否所有列式fit()方法均接受可选的可变String... columns参数省略时自动变换全部数值列。附源码级验证线索接口与实现Transform/InvertibleTransform/ColumnTransform/InvertibleColumnTransform见 base/src/main/java/smile/data/transform内置缩放器Scaler、Standardizer、RobustStandardizer、WinsorScaler、MaxAbsScaler、Normalizer见 core/src/main/java/smile/feature/transform单元测试基于 ImageSegmentation 数据集的六种变换数值断言见 FeatureTransformTest.java常数列回退缩放、子集列变换、空 DataFrame 与非数值列异常等边界用例见 FeatureTransformEdgeCaseTest.javaNormalizer专项测试见 NormalizerTest.java。从上述源码与测试可以确认所有列式缩放器在常数列/全零列上都会把缩放因子回退为1.0以避免除零fit在空 DataFrame 上抛IllegalArgumentException(Empty data frame)指定非数值列抛col is not numeric——这些边界行为已被 FeatureTransformEdgeCaseTest.java 直接断言可作为生产代码中的防御性参考。赞分享人工智能机器学习深度学习NLP大模型模型推理服务数据可视化【免费下载链接】smileStatistical Machine Intelligence Learning Engine项目地址https://gitcode.com/gh_mirrors/smi/smile点击查看免费下载相关推荐sktime数据转换与特征工程时间序列预处理sktime数据转换与特征工程时间序列预处理 本文全面介绍了sktime库在时间序列数据预处理和特征工程方面的强大功能。内容涵盖从基础数据转换标准化、差分、机器学习人工智能数据分析Higgs TTS v3-4b vs 竞品四大权威 benchmark 全面领先的关键解析Higgs TTS v3 4b vs 竞品四大权威 benchmark 全面领先的关键解析 在当今快速发展的AI语音合成领域 Higgs TTS v3 4brequests库文件上传功能Multipart请求实现详解requests库文件上传功能Multipart请求实现详解 在网络开发中文件上传是常见的功能需求而Multipart请求是实现这一功能的标准方式。 re上一篇Visual C运行库修复一站式解决Windows软件兼容性问题下一篇3步解锁iOS设备applera1n开源工具实现激活锁完美绕过创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考