package weka.filters.timeseries; import weka.core.Attribute; import weka.core.DenseInstance; import weka.core.FastVector; import weka.core.Instance; import weka.core.Instances; import weka.filters.Filter; import weka.filters.SimpleBatchFilter; /* simple Filter that just summarises the series * copyright: Anthony Bagnall * Global stats: * mean, variance, skewness, kurtosis,min, max, range, * */ public class SummaryStats extends SimpleBatchFilter { private int numMoments=4; public void setNumMoments(int m){numMoments=4;} private static final long serialVersionUID = 1L; protected Instances determineOutputFormat(Instances inputFormat) throws Exception { //Check all attributes are real valued, otherwise throw exception for(int i=0;i<inputFormat.numAttributes();i++) if(inputFormat.classIndex()!=i) if(!inputFormat.attribute(i).isNumeric()) throw new Exception("Non numeric attribute not allowed in Moments"); //Set up instances size and format. FastVector atts=new FastVector(); String name; for(int i=0;i<numMoments;i++){ name = "Moment_"+(i+1); atts.addElement(new Attribute(name)); } if(inputFormat.classIndex()>=0){ //Classification set, set class //Get the class values as a fast vector Attribute target =inputFormat.attribute(inputFormat.classIndex()); FastVector vals=new FastVector(target.numValues()); for(int i=0;i<target.numValues();i++) vals.addElement(target.value(i)); atts.addElement(new Attribute(inputFormat.attribute(inputFormat.classIndex()).name(),vals)); } Instances result = new Instances("Moments"+inputFormat.relationName(),atts,inputFormat.numInstances()); if(inputFormat.classIndex()>=0){ result.setClassIndex(result.numAttributes()-1); } return result; } @Override public String globalInfo() { return null; } @Override public Instances process(Instances inst) throws Exception { Instances output=determineOutputFormat(inst); //For each data, first extract the relevan int seriesLength=inst.numAttributes(); if(inst.classIndex()>=0){ seriesLength--; } for(int i=0;i<inst.numInstances();i++){ //1. Get series: double[] d=inst.instance(i).toDoubleArray(); //2. Remove target class double[] temp; int c=inst.classIndex(); if(c>=0) { temp=new double[d.length-1]; System.arraycopy(d,0,temp,0,c); // if(c<temp.length) // System.arraycopy(d,c+1,temp,c,d.length-(c+1)); d=temp; } double[] moments=new double[numMoments]; /** * * * HERE FIND MOMENTS HERE * * **/ double sum = 0; //Find mean for(int j=0;j<d.length;j++) sum = sum+d[j]; moments[0] = sum/d.length; double totalVar=0; double totalSkew =0; double totalKur =0; //Find variance for(int j=0;j<d.length;j++) { totalVar = totalVar+ (d[j]-moments[0])*(d[j]-moments[0]); totalSkew = totalSkew+ (d[j]-moments[0])*(d[j]-moments[0])*(d[j]-moments[0]); totalKur = totalKur+ (d[j]-moments[0])*(d[j]-moments[0])*(d[j]-moments[0])*(d[j]-moments[0]); } moments[1] = totalVar/d.length; double standardDeviation = Math.sqrt(moments[1]); double skew = totalSkew/(standardDeviation*standardDeviation*standardDeviation); moments[2] = skew/d.length; double kur = totalKur/(standardDeviation*standardDeviation*standardDeviation*standardDeviation); moments[3] = kur/d.length; //Extract out the terms and set the attributes Instance newInst=null; if(inst.classIndex()>=0) newInst=new DenseInstance(numMoments+1); else newInst=new DenseInstance(numMoments); for(int j=0;j<numMoments;j++){ newInst.setValue(j,moments[j]); } if(inst.classIndex()>=0) newInst.setValue(output.classIndex(), inst.instance(i).classValue()); output.add(newInst); } return output; } public String getRevision() { // TODO Auto-generated method stub return null; } public static void main(String[] args) { /**Debug code to test SummaryStats generation: try{ Instances test=ClassifierTools.loadData("C:\\Users\\ajb\\Dropbox\\TSC Problems\\Beef\\Beef_TRAIN"); // Instances filter=new SummaryStats().process(test); SummaryStats m=new SummaryStats(); m.setInputFormat(test); Instances filter=Filter.useFilter(test,m); System.out.println(filter); } catch(Exception e){ System.out.println("Exception thrown ="+e); e.printStackTrace(); }**/ } }