MaxAbsScalerTrainer implements PreprocessingTrainer<K, V> { @Override public MaxAbsScalerPreprocessor<K, V> fit( LearningEnvironmentBuilder envBuilder, DatasetBuilder<K, V> datasetBuilder, Preprocessor<K, V> basePreprocessor) { try (Dataset<EmptyContext, MaxAbsScalerPartitionData> dataset = datasetBuilder.build( envBuilder, (env, upstream, upstreamSize) -> new EmptyContext(), (env, upstream, upstreamSize, ctx) -> { double[] maxAbs = null; while (upstream.hasNext()) { UpstreamEntry<K, V> entity = upstream.next(); LabeledVector row = basePreprocessor.apply(entity.getKey(), entity.getValue()); if (maxAbs == null) { maxAbs = new double[row.size()]; for (int i = 0; i < maxAbs.length; i++) maxAbs[i] = .0; } else assert maxAbs.length == row.size() : "Base preprocessor must return exactly " + maxAbs.length + " features"; for (int i = 0; i < row.size(); i++) { if (Math.abs(row.get(i)) > Math.abs(maxAbs[i])) maxAbs[i] = Math.abs(row.get(i)); } } return new MaxAbsScalerPartitionData(maxAbs); }, learningEnvironment(basePreprocessor) )) { double[] maxAbs = dataset.compute(MaxAbsScalerPartitionData::getMaxAbs, (a, b) -> { if (a == null) return b; if (b == null) return a; double[] res = new double[a.length]; for (int i = 0; i < res.length; i++) res[i] = Math.max(Math.abs(a[i]), Math.abs(b[i])); return res; }); return new MaxAbsScalerPreprocessor<>(maxAbs, basePreprocessor); } catch (Exception e) { throw new RuntimeException(e); } }  @Override MaxAbsScalerPreprocessor<K, V> fit(
        LearningEnvironmentBuilder envBuilder,
        DatasetBuilder<K, V> datasetBuilder,
        Preprocessor<K, V> basePreprocessor);  }
@Test public void testFit() { Map<Integer, Vector> data = new HashMap<>(); data.put(1, VectorUtils.of(2, -4, 1)); data.put(2, VectorUtils.of(1, -8, 22)); data.put(3, VectorUtils.of(-4, 10, 100)); data.put(4, VectorUtils.of(0, 22, 300)); DatasetBuilder<Integer, Vector> datasetBuilder = new LocalDatasetBuilder<>(data, parts); final Vectorizer<Integer, Vector, Integer, Double> vectorizer = new DummyVectorizer<>(0, 1, 2); MaxAbsScalerTrainer<Integer, Vector> standardizationTrainer = new MaxAbsScalerTrainer<>(); MaxAbsScalerPreprocessor<Integer, Vector> preprocessor = standardizationTrainer.fit( TestUtils.testEnvBuilder(), datasetBuilder, vectorizer ); assertArrayEquals(new double[] {4, 22, 300}, preprocessor.getMaxAbs(), 1e-8); }