⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tripleexponentialsmoothingmodel.java

📁 搞算法预测的可以来看。有移动平均法
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        int bestModelIndex = 0;        for ( int m=1; m<5; m++ )            if ( model[m].getMSE() < model[bestModelIndex].getMSE() )                bestModelIndex = m;        switch ( bestModelIndex )            {            case 1:                // Reduce maximums                // Can discard models 3 and 4                model[3] = null;                model[4] = null;                return findBest( dataSet, model[0], model[1], model[2],                                 alphaTolerance, betaTolerance );            case 2:                // Can discard models 0 and 4                model[0] = null;                model[4] = null;                return findBest( dataSet, model[1], model[2], model[3],                                 alphaTolerance, betaTolerance );                            case 3:                // Reduce minimums                // Can discard models 0 and 1                model[0] = null;                model[1] = null;                return findBest( dataSet, model[2], model[3], model[4],                                 alphaTolerance, betaTolerance );            case 0:            case 4:                // We're done???                break;            }        // Release all but the best model constructed so far        for ( int m=0; m<5; m++ )            if ( m != bestModelIndex )                model[m] = null;                return model[bestModelIndex];    }    /**     * For the given value of the alpha smoothing constant, returns the best     * fit model where the value of the beta (trend) smoothing constant is     * between betaMin and betaMax. This method will continually try to     * refine the estimate of beta until a tolerance of less than     * betaTolerance is achieved.     *     * <p>Note that the descriptions of the parameters below include a     * discussion of valid values. However, since this is a private method and     * to help improve performance, we don't provide any validation of these     * parameters. Using invalid values may lead to unexpected results.     * @param dataSet the data set for which a best fit model is required.     * @param alpha the (fixed) value of the alpha smoothing constant to use     * for the best fit model.     * @param betaMin the minimum value of the beta (trend) smoothing     * constant accepted in the resulting best fit model. Must be greater than     * (or equal to) 0.0 and less than betaMax.     * @param betaMax the maximum value of the beta (trend) smoothing     * constant accepted in the resulting best fit model. Must be greater than     * betaMin and less than (or equal to) 1.0.     * @param betaTolerance the tolerance within which the beta value is     * required. Must be considerably less than 1.0. However, note that the     * smaller this value the longer it will take to diverge on a best fit     * model.     */    private static TripleExponentialSmoothingModel findBestBeta(                        DataSet dataSet, double alpha,                        double betaMin, double betaMax,                        double betaTolerance )    {        int stepsPerIteration = 10;        if ( betaMin < 0.0 )            betaMin = 0.0;        if ( betaMax > 1.0 )            betaMax = 1.0;        TripleExponentialSmoothingModel bestModel            = new TripleExponentialSmoothingModel( alpha, betaMin, 0.0 );        bestModel.init(dataSet);        double initialMSE = bestModel.getMSE();        boolean betaImproving = true;        double betaStep = (betaMax-betaMin)/stepsPerIteration;        double beta = betaMin + betaStep;        for ( ; beta<=betaMax || betaImproving; )            {                TripleExponentialSmoothingModel model                    = new TripleExponentialSmoothingModel( alpha, beta, 0.0 );                model.init( dataSet );                                if ( model.getMSE() < bestModel.getMSE() )                    bestModel = model;                else                    betaImproving = false;                                beta += betaStep;                if ( beta > 1.0 )                    betaImproving = false;            }        // If we're making progress, then try to refine the beta estimate        if ( bestModel.getMSE() < initialMSE             && betaStep > betaTolerance )            {                // Can this be further refined - improving efficiency - by                //  only searching in the range beta-betaStep/2 to                //  beta+betaStep/2 ?                return findBestBeta( dataSet, bestModel.getAlpha(),                                      bestModel.getBeta()-betaStep,                                      bestModel.getBeta()+betaStep,                                      betaTolerance );            }                return bestModel;    }    /**     * Constructs a new triple exponential smoothing forecasting model, using     * the given smoothing constants - alpha, beta and gamma. 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.     * @param alpha the smoothing constant to use for this exponential     * smoothing model. Must be a value in the range 0.0-1.0. Values above 0.5     * are uncommon - though they are still valid and are supported by this     * implementation.     * @param beta the second smoothing constant, beta to use in this model     * to smooth the trend. Must be a value in the range 0.0-1.0. Values above     * 0.5 are uncommon - though they are still valid and are supported by this     * implementation.     * @param gamma the third smoothing constant, gamma to use in this model     * to smooth the seasonality. Must be a value in the range 0.0-1.0.     * @throws IllegalArgumentException if the value of any of the smoothing     * constants are invalid - outside the range 0.0-1.0.     */    public TripleExponentialSmoothingModel(    double alpha,                                            double beta,                                            double gamma )    {        if ( alpha < 0.0  ||  alpha > 1.0 )            throw new IllegalArgumentException("TripleExponentialSmoothingModel: Invalid smoothing constant, " + alpha + " - must be in the range 0.0-1.0.");                if ( beta < 0.0  ||  beta > 1.0 )            throw new IllegalArgumentException("TripleExponentialSmoothingModel: Invalid smoothing constant, beta=" + beta + " - must be in the range 0.0-1.0.");                if ( gamma < 0.0  ||  gamma > 1.0 )            throw new IllegalArgumentException("TripleExponentialSmoothingModel: Invalid smoothing constant, gamma=" + gamma + " - must be in the range 0.0-1.0.");                baseValues = new DataSet();        trendValues = new DataSet();        seasonalIndex = new DataSet();                this.alpha = alpha;        this.beta = beta;        this.gamma = gamma;    }        /**     * Used to initialize the time based model. This method must be called     * before any other method in the class. Since the time based model does     * not derive any equation for forecasting, this method uses the input     * DataSet to calculate forecast values for all values of the independent     * time variable within the initial data set.     * @param dataSet a data set of observations that can be used to     * initialize the forecasting parameters of the forecasting model.     */    public void init( DataSet dataSet )    {        initTimeVariable( dataSet );        String timeVariable = getTimeVariable();        if ( dataSet.getPeriodsPerYear() <= 1 )            throw new IllegalArgumentException("Data set passed to init in the triple exponential smoothing model does not contain seasonal data. Don't forget to call setPeriodsPerYear on the data set to set this.");        periodsPerYear = dataSet.getPeriodsPerYear();        // Calculate initial values for base and trend        initBaseAndTrendValues( dataSet );        // Initialize seasonal indices using data for all complete years        initSeasonalIndices( dataSet );        Iterator it = dataSet.iterator();        maxObservedTime = Double.NEGATIVE_INFINITY;        while ( it.hasNext() )            {                DataPoint dp = (DataPoint)it.next();                if ( dp.getIndependentValue(timeVariable) > maxObservedTime )                    maxObservedTime = dp.getIndependentValue(timeVariable);            }        super.init( dataSet );    }    /**     * Calculates (and caches) the initial base and trend values for the given     * DataSet. Note that there are a variety of ways to estimate initial     * values for both the base and the trend. The approach here averages the     * trend calculated from the first two complete "years" - or cycles - of     * data in the DataSet.     * @param dataSet the set of data points - observations - to use to     * initialize the base and trend values.     */    private void initBaseAndTrendValues( DataSet dataSet )    {        String timeVariable = getTimeVariable();        double trend = 0.0;        Iterator it = dataSet.iterator();        for ( int p=0; p<periodsPerYear; p++ )            {                DataPoint dp = (DataPoint)it.next();                trend -= dp.getDependentValue();            }        double year2Average = 0.0;        for ( int p=0; p<periodsPerYear; p++ )            {                DataPoint dp = (DataPoint)it.next();                trend += dp.getDependentValue();                year2Average += dp.getDependentValue();            }        trend /= periodsPerYear;        trend /= periodsPerYear;        year2Average /= periodsPerYear;        it = dataSet.iterator();        for ( int p=0; p<periodsPerYear*NUMBER_OF_YEARS; p++ )            {                DataPoint obs = (DataPoint)it.next();                double time = obs.getIndependentValue( timeVariable );                DataPoint dp = new Observation( trend );                dp.setIndependentValue( timeVariable, time );                trendValues.add( dp );                // Initialize base values for second year only                if ( p >= periodsPerYear )                    {                        // This formula gets a little convoluted partly due to                        // the fact that p is zero-based, and partly because                        // of the generalized nature of the formula                        dp.setDependentValue(year2Average                                             + (p+1-periodsPerYear                                                -(periodsPerYear+1)/2.0)*trend);                        //dp.setIndependentValue( timeVariable, time );                        baseValues.add( dp );                    }            }    }    /**     * Calculates (and caches) the initial seasonal indices for the given     * DataSet. Note that there are a variety of ways to estimate initial     * values for the seasonal indices. The approach here averages seasonal     * indices calculated for the first two complete "years" - or cycles - in     * the DataSet.     * @param dataSet the set of data points - observations - to use to     * initialize the seasonal indices.     */    private void initSeasonalIndices( DataSet dataSet )    {        String timeVariable = getTimeVariable();        double yearlyAverage[] = new double[NUMBER_OF_YEARS];        Iterator it = dataSet.iterator();        for ( int year=0; year<NUMBER_OF_YEARS; year++ )            {                double sum = 0.0;                for ( int p=0; p<periodsPerYear; p++ )                    {                        DataPoint dp = (DataPoint)it.next();                        sum += dp.getDependentValue();                    }                yearlyAverage[year] = sum / (double)periodsPerYear;            }        it = dataSet.iterator();        double index[] = new double[periodsPerYear];        for ( int year=0; year<NUMBER_OF_YEARS; year++ )            {                double sum = 0.0;                for ( int p=0; p<periodsPerYear; p++ )                    {                        DataPoint dp = (DataPoint)it.next();                        index[p]                            += (dp.getDependentValue()/yearlyAverage[year])                                 / NUMBER_OF_YEARS;                    }            }        it = dataSet.iterator();        // Skip over first n-1 years        for ( int year=0; year<NUMBER_OF_YEARS-1; year++ )            for ( int p=0; p<periodsPerYear; p++ )                it.next();        for ( int p=0; p<periodsPerYear; p++ )            {                DataPoint dp = (DataPoint)it.next();                double time = dp.getIndependentValue( timeVariable );                Observation obs = new Observation( index[p] );                obs.setIndependentValue( timeVariable, time );                seasonalIndex.add( obs );            }    }    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -