时间序列分析之ADF检验——Java实现

ADF IN JAVA

1.测试数据
一串时间序列
2.将原始的数据进行差分处理。

//difflist 差分数列
List<Double> difflist =  Diff.diffArr(arr);

3.通过最大窗口值,处理差分后的数据。获得double[][]数组后,将第一列的数据替换为原始数组队应位置,同时在替换完的数组前加一列常数列 1。

//计算最大窗口大小 windowSize
int windowSize =(int) Math.ceil(Math.pow(arr.length / 100.0 ,1.0/4) * 12.0) + 1;
//slidingWindowLists 最大滑动窗口
List<List<Double>> maxslidingsindowLists = SlidingWindow.SlidingWindow(difflist , windowSize);
// 输出代替后的最大窗口数组
double[][] maxreplacewindow = Replace.replace(arr,maxslidingsindowLists);
//在第一列增加常数项
double[][] maxfullRHS = add.add2(maxreplacewindow);

4,通过最大窗口数组,找到最佳的滑动窗口大小。具体做法是,从0开始到最大窗口数组长度,依次计算每个数组的残差值,通过计算找到最小的比较值,输出此时的窗口大小,即为最佳的最佳窗口长度大小。

//找到最佳的滑动窗口大小
int bestWindowSize = BestWindow.bestwindow(d , maxfullRHS) + 1;
System.out.println("bestWindowSize = " + bestWindowSize);

5.找到最佳窗口长度以后,通过此值得到最佳窗口double[][]数组,并将第一列替换为原始数组的队应值,同时在最后加一列常数列 1。

//返回最佳窗口list
List<List<Double>> bestslidingsindowLists = SlidingWindow.SlidingWindow(difflist,bestWindowSize);

// 输出代替后的最佳窗口数组
double[][] bestreplacewindow = Replace.replace(arr,bestslidingsindowLists);

//在最后一列增加常数项
double[][] bestresult = add.add1(bestreplacewindow);

6.对最佳窗口数组进行OLS运算,求出相关系数beta ,残差和标准差std。

Matrix matrixa = new Matrix(d2);
Matrix matrixb = new Matrix(bestresult);
OLS ols = new OLS();

//计算beta
Matrix tempbetas = ols.Regress(matrixb, matrixa, false);
double beta = tempbetas.getValue(0,0);
System.out.println("beta = " + beta);
//计算残差
Matrix res = ols.getResiduals();
double residual = 0;
double[][] ressum = res.getData();
for(int i = 0 ; i < ressum.length ;i++)
    for (int j = 0; j < ressum[0].length; j++)
        residual = ressum[i][j] * ressum[i][j] + residual;
System.out.println("residual = " + residual);

//计算标准差
Matrix sse = ols.getStandartErrorsOfParameters();
double std = sse.getValue(0,0);
System.out.println("std = " + std);

7.计算t_value

ouble t_value = beta / std;
System.out.println("t_value = " + t_value);

8.计算得到p。我们在这里将公式简化。

double p = Mackinnonp.calc(Mackinnonp.calMackinnonp(t_value));
System.out.println("p = " + p);

ADF检验相关类:

Add:

package ADF;

public class add {
    public static double[][] add1(double[][] replacewindow){
        double[][] result = new double[replacewindow.length][replacewindow[0].length + 1];
        for(int i = 0 ; i < replacewindow.length ; i++){
            for(int j = 0 ; j< replacewindow[0].length ;j++)
                result[i][j] = replacewindow[i][j];
            result[i][replacewindow[0].length] = 1;
        }
        return result;
    }
   public static double[][] add2(double[][] replacewindow){
        double[][] result = new double[replacewindow.length][replacewindow[0].length + 1];
        for(int i = 0 ; i < replacewindow.length ; i++){
            for(int j = 0, k = 1 ; j< replacewindow[0].length ;j++ , k++)
                result[i][k] = replacewindow[i][j];
            result[i][0] = 1;
        }
        return result;
    }
}

ADFCheck:

package ADF;

import org.apache.commons.math3.linear.RealVector;

import java.util.List;

public class ADFCheck {

    public static double ADFCheck(double[] arr){

        //difflist 差分数列
        List<Double> difflist =  Diff.diffArr(arr);

        //计算最大窗口大小 windowSize
        int windowSize =(int) Math.ceil(Math.pow(arr.length / 100.0 ,1.0/4) * 12.0) + 1;
        //slidingWindowLists 最大滑动窗口
        List<List<Double>> maxslidingsindowLists = SlidingWindow.SlidingWindow(difflist , windowSize);
        // 输出代替后的最大窗口数组
        double[][] maxreplacewindow = Replace.replace(arr,maxslidingsindowLists);
        //在第一列增加常数项
        double[][] maxfullRHS = add.add2(maxreplacewindow);


        //将差分的list转换为数组
        int length =  maxfullRHS[0].length - 2;
        double[] d = new double[difflist.size() - length];
        for (int j = 0 ,i = length ; i < difflist.size() ;j++, i++) {
            d[j] = difflist.get(i);
        }

        //找到最佳的滑动窗口大小
        int bestWindowSize = BestWindow.bestwindow(d , maxfullRHS) + 1;
        System.out.println("bestWindowSize = " + bestWindowSize);

        //返回最佳窗口list
        List<List<Double>> bestslidingsindowLists = SlidingWindow.SlidingWindow(difflist,bestWindowSize);

        // 输出代替后的最佳窗口数组
        double[][] bestreplacewindow = Replace.replace(arr,bestslidingsindowLists);

        //在最后一列增加常数项
        double[][] bestresult = add.add1(bestreplacewindow);

        //将差分的list转换为数组
        int length2 =  bestresult[0].length - 2;
        double[] d2 = new double[difflist.size() - length2];
        for (int j = 0 ,i = length2 ; i < difflist.size() ;j++, i++) {
            d2[j] = difflist.get(i);
        }
        Matrix matrixa = new Matrix(d2);
        Matrix matrixb = new Matrix(bestresult);
        OLS ols = new OLS();

        //计算beta
        Matrix tempbetas = ols.Regress(matrixb, matrixa, false);
        double beta = tempbetas.getValue(0,0);
        System.out.println("beta = " + beta);

        //计算残差
        Matrix res = ols.getResiduals();
        double residual = 0;
        double[][] ressum = res.getData();
        for(int i = 0 ; i < ressum.length ;i++)
            for (int j = 0; j < ressum[0].length; j++)
                residual = ressum[i][j] * ressum[i][j] + residual;
        System.out.println("residual = " + residual);

        //计算标准差
        Matrix sse = ols.getStandartErrorsOfParameters();
        double std = sse.getValue(0,0);
        System.out.println("std = " + std);

        double t_value = beta / std;
        System.out.println("t_value = " + t_value);
        double p = Mackinnonp.calc(Mackinnonp.calMackinnonp(t_value));
        System.out.println("p = " + p);

        return p;
    }

}

BestWindow:

package ADF;

public class BestWindow {
    public static int bestwindow(double[] diff ,double[][] fullRHS){
        double[] residualarr = new double[fullRHS[0].length];
        int size = 1;
        for(int i = 1 ; i < fullRHS[0].length ; i++){
            double[][] window = new double[fullRHS.length][i + 1];
            for(int j = 0 ; j < fullRHS.length ; j++)
                for (int k = 0; k < i + 1; k++)
                    window[j][k] = fullRHS[j][k];
            Matrix matrixa = new Matrix(diff);
            Matrix matrixb = new Matrix(window);
            OLS ols = new OLS();
            //计算beta
            Matrix tempbetas = ols.Regress(matrixb, matrixa, false);
            double beta = tempbetas.getValue(1,0);
            Matrix res = ols.getResiduals();
            double residual = 0;
            double[][] ressum = res.getData();
            for(int k = 0 ; k < ressum.length ;k++)
                for (int t = 0; t < ressum[0].length; t++)
                    residual = ressum[k][t] * ressum[k][t] + residual;

            double num = 2 * window[0].length + window.length * Math.log(residual / window.length);
            residualarr[i] = num;

        }
        double bestWindow = residualarr[1];
        for(int i = 1 ; i < residualarr.length ; i++){
            if(Double.compare(bestWindow, residualarr[i]) > 0) {
                bestWindow = residualarr[i];
                size = i;
            }

        }

        return (size - 1);
    }
}

Diff:

package ADF;


import java.util.ArrayList;
import java.util.List;

public class Diff {
    public static List<Double> diffArr(double[] arr){
        List<Double> list = new ArrayList();
        for(int i = 1 ; i < arr.length ; i++){
            list.add(arr[i] - arr[i - 1]);
        }
        return list;
    }

}

Mackinnop:

package ADF;

public class Mackinnonp {
    public static double calMackinnonp(double num){
        if(num > 2.74)
            return 1;
        if(num < -18.83)
            return 0;

        if(num < -1.61)
            return 0.038269 * Math.pow(num,2) + 1.4412 * num + 2.1659;
        else
            return -0.010368 * Math.pow(num,3) - 0.12745 * Math.pow(num,2) + 0.93202 * num + 1.7339;
    }
    public static double calc(double u){
        double y = Math.abs(u);
        double y2 = y*y;
        double z = Math.exp(-0.5 * y2) * 0.398942280401432678;
        double p = 0;
        int k = 28;
        double s = -1;
        double fj = k;

        if(y > 3){
            for(int i = 1 ; i <= k ; i++){
                p = fj / (y + p);
                fj = fj - 1.0;
            }
            p = z / (y + p);
        }else{
            for(int i = 1 ; i <= k ; i++){
                p = fj * y2 / (2.0*fj +1.0 + s * p);
                s = -s;
                fj = fj - 1.0;
            }
            p = 0.5 - z * y / ( 1 - p );
        }
        if(u>0) p = 1.0 - p;
        return p;
    }
}

Matrix:

package ADF;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.StringTokenizer;

public class Matrix
{
    public double myData[][];
    public int n;
    public int m;

    public Matrix()
    {
    }

    public Matrix(int n, int m)
    {
        this.n = n;
        this.m = m;
        try
        {
            myData = new double[n][m];
        }
        catch(Exception _ex)
        {
            System.out.println("Matrix(n,m) can't create");
        }
    }

    public Matrix(double data[][])
    {
        n = data.length;
        m = data[0].length;
        myData = data;
    }

    public Matrix(double data[]) {
        n = data.length;
        m = 1;
        double[][] a = new double[n][1];
        for(int i = 0 ; i < n ; i++)
            a[i][0] = data[i];
        myData = a;
    }

    public double Det()
    {
        if(n != m)
            return 0.0D;
        double mydet = 1.0D;
        Matrix temp1 = new Matrix(myData);
        double temp2[][] = temp1.Eshelon().getData();
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
                if(i == j)
                    mydet *= temp2[i][j];

        }

        temp2 = null;
        temp1 = null;
        return mydet;
    }

    public Matrix Diff(Matrix A)
    {
        Matrix mynew = new Matrix(A.n, A.m);
        for(int i = 0; i < A.n; i++)
        {
            for(int j = 0; j < A.m; j++)
                mynew.setValue(i, j, myData[i][j] - A.getValue(i, j));

        }

        return mynew;
    }

    public Matrix Eshelon()
    {
        double pivot = 0.0D;
        Matrix t = new Matrix(myData);
        double temp[][] = new double[t.n][t.m];
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
                temp[i][j] = t.getValue(i, j);

        }

        for(int i = 0; i < n; i++)
        {
            for(int j = i + 1; j < n; j++)
            {
                pivot = -temp[j][i] / temp[i][i];
                for(int k = 0; k < m; k++)
                    temp[j][k] = temp[i][k] * pivot + temp[j][k];

            }

        }

        t = null;
        return new Matrix(temp);
    }

    public Matrix Inverse()
    {
        if(this.n != this.m || Det() == 0.0D)
            return new Matrix(this.n, this.m);
        Matrix temp = new Matrix(myData);
        int n = temp.n;
        int m = temp.m;
        Matrix Cofactor = new Matrix(n, m);
        for(int j = 0; j < m; j++)
        {
            for(int i = 0; i < n; i++)
            {
                Matrix Mintemp = temp.Minor(i, j);
                double tempdet = Mintemp.Det();
                Cofactor.setValue(i, j, tempdet);
            }

        }

        Cofactor = Cofactor.Transpose();
        double det = temp.Det();
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
                Cofactor.setValue(i, j, (Cofactor.getValue(i, j) * Math.pow(-1D, i + j + 2)) / det);

        }

        return Cofactor;
    }

    public Matrix Minor(int x, int y)
    {
        Matrix temp = new Matrix(myData);
        Matrix newmat = new Matrix(temp.n - 1, temp.m - 1);
        int n = temp.n;
        int m = temp.m;
        int cnt = 0;
        double myArr[] = new double[(n - 1) * (m - 1)];
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
                if(i != x && j != y)
                {
                    myArr[cnt] = temp.getValue(i, j);
                    cnt++;
                }

        }

        cnt = 0;
        for(int i = 0; i < n - 1; i++)
        {
            for(int j = 0; j < m - 1; j++)
            {
                newmat.setValue(i, j, myArr[cnt]);
                cnt++;
            }

        }

        return newmat;
    }

    public Matrix Mult(Matrix A)
    {
        double c[][] = new double[n][A.m];
        double tempdata[][] = A.getData();
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < A.m; j++)
            {
                for(int y = 0; y < m; y++)
                    c[i][j] = c[i][j] + myData[i][y] * tempdata[y][j];

            }

        }

        return new Matrix(c);
    }
    public Matrix Transpose()
    {
        Matrix temp = new Matrix(myData);
        int n = temp.n;
        int m = temp.m;
        Matrix newmat = new Matrix(m, n);
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
                newmat.setValue(j, i, temp.getValue(i, j));

        }

        return newmat;
    }


    public double[][] getData()
    {
        double temp[][] = myData;
        return temp;
    }

    public double getValue(int x, int y)
    {
        return myData[x][y];
    }


    public void setValue(int x, int y, double value)
    {
        myData[x][y] = value;
    }

}

OLS:

package ADF;


// Referenced classes of package Statistics:
//            Matrix

public class OLS
{
    public Matrix betas;
    public Matrix x;
    public Matrix y;
    boolean intercept;

    public OLS()
    {
    }

    public Matrix Regress(Matrix x, Matrix y, boolean intercept)
    {
       this.intercept=intercept;
        betas = new Matrix();
        this.x = x;
        this.y = y;
        if(!intercept) {
            //Transpose  转置 Mult相乘  inverse 求逆
            betas = x.Transpose().Mult(x).Inverse().Mult(x.Transpose()).Mult(y);
        } else {
            int n = x.n;
            int m = x.m;
            Matrix design = new Matrix(n, m + 1);
            for(int i = 0; i < n; i++)
                design.setValue(i, 0, 1.0D);

            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < m; j++)
                    design.setValue(i, j + 1, x.getValue(i, j));

            }

            betas = design.Transpose().Mult(design).Inverse().Mult(design.Transpose()).Mult(y);
            this.x =new Matrix(design.myData);
        }
        return betas;
    }

    public Matrix getResiduals()
    {
        Matrix temp = y.Diff(x.Mult(betas));
        return temp;
    }
    
    public double getEstimatedVariance(){
       Matrix temp=new Matrix(x.n,1);
       temp.myData=getResiduals().myData;
       double temp1=0;
       for (int i=0;i<x.n;i++){
          temp1+= Math.pow(temp.getValue(i,0),2.0);
       }
       return (temp1/(x.n-x.m));
    }
    
    public Matrix getCovarianceMatrixOfParameters(){
       Matrix temp=(x.Transpose().Mult(x)).Inverse();
       double std=getEstimatedVariance();
       for (int i=0;i<x.m;i++){
          temp.myData[i][i]=temp.myData[i][i]*std;
       }
       return (temp);
    }
    
    public Matrix getStandartErrorsOfParameters() {
       Matrix temp=getCovarianceMatrixOfParameters();
       for (int i=0;i<x.m;i++){
          temp.myData[i][i]= Math.sqrt(temp.myData[i][i]);
       }
       return (temp);
    }
}

Replace:

package ADF;

import java.util.List;

public class Replace {
public static double[][] replace(double[] arr , List<List<Double>> lists){
    double[][] arrs = new double[lists.size()][lists.get(0).size()];
    for (int i = 0; i < lists.size(); i++) {
         List<Double> temp = lists.get(i);
        for (int j = 0; j < temp.size(); j++) {
            arrs[i][j] = temp.get(j);
        }
    }

    for(int i = arrs.length - 1 , j = arr.length -1  ; i >= 0 ; i-- ,j --)
        arrs[i][0] = arr[j - 1];
    return arrs;
}
}

SlidingWindow:

package ADF;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SlidingWindow {
    public static List SlidingWindow(List rawlist, int size){
        List<List<Double>> list = new ArrayList<>();
        for(int i = 0 ; i < rawlist.size() - size + 1 ; i++){
            List<Double> lists = new ArrayList<>();
            for(int j = 0 ; j <size ; j++)
                lists.add((Double) rawlist.get(i + j));
            Collections.reverse(lists);
            list.add(lists);
        }
        for(int i = 0 ; i < rawlist.size() - size + 1 ; i++){
            List<Double> lists = new ArrayList<>();
            lists = list.get(i);
        }
        return list;
    }
}   
发布了26 篇原创文章 · 获赞 0 · 访问量 803

猜你喜欢

转载自blog.csdn.net/u013317894/article/details/99660036
今日推荐