time-to-botec/squiggle/node_modules/jstat/src/regression.js
NunoSempere b6addc7f05 feat: add the node modules
Necessary in order to clearly see the squiggle hotwiring.
2022-12-03 12:44:49 +00:00

207 lines
5.4 KiB
JavaScript

//To regress, simply build X matrix
//(append column of 1's) using
//buildxmatrix and build the Y
//matrix using buildymatrix
//(simply the transpose)
//and run regress.
//Regressions
jStat.extend({
buildxmatrix: function buildxmatrix(){
//Parameters will be passed in as such
//(array1,array2,array3,...)
//as (x1,x2,x3,...)
//needs to be (1,x1,x2,x3,...)
var matrixRows = new Array(arguments.length);
for(var i=0;i<arguments.length;i++){
var array = [1];
matrixRows[i]= array.concat(arguments[i]);
}
return jStat(matrixRows);
},
builddxmatrix: function builddxmatrix() {
//Paramters will be passed in as such
//([array1,array2,...]
var matrixRows = new Array(arguments[0].length);
for(var i=0;i<arguments[0].length;i++){
var array = [1]
matrixRows[i]= array.concat(arguments[0][i]);
}
return jStat(matrixRows);
},
buildjxmatrix: function buildjxmatrix(jMat) {
//Builds from jStat Matrix
var pass = new Array(jMat.length)
for(var i=0;i<jMat.length;i++){
pass[i] = jMat[i];
}
return jStat.builddxmatrix(pass);
},
buildymatrix: function buildymatrix(array){
return jStat(array).transpose();
},
buildjymatrix: function buildjymatrix(jMat){
return jMat.transpose();
},
matrixmult: function matrixmult(A,B){
var i, j, k, result, sum;
if (A.cols() == B.rows()) {
if(B.rows()>1){
result = [];
for (i = 0; i < A.rows(); i++) {
result[i] = [];
for (j = 0; j < B.cols(); j++) {
sum = 0;
for (k = 0; k < A.cols(); k++) {
sum += A.toArray()[i][k] * B.toArray()[k][j];
}
result[i][j] = sum;
}
}
return jStat(result);
}
result = [];
for (i = 0; i < A.rows(); i++) {
result[i] = [];
for (j = 0; j < B.cols(); j++) {
sum = 0;
for (k = 0; k < A.cols(); k++) {
sum += A.toArray()[i][k] * B.toArray()[j];
}
result[i][j] = sum;
}
}
return jStat(result);
}
},
//regress and regresst to be fixed
regress: function regress(jMatX,jMatY){
//print("regressin!");
//print(jMatX.toArray());
var innerinv = jStat.xtranspxinv(jMatX);
//print(innerinv);
var xtransp = jMatX.transpose();
var next = jStat.matrixmult(jStat(innerinv),xtransp);
return jStat.matrixmult(next,jMatY);
},
regresst: function regresst(jMatX,jMatY,sides){
var beta = jStat.regress(jMatX,jMatY);
var compile = {};
compile.anova = {};
var jMatYBar = jStat.jMatYBar(jMatX, beta);
compile.yBar = jMatYBar;
var yAverage = jMatY.mean();
compile.anova.residuals = jStat.residuals(jMatY, jMatYBar);
compile.anova.ssr = jStat.ssr(jMatYBar, yAverage);
compile.anova.msr = compile.anova.ssr / (jMatX[0].length - 1);
compile.anova.sse = jStat.sse(jMatY, jMatYBar);
compile.anova.mse =
compile.anova.sse / (jMatY.length - (jMatX[0].length - 1) - 1);
compile.anova.sst = jStat.sst(jMatY, yAverage);
compile.anova.mst = compile.anova.sst / (jMatY.length - 1);
compile.anova.r2 = 1 - (compile.anova.sse / compile.anova.sst);
if (compile.anova.r2 < 0) compile.anova.r2 = 0;
compile.anova.fratio = compile.anova.msr / compile.anova.mse;
compile.anova.pvalue =
jStat.anovaftest(compile.anova.fratio,
jMatX[0].length - 1,
jMatY.length - (jMatX[0].length - 1) - 1);
compile.anova.rmse = Math.sqrt(compile.anova.mse);
compile.anova.r2adj = 1 - (compile.anova.mse / compile.anova.mst);
if (compile.anova.r2adj < 0) compile.anova.r2adj = 0;
compile.stats = new Array(jMatX[0].length);
var covar = jStat.xtranspxinv(jMatX);
var sds, ts, ps;
for(var i=0; i<beta.length;i++){
sds=Math.sqrt(compile.anova.mse * Math.abs(covar[i][i]));
ts= Math.abs(beta[i] / sds);
ps= jStat.ttest(ts, jMatY.length - jMatX[0].length - 1, sides);
compile.stats[i]=[beta[i], sds, ts, ps];
}
compile.regress = beta;
return compile;
},
xtranspx: function xtranspx(jMatX){
return jStat.matrixmult(jMatX.transpose(),jMatX);
},
xtranspxinv: function xtranspxinv(jMatX){
var inner = jStat.matrixmult(jMatX.transpose(),jMatX);
var innerinv = jStat.inv(inner);
return innerinv;
},
jMatYBar: function jMatYBar(jMatX, beta) {
var yBar = jStat.matrixmult(jMatX, beta);
return new jStat(yBar);
},
residuals: function residuals(jMatY, jMatYBar) {
return jStat.matrixsubtract(jMatY, jMatYBar);
},
ssr: function ssr(jMatYBar, yAverage) {
var ssr = 0;
for(var i = 0; i < jMatYBar.length; i++) {
ssr += Math.pow(jMatYBar[i] - yAverage, 2);
}
return ssr;
},
sse: function sse(jMatY, jMatYBar) {
var sse = 0;
for(var i = 0; i < jMatY.length; i++) {
sse += Math.pow(jMatY[i] - jMatYBar[i], 2);
}
return sse;
},
sst: function sst(jMatY, yAverage) {
var sst = 0;
for(var i = 0; i < jMatY.length; i++) {
sst += Math.pow(jMatY[i] - yAverage, 2);
}
return sst;
},
matrixsubtract: function matrixsubtract(A,B){
var ans = new Array(A.length);
for(var i=0;i<A.length;i++){
ans[i] = new Array(A[i].length);
for(var j=0;j<A[i].length;j++){
ans[i][j]=A[i][j]-B[i][j];
}
}
return jStat(ans);
}
});