class StandardScalerTrainer implements PreprocessingTrainer<K, V> {

    @Override public StandardScalerPreprocessor<K, V> fit(LearningEnvironmentBuilder envBuilder,
        DatasetBuilder<K, V> datasetBuilder,
        Preprocessor<K, V> basePreprocessor) {
        StandardScalerData standardScalerData = computeSum(envBuilder, datasetBuilder, basePreprocessor);

        int n = standardScalerData.sum.length;
        long cnt = standardScalerData.cnt;
        double[] mean = new double[n];
        double[] sigma = new double[n];

        for (int i = 0; i < n; i++) {
            mean[i] = standardScalerData.sum[i] / cnt;
            double variance = (standardScalerData.squaredSum[i] - Math.pow(standardScalerData.sum[i], 2) / cnt) / cnt;
            sigma[i] = Math.sqrt(variance);
        }
        return new StandardScalerPreprocessor<>(mean, sigma, basePreprocessor);
    }

}