//
//  OpenForecast - open source, general-purpose forecasting package.
//  Copyright (C) 2002-2011  Steven R. Gould
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

package net.sourceforge.openforecast.models;


/**
 * A weighted moving average forecast model is based on an artificially
 * constructed time series in which the value for a given time period is
 * replaced by the weighted mean of that value and the values for some number
 * of preceding time periods. As you may have guessed from the description,
 * this model is best suited to time-series data; i.e. data that changes over
 * time.
 *
 * 

Since the forecast value for any given period is a weighted average of * the previous periods, then the forecast will always appear to "lag" behind * either increases or decreases in the observed (dependent) values. For * example, if a data series has a noticable upward trend then a weighted * moving average forecast will generally provide an underestimate of the * values of the dependent variable. * *

The weighted moving average model, like the moving average model, has * an advantage over other forecasting models in that it does smooth out * peaks and troughs (or valleys) in a set of observations. However, like the * moving average model, it also has several disadvantages. In particular this * model does not produce an actual equation. Therefore, it is not all that * useful as a medium-long range forecasting tool. It can only reliably be * used to forecast a few periods into the future. * @author Steven R. Gould * @since 0.4 */ public class WeightedMovingAverageModel extends AbstractTimeBasedModel { /** * The weights to assign to each period. These weights must add up to 1.0. */ private double[] weights; /** * Constructs a new weighted moving average forecasting model, using the * specified weights. For a valid model to be constructed, you should call * init and pass in a data set containing a series of data points with the * time variable initialized to identify the independent variable. * *

The size of the weights array is used to determine the number of * observations to be used to calculate the weighted moving average. * Additionally, the most recent period will be given the weight defined * by the first element of the array; i.e. weights[0]. * *

The size of the weights array is also used to determine the amount * of future periods that can effectively be forecast. With a 50 day * weighted moving average, then we cannot reasonably - with any degree * of accuracy - forecast more than 50 days beyond the last period for * which data is available. Even forecasting near the end of this range * is likely be be unreliable. * *

Note on weights

*

In general, the weights passed to this constructor should add up * to 1.0. However, as a convenience, if the sum of the weights does not * add up to 1.0, this implementation scales all weights proportionally * so that they do sum to 1.0. * @param weights an array of weights to assign to the historical * observations when calculating the weighted moving average. */ public WeightedMovingAverageModel( double[] weights ) { setWeights( weights ); } /** * Constructs a new weighted moving average forecasting model, using the * named variable as the independent variable and the specified weights. * @param independentVariable the name of the independent variable to use * in this model. * @param weights an array of weights to assign to the historical * observations when calculating the weighted moving average. * @deprecated As of 0.4, replaced by {@link #WeightedMovingAverageModel(double[])}. */ public WeightedMovingAverageModel( String independentVariable, double[] weights ) { super( independentVariable ); setWeights( weights ); } /** * Constructs a new weighted moving average forecasting model. This * constructor is intended to be used only by subclasses (hence it is * protected). Any subclass using this constructor must subsequently * invoke the (protected) setWeights method to initialize the weights to * be used by this model. */ protected WeightedMovingAverageModel() { } /** * Constructs a new weighted moving average forecasting model using * the given independent variable. * @param independentVariable the name of the independent variable to use * in this model. * @deprecated As of 0.4, replaced by {@link #WeightedMovingAverageModel}. */ protected WeightedMovingAverageModel( String independentVariable ) { super( independentVariable ); } /** * Sets the weights used by this weighted moving average forecasting model * to the given weights. This method is intended to be used only by * subclasses (hence it is protected), and only in conjunction with the * (protected) one-argument constructor. * *

Any subclass using the one-argument constructor must subsequently * call setWeights before invoking the {@link #init} method to * initialize the model. * *

Note on weights

*

In general, the weights passed to this method should add up to 1.0. * However, as a convenience, if the sum of the weights does not add up * to 1.0, this implementation scales all weights proportionally so that * they do sum to 1.0. * @param weights an array of weights to assign to the historical * observations when calculating the weighted moving average. */ protected void setWeights( double[] weights ) { int periods = weights.length; // Check sum of weights adds up to 1.0 double sum = 0.0; for ( int w=0; w TOLERANCE ) adjust = true; // Save weights or adjusted weights this.weights = new double[ periods ]; for ( int w=0; w=0; p-- ) { t -= timeDiff; try { forecast += weights[p]*getObservedValue( t ); } catch ( IllegalArgumentException iaex ) { forecast += weights[p]*getForecastValue( t ); } } return forecast; } /** * Returns the number of predictors used by the underlying model. * @return the number of predictors used by the underlying model. */ public int getNumberOfPredictors() { return 1; } /** * Returns the current number of periods used in this model. * @return the current number of periods used in this model. */ protected int getNumberOfPeriods() { return weights.length; } /** * Returns a one or two word name of this type of forecasting model. Keep * this short. A longer description should be implemented in the toString * method. * @return a string representation of the type of forecasting model * implemented. */ public String getForecastType() { return "Weighted Moving Average"; } /** * This should be overridden to provide a textual description of the * current forecasting model including, where possible, any derived * parameters used. * @return a string representation of the current forecast model, and its * parameters. */ public String toString() { return "weighted moving average model, spanning " + getNumberOfPeriods() + " periods and using an independent variable of " + getIndependentVariable() + "."; } } // Local Variables: // tab-width: 4 // End:

Ads help maintain this website.