SpearmansCorrelation.java
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * This is not the original file distributed by the Apache Software Foundation
- * It has been modified by the Hipparchus project
- */
- package org.hipparchus.stat.correlation;
- import org.hipparchus.exception.LocalizedCoreFormats;
- import org.hipparchus.exception.MathIllegalArgumentException;
- import org.hipparchus.linear.BlockRealMatrix;
- import org.hipparchus.linear.RealMatrix;
- import org.hipparchus.stat.LocalizedStatFormats;
- import org.hipparchus.stat.ranking.NaNStrategy;
- import org.hipparchus.stat.ranking.NaturalRanking;
- import org.hipparchus.stat.ranking.RankingAlgorithm;
- import org.hipparchus.util.MathArrays;
- /**
- * Spearman's rank correlation. This implementation performs a rank
- * transformation on the input data and then computes {@link PearsonsCorrelation}
- * on the ranked data.
- * <p>
- * By default, ranks are computed using {@link NaturalRanking} with default
- * strategies for handling NaNs and ties in the data (NaNs maximal, ties averaged).
- * The ranking algorithm can be set using a constructor argument.
- */
- public class SpearmansCorrelation {
- /** Input data */
- private final RealMatrix data;
- /** Ranking algorithm */
- private final RankingAlgorithm rankingAlgorithm;
- /** Rank correlation */
- private final PearsonsCorrelation rankCorrelation;
- /**
- * Create a SpearmansCorrelation without data.
- */
- public SpearmansCorrelation() {
- this(new NaturalRanking());
- }
- /**
- * Create a SpearmansCorrelation with the given ranking algorithm.
- *
- * @param rankingAlgorithm ranking algorithm
- * @throws MathIllegalArgumentException if the provided {@link RankingAlgorithm} is of
- * type {@link NaturalRanking} and uses a {@link NaNStrategy#REMOVED} strategy
- */
- public SpearmansCorrelation(final RankingAlgorithm rankingAlgorithm)
- throws MathIllegalArgumentException {
- if (rankingAlgorithm instanceof NaturalRanking &&
- NaNStrategy.REMOVED == ((NaturalRanking) rankingAlgorithm).getNanStrategy()) {
- throw new MathIllegalArgumentException(LocalizedStatFormats.NOT_SUPPORTED_NAN_STRATEGY,
- NaNStrategy.REMOVED);
- }
- data = null;
- this.rankingAlgorithm = rankingAlgorithm;
- rankCorrelation = null;
- }
- /**
- * Create a SpearmansCorrelation from the given data matrix.
- *
- * @param dataMatrix matrix of data with columns representing
- * variables to correlate
- */
- public SpearmansCorrelation(final RealMatrix dataMatrix) {
- this(dataMatrix, new NaturalRanking());
- }
- /**
- * Create a SpearmansCorrelation with the given input data matrix
- * and ranking algorithm.
- *
- * @param dataMatrix matrix of data with columns representing
- * variables to correlate
- * @param rankingAlgorithm ranking algorithm
- * @throws MathIllegalArgumentException if the provided {@link RankingAlgorithm} is of
- * type {@link NaturalRanking} and uses a {@link NaNStrategy#REMOVED} strategy
- */
- public SpearmansCorrelation(final RealMatrix dataMatrix, final RankingAlgorithm rankingAlgorithm)
- throws MathIllegalArgumentException {
- if (rankingAlgorithm instanceof NaturalRanking &&
- NaNStrategy.REMOVED == ((NaturalRanking) rankingAlgorithm).getNanStrategy()) {
- throw new MathIllegalArgumentException(LocalizedStatFormats.NOT_SUPPORTED_NAN_STRATEGY,
- NaNStrategy.REMOVED);
- }
- this.rankingAlgorithm = rankingAlgorithm;
- this.data = rankTransform(dataMatrix);
- rankCorrelation = new PearsonsCorrelation(data);
- }
- /**
- * Calculate the Spearman Rank Correlation Matrix.
- *
- * @return Spearman Rank Correlation Matrix
- * @throws NullPointerException if this instance was created with no data
- */
- public RealMatrix getCorrelationMatrix() {
- return rankCorrelation.getCorrelationMatrix();
- }
- /**
- * Returns a {@link PearsonsCorrelation} instance constructed from the
- * ranked input data. That is,
- * <code>new SpearmansCorrelation(matrix).getRankCorrelation()</code>
- * is equivalent to
- * <code>new PearsonsCorrelation(rankTransform(matrix))</code> where
- * <code>rankTransform(matrix)</code> is the result of applying the
- * configured <code>RankingAlgorithm</code> to each of the columns of
- * <code>matrix.</code>
- *
- * <p>Returns null if this instance was created with no data.</p>
- *
- * @return PearsonsCorrelation among ranked column data
- */
- public PearsonsCorrelation getRankCorrelation() {
- return rankCorrelation;
- }
- /**
- * Computes the Spearman's rank correlation matrix for the columns of the
- * input matrix.
- *
- * @param matrix matrix with columns representing variables to correlate
- * @return correlation matrix
- */
- public RealMatrix computeCorrelationMatrix(final RealMatrix matrix) {
- final RealMatrix matrixCopy = rankTransform(matrix);
- return new PearsonsCorrelation().computeCorrelationMatrix(matrixCopy);
- }
- /**
- * Computes the Spearman's rank correlation matrix for the columns of the
- * input rectangular array. The columns of the array represent values
- * of variables to be correlated.
- *
- * @param matrix matrix with columns representing variables to correlate
- * @return correlation matrix
- */
- public RealMatrix computeCorrelationMatrix(final double[][] matrix) {
- return computeCorrelationMatrix(new BlockRealMatrix(matrix));
- }
- /**
- * Computes the Spearman's rank correlation coefficient between the two arrays.
- *
- * @param xArray first data array
- * @param yArray second data array
- * @return Returns Spearman's rank correlation coefficient for the two arrays
- * @throws MathIllegalArgumentException if the arrays lengths do not match
- * @throws MathIllegalArgumentException if the array length is less than 2
- */
- public double correlation(final double[] xArray, final double[] yArray) {
- MathArrays.checkEqualLength(xArray, yArray);
- if (xArray.length < 2) {
- throw new MathIllegalArgumentException(LocalizedCoreFormats.INSUFFICIENT_DIMENSION,
- xArray.length, 2);
- }
- return new PearsonsCorrelation().correlation(rankingAlgorithm.rank(xArray),
- rankingAlgorithm.rank(yArray));
- }
- /**
- * Applies rank transform to each of the columns of <code>matrix</code>
- * using the current <code>rankingAlgorithm</code>.
- *
- * @param matrix matrix to transform
- * @return a rank-transformed matrix
- */
- private RealMatrix rankTransform(final RealMatrix matrix) {
- RealMatrix transformed = matrix.copy();
- for (int i = 0; i < transformed.getColumnDimension(); i++) {
- transformed.setColumn(i, rankingAlgorithm.rank(transformed.getColumn(i)));
- }
- return transformed;
- }
- }