public static SumSquaresRatio[] fit(DataFrame data, String clazz) {
        BaseVector<?, ?, ?> y = data.column(clazz);
        ClassLabels codec = ClassLabels.fit(y);

        if (codec.k < 2) {
            throw new UnsupportedOperationException("Invalid number of classes: " + codec.k);
        }

        int n = data.nrow();
        int k = codec.k;
        int[] nc = new int[k];
        double[] condmu = new double[k];

        for (int i = 0; i < n; i++) {
            int yi = codec.y[i];
            nc[yi]++;
        }

        StructType schema = data.schema();

        return IntStream.range(0, schema.length()).mapToObj(j -> {
            StructField field = schema.field(j);
            if (field.isNumeric()) {
                BaseVector<?, ?, ?> xj = data.column(j);
                double mu = 0.0;
                Arrays.fill(condmu, 0.0);
                for (int i = 0; i < n; i++) {
                    int yi = codec.y[i];
                    double xij = xj.getDouble(i);
                    mu += xij;
                    condmu[yi] += xij;
                }

                mu /= n;
                for (int i = 0; i < k; i++) {
                    condmu[i] /= nc[i];
                }

                double wss = 0.0;
                double bss = 0.0;

                for (int i = 0; i < n; i++) {
                    int yi = codec.y[i];
                    double xij = xj.getDouble(i);
                    bss += MathEx.pow2(condmu[yi] - mu);
                    wss += MathEx.pow2(xij - condmu[yi]);
                }

                return new SumSquaresRatio(field.name, bss / wss);
            } else {
                return null;
            }
        }).filter(s2n -> s2n != null && !s2n.feature.equals(clazz)).toArray(SumSquaresRatio[]::new);
    }
@Test
    public void tesUSPS() {
        System.out.println("USPS");

        SumSquaresRatio[] score = SumSquaresRatio.fit(USPS.train, "class");
        Arrays.sort(score);
        String[] columns = Arrays.stream(score).limit(121).map(s -> s.feature).toArray(String[]::new);

        double[][] train = USPS.formula.x(USPS.train.drop(columns)).toArray();
        LDA lda = LDA.fit(train, USPS.y);

        double[][] test = USPS.formula.x(USPS.test.drop(columns)).toArray();
        int[] prediction = lda.predict(test);

        double accuracy = new Accuracy().score(USPS.testy, prediction);
        System.out.format("SSR %.2f%%%n", 100 * accuracy);
        assertEquals(0.86, accuracy, 1E-2);
    }