| 1 | /*
|
|---|
| 2 | * Copyright (c) Numerical Method Inc.
|
|---|
| 3 | * http://www.numericalmethod.com/
|
|---|
| 4 | *
|
|---|
| 5 | * THIS SOFTWARE IS LICENSED, NOT SOLD.
|
|---|
| 6 | *
|
|---|
| 7 | * YOU MAY USE THIS SOFTWARE ONLY AS DESCRIBED IN THE LICENSE.
|
|---|
| 8 | * IF YOU ARE NOT AWARE OF AND/OR DO NOT AGREE TO THE TERMS OF THE LICENSE,
|
|---|
| 9 | * DO NOT USE THIS SOFTWARE.
|
|---|
| 10 | *
|
|---|
| 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITH NO WARRANTY WHATSOEVER,
|
|---|
| 12 | * EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
|
|---|
| 13 | * ANY WARRANTIES OF ACCURACY, ACCESSIBILITY, COMPLETENESS,
|
|---|
| 14 | * FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, NON-INFRINGEMENT,
|
|---|
| 15 | * TITLE AND USEFULNESS.
|
|---|
| 16 | *
|
|---|
| 17 | * IN NO EVENT AND UNDER NO LEGAL THEORY,
|
|---|
| 18 | * WHETHER IN ACTION, CONTRACT, NEGLIGENCE, TORT, OR OTHERWISE,
|
|---|
| 19 | * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|---|
| 20 | * ANY CLAIMS, DAMAGES OR OTHER LIABILITIES,
|
|---|
| 21 | * ARISING AS A RESULT OF USING OR OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 22 | */
|
|---|
| 23 | package com.numericalmethod.suanshu.examples;
|
|---|
| 24 |
|
|---|
| 25 | import com.numericalmethod.suanshu.algebra.linear.matrix.doubles.Matrix;
|
|---|
| 26 | import com.numericalmethod.suanshu.algebra.linear.matrix.doubles.matrixtype.dense.DenseMatrix;
|
|---|
| 27 | import com.numericalmethod.suanshu.algebra.linear.vector.doubles.Vector;
|
|---|
| 28 | import com.numericalmethod.suanshu.algebra.linear.vector.doubles.dense.DenseVector;
|
|---|
| 29 | import com.numericalmethod.suanshu.stats.regression.linear.LMProblem;
|
|---|
| 30 | import com.numericalmethod.suanshu.stats.regression.linear.glm.GLMProblem;
|
|---|
| 31 | import com.numericalmethod.suanshu.stats.regression.linear.glm.GeneralizedLinearModel;
|
|---|
| 32 | import com.numericalmethod.suanshu.stats.regression.linear.glm.distribution.GLMFamily;
|
|---|
| 33 | import com.numericalmethod.suanshu.stats.regression.linear.glm.distribution.GLMPoisson;
|
|---|
| 34 | import com.numericalmethod.suanshu.stats.regression.linear.glm.quasi.GeneralizedLinearModelQuasiFamily;
|
|---|
| 35 | import com.numericalmethod.suanshu.stats.regression.linear.glm.quasi.QuasiGLMProblem;
|
|---|
| 36 | import com.numericalmethod.suanshu.stats.regression.linear.glm.quasi.family.QuasiFamily;
|
|---|
| 37 | import com.numericalmethod.suanshu.stats.regression.linear.glm.quasi.family.QuasiGamma;
|
|---|
| 38 | import com.numericalmethod.suanshu.stats.regression.linear.logistic.LogisticRegression;
|
|---|
| 39 | import com.numericalmethod.suanshu.stats.regression.linear.ols.*;
|
|---|
| 40 | import com.numericalmethod.suanshu.stats.regression.linear.residualanalysis.LMDiagnostics;
|
|---|
| 41 | import com.numericalmethod.suanshu.stats.regression.linear.residualanalysis.LMInformationCriteria;
|
|---|
| 42 |
|
|---|
| 43 | /**
|
|---|
| 44 | * Demonstrates how to do Ordinary Least Square regression in Java using SuanShu.
|
|---|
| 45 | *
|
|---|
| 46 | * @author Haksun Li
|
|---|
| 47 | */
|
|---|
| 48 | public final class LinearRegression {
|
|---|
| 49 |
|
|---|
| 50 | private LinearRegression() {
|
|---|
| 51 | }
|
|---|
| 52 | /**
|
|---|
| 53 | * The matrix of factor values used for OLS.
|
|---|
| 54 | */
|
|---|
| 55 | public static final Matrix TEST_X1 =
|
|---|
| 56 | new DenseMatrix(new double[][]{
|
|---|
| 57 | {1.52, 2.23, 4.31},
|
|---|
| 58 | {3.22, 6.34, 3.46},
|
|---|
| 59 | {4.32, 12.2, 23.1},
|
|---|
| 60 | {10.1034, 43.2, 22.3},
|
|---|
| 61 | {12.1, 2.12, 3.27}
|
|---|
| 62 | });
|
|---|
| 63 | /**
|
|---|
| 64 | * The vector of dependent variables used for OLS.
|
|---|
| 65 | */
|
|---|
| 66 | public static final Vector TEST_Y1 =
|
|---|
| 67 | new DenseVector(new double[]{2.32, 0.452, 4.53, 12.34, 32.2});
|
|---|
| 68 | /**
|
|---|
| 69 | * The vector of weights used for testing.
|
|---|
| 70 | */
|
|---|
| 71 | public static final Vector TEST_W = new DenseVector(new double[]{0.2, 0.4, 0.1, 0.3, 0.1});
|
|---|
| 72 | /**
|
|---|
| 73 | * The matrix of factor values used for GLM.
|
|---|
| 74 | */
|
|---|
| 75 | public static final Matrix TEST_X2 =
|
|---|
| 76 | new DenseMatrix(new double[][]{
|
|---|
| 77 | {1.52, 2.11},
|
|---|
| 78 | {3.22, 4.32},
|
|---|
| 79 | {4.32, 1.23},
|
|---|
| 80 | {10.1034, 8.43},
|
|---|
| 81 | {12.1, 7.31}
|
|---|
| 82 | });
|
|---|
| 83 | /**
|
|---|
| 84 | * The vector of dependent variables used for GLM.
|
|---|
| 85 | */
|
|---|
| 86 | public static final Vector TEST_Y2 = new DenseVector(new double[]{2, 1, 4, 5, 7});
|
|---|
| 87 |
|
|---|
| 88 | /**
|
|---|
| 89 | * Showcases different types of regressions implemented in SuanShu.
|
|---|
| 90 | *
|
|---|
| 91 | * @param args not used
|
|---|
| 92 | * @throws Exception if an error occurs during a regression
|
|---|
| 93 | */
|
|---|
| 94 | public static void main(String[] args) throws Exception {
|
|---|
| 95 | System.out.println("This class demonstrates how to do Ordinary Least Square regression in"
|
|---|
| 96 | + " Java using SuanShu.");
|
|---|
| 97 |
|
|---|
| 98 | olsEqualWeight(TEST_X1, TEST_Y1, true);
|
|---|
| 99 | System.out.println();
|
|---|
| 100 | olsWeighted(TEST_X1, TEST_Y1, TEST_W, true);
|
|---|
| 101 |
|
|---|
| 102 | System.out.println();
|
|---|
| 103 | glm(TEST_X2, TEST_Y2, true, new GLMFamily(new GLMPoisson()));
|
|---|
| 104 |
|
|---|
| 105 | System.out.println();
|
|---|
| 106 | quasiGLM(TEST_X2, TEST_Y2, true, new QuasiFamily(
|
|---|
| 107 | new com.numericalmethod.suanshu.stats.regression.linear.glm.quasi.family.QuasiPoisson()));
|
|---|
| 108 | quasiGLM(new DenseMatrix(new double[][]{{1.52}, {3.22}, {4.32}, {10.1034}, {12.1}}),
|
|---|
| 109 | new DenseVector(new double[]{1.3, 2.4, 0.4, 2, 5.2}),
|
|---|
| 110 | true,
|
|---|
| 111 | new QuasiFamily(new QuasiGamma()));
|
|---|
| 112 |
|
|---|
| 113 | System.out.println();
|
|---|
| 114 | logistic(new DenseMatrix(new double[][]{
|
|---|
| 115 | {1.52},
|
|---|
| 116 | {3.22},
|
|---|
| 117 | {4.32},
|
|---|
| 118 | {10.1034},
|
|---|
| 119 | {12.1}
|
|---|
| 120 | }), new DenseVector(new double[]{0, 1, 0, 1, 1}), true);
|
|---|
| 121 | }
|
|---|
| 122 |
|
|---|
| 123 | /**
|
|---|
| 124 | * Runs an OLS regression on the given data, where all observations are given equal weight.
|
|---|
| 125 | *
|
|---|
| 126 | * @param x the factor values
|
|---|
| 127 | * @param y the dependent variable values
|
|---|
| 128 | * @param intercept whether an intercept should be used as part of the regression.
|
|---|
| 129 | */
|
|---|
| 130 | public static void olsEqualWeight(Matrix x, Vector y, boolean intercept) {
|
|---|
| 131 | LMProblem problem = new LMProblem(y, x, intercept);
|
|---|
| 132 |
|
|---|
| 133 | printOLSResults(problem);
|
|---|
| 134 | }
|
|---|
| 135 |
|
|---|
| 136 | /**
|
|---|
| 137 | * Performs an OLS regression on the given problem and prints the results, as well as various
|
|---|
| 138 | * statistics.
|
|---|
| 139 | *
|
|---|
| 140 | * @param problem the OLS problem on which to perform the regression
|
|---|
| 141 | */
|
|---|
| 142 | public static void printOLSResults(LMProblem problem) {
|
|---|
| 143 | OLSRegression ols = new OLSRegression(problem);
|
|---|
| 144 | OLSResiduals olsResiduals = ols.residuals();
|
|---|
| 145 |
|
|---|
| 146 | System.out.printf("beta hat: %s,%nstderr: %s,%nt: %s,%nresiduals: %s%n",
|
|---|
| 147 | ols.beta().betaHat(), ols.beta().stderr(), ols.beta().t(),
|
|---|
| 148 | olsResiduals.residuals());
|
|---|
| 149 |
|
|---|
| 150 | System.out.printf("R2: %f, AR2: %f, standard error: %f, f: %f%n",
|
|---|
| 151 | olsResiduals.R2(), olsResiduals.AR2(), olsResiduals.stderr(),
|
|---|
| 152 | olsResiduals.Fstat());
|
|---|
| 153 |
|
|---|
| 154 | System.out.printf("fitted values: %s%n", olsResiduals.fitted());
|
|---|
| 155 | System.out.printf("leverage: %s%n", olsResiduals.leverage());
|
|---|
| 156 | System.out.printf("standardized residuals: %s%n", olsResiduals.standardized());
|
|---|
| 157 | System.out.printf("studentized residuals: %s%n", olsResiduals.studentized());
|
|---|
| 158 |
|
|---|
| 159 | System.out.printf("sum of squared residuals: %s%n", olsResiduals.RSS());
|
|---|
| 160 | System.out.printf("total sum of squares: %f%n", olsResiduals.TSS());
|
|---|
| 161 |
|
|---|
| 162 | System.out.println();
|
|---|
| 163 | LMDiagnostics olsDiagnostics = ols.diagnostics();
|
|---|
| 164 |
|
|---|
| 165 | System.out.printf("DFFITS (Welsch and Kuh measure): %s%n", olsDiagnostics.DFFITS());
|
|---|
| 166 | System.out.printf("Hadi: %s%n", olsDiagnostics.Hadi());
|
|---|
| 167 | System.out.printf("Cook distance: %s%n", olsDiagnostics.cookDistances());
|
|---|
| 168 |
|
|---|
| 169 |
|
|---|
| 170 | LMInformationCriteria olsInformationCriteria = ols.informationCriteria();
|
|---|
| 171 |
|
|---|
| 172 | System.out.printf("Akaike information criterion: %f%n", olsInformationCriteria.AIC());
|
|---|
| 173 | System.out.printf("Bayesian information criterion: %f%n", olsInformationCriteria.BIC());
|
|---|
| 174 | }
|
|---|
| 175 |
|
|---|
| 176 | /**
|
|---|
| 177 | * Runs an OLS regression on the given data, where observations are given the weight specified
|
|---|
| 178 | * in the given vector.
|
|---|
| 179 | *
|
|---|
| 180 | * @param x the factor values
|
|---|
| 181 | * @param y the dependent variable values
|
|---|
| 182 | * @param w the weight given to the observations
|
|---|
| 183 | * @param intercept whether an intercept should be used as part of the regression.
|
|---|
| 184 | */
|
|---|
| 185 | public static void olsWeighted(Matrix x, Vector y, Vector w, boolean intercept) {
|
|---|
| 186 | LMProblem problem = new LMProblem(y, x, intercept, w);
|
|---|
| 187 | printOLSResults(problem);
|
|---|
| 188 | }
|
|---|
| 189 |
|
|---|
| 190 | /**
|
|---|
| 191 | * Runs a GLM regression on the given data, with the given link function (family).
|
|---|
| 192 | *
|
|---|
| 193 | * @param x the factor values
|
|---|
| 194 | * @param y the dependent variable values
|
|---|
| 195 | * @param intercept whether an intercept should be used as part of the regression
|
|---|
| 196 | * @param family the link function
|
|---|
| 197 | */
|
|---|
| 198 | public static void glm(Matrix x, Vector y, boolean intercept, GLMFamily family) {
|
|---|
| 199 | GLMProblem problem = new GLMProblem(y, x, true, family);
|
|---|
| 200 | GeneralizedLinearModel glm = new GeneralizedLinearModel(problem);
|
|---|
| 201 |
|
|---|
| 202 |
|
|---|
| 203 | System.out.printf("beta hat: %s,%nstderr: %s,%nt: %s%n",
|
|---|
| 204 | glm.beta().betaHat(), glm.beta().stderr(), glm.beta().t());
|
|---|
| 205 |
|
|---|
| 206 | System.out.printf("fitted values: %s%n", glm.residuals().fitted());
|
|---|
| 207 | System.out.printf("deviance residuals: %s%n", glm.residuals().devianceResiduals());
|
|---|
| 208 | System.out.printf("deviance: %f, overdispersion: %f, AIC: %f%n",
|
|---|
| 209 | glm.residuals().deviance(), glm.residuals().overdispersion(), glm.AIC());
|
|---|
| 210 | }
|
|---|
| 211 |
|
|---|
| 212 | /**
|
|---|
| 213 | * Runs a GLM regression on the given data, estimating beta with quasi-likelihood estimators
|
|---|
| 214 | * from the given family.
|
|---|
| 215 | *
|
|---|
| 216 | * @param x the factor values
|
|---|
| 217 | * @param y the dependent variable values
|
|---|
| 218 | * @param intercept whether an intercept should be used as part of the regression
|
|---|
| 219 | * @param family the family
|
|---|
| 220 | */
|
|---|
| 221 | public static void quasiGLM(Matrix x, Vector y, boolean intercept, QuasiFamily family) {
|
|---|
| 222 | GeneralizedLinearModelQuasiFamily quasi = new GeneralizedLinearModelQuasiFamily(
|
|---|
| 223 | new QuasiGLMProblem(y, x, intercept, family));
|
|---|
| 224 | System.out.printf("beta hat: %s,%nstderr: %s,%nt: %s%n",
|
|---|
| 225 | quasi.beta().betaHat(), quasi.beta().stderr(), quasi.beta().t());
|
|---|
| 226 |
|
|---|
| 227 | System.out.printf("fitted values: %s%n", quasi.residuals().fitted());
|
|---|
| 228 | System.out.printf("deviance residuals: %s%n", quasi.residuals().devianceResiduals());
|
|---|
| 229 | System.out.printf("deviance: %f, overdispersion: %f%n",
|
|---|
| 230 | quasi.residuals().deviance(), quasi.residuals().overdispersion());
|
|---|
| 231 | }
|
|---|
| 232 |
|
|---|
| 233 | /**
|
|---|
| 234 | * Runs a logistic regression on the given data.
|
|---|
| 235 | *
|
|---|
| 236 | * @param x the factor values
|
|---|
| 237 | * @param y the dependent variable values
|
|---|
| 238 | * @param intercept whether an intercept should be used as part of the regression
|
|---|
| 239 | * @throws Exception thrown if an error occurs during the regression
|
|---|
| 240 | */
|
|---|
| 241 | public static void logistic(DenseMatrix x, DenseVector y, boolean intercept) throws Exception {
|
|---|
| 242 | com.numericalmethod.suanshu.stats.regression.linear.LMProblem problem =
|
|---|
| 243 | new com.numericalmethod.suanshu.stats.regression.linear.LMProblem(y, x, true);
|
|---|
| 244 | LogisticRegression logistic = new LogisticRegression(problem);
|
|---|
| 245 | System.out.printf("beta hat: %s,%nstderr: %s,%nt: %s%n",
|
|---|
| 246 | logistic.beta().betaHat(), logistic.beta().stderr(), logistic.beta().t());
|
|---|
| 247 |
|
|---|
| 248 | System.out.printf("fitted values: %s%n", logistic.residuals().fitted());
|
|---|
| 249 | }
|
|---|
| 250 | }
|
|---|