Package weka.classifiers.timeseries.gui

Source Code of weka.classifiers.timeseries.gui.SimpleConfigPanel

/*
* Copyright (c) 2010 Pentaho Corporation.  All rights reserved.
* This software was developed by Pentaho Corporation and is provided under the terms
* of the GNU Lesser General Public License, Version 2.1. You may not use
* this file except in compliance with the license. If you need a copy of the license,
* please go to http://www.gnu.org/licenses/lgpl-2.1.txt. The Original Code is Time Series
* Forecasting.  The Initial Developer is Pentaho Corporation.
*
* Software distributed under the GNU Lesser Public License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or  implied. Please refer to
* the license for the specific language governing your rights and limitations.
*/

/*
*    SimpleConfigPanel.java
*    Copyright (C) 2010 Pentaho Corporation
*/

package weka.classifiers.timeseries.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;

import weka.classifiers.timeseries.WekaForecaster;
import weka.classifiers.timeseries.core.TSLagMaker;
import weka.classifiers.timeseries.eval.TSEvaluation;
import weka.core.Attribute;
import weka.core.Instances;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.Remove;
import weka.gui.AttributeSelectionPanel;

/**
* Class that renders a simple configuration panel for configuring a time series
* forecaster.
*
* @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
* @version $Revision: 50889 $
*/
public class SimpleConfigPanel extends JPanel {

  /**
   * For serialization
   */
  private static final long serialVersionUID = 4339062970124604791L;

  /** The training instances to operate on */
  protected Instances m_instances;

  /** The forecaster to configure */
  protected WekaForecaster m_forecaster;

  /**
   * Holds the header of the training instances after all but numeric attributes
   * are removed (for target selection purposes
   */
  protected Instances m_targetHeader;

  /** Combo box for selecting the time stamp attribute */
  protected JComboBox m_timeStampCombo = new JComboBox();

  /** Combo box for selecting the periodicity */
  protected JComboBox m_periodicityCombo = new JComboBox();

  /** Panel for selecting targets to forecast */
  protected AttributeSelectionPanel m_targetPanel = new AttributeSelectionPanel();

  /** Checkbox for computing confidence intervals */
  protected JCheckBox m_computeConfidence = new JCheckBox();

  /** Spinner for selecting the number of steps to forecast */
  protected JSpinner m_horizonSpinner;

  /** Spinner for selecting the confidence interval */
  protected JSpinner m_confidenceLevelSpinner;

  /** Checkbox for selecting whether to perform evaluation */
  protected JCheckBox m_performEvaluation = new JCheckBox();

  /** A reference to the advanced config panel */
  protected AdvancedConfigPanel m_advancedConfig;

  /**
   * Text field for entering date time stamp values that should be "skipped" -
   * i.e. not considered as a time step
   */
  protected JTextField m_skipText = new JTextField(18);

  /** A reference to the parent panel */
  protected ForecastingPanel m_parentPanel;

  /**
   * Constructor
   *
   * @param parent the parent ForecastingPanel
   */
  public SimpleConfigPanel(ForecastingPanel parent) {

    m_parentPanel = parent;
    setLayout(new BorderLayout());

    JPanel colSelect = new JPanel();
    colSelect.setLayout(new BorderLayout());
    colSelect.setBorder(BorderFactory.createTitledBorder("Target Selection"));
    JPanel tempHolder1 = new JPanel();
    tempHolder1.setLayout(new BorderLayout());
    tempHolder1.add(m_targetPanel, BorderLayout.NORTH);
    colSelect.add(tempHolder1, BorderLayout.NORTH);

    m_targetPanel.setPreferredScrollableViewportSize(new Dimension(250, 80));
    SpinnerNumberModel snm = new SpinnerNumberModel();
    snm.setValue(1);
    snm.setMinimum(1);
    m_horizonSpinner = new JSpinner(snm);
    Dimension spinD = m_horizonSpinner.getPreferredSize();
    spinD = new Dimension((int) (spinD.getWidth() * 1.5),
        (int) spinD.getHeight());
    m_horizonSpinner.setPreferredSize(spinD);
    JPanel spinnerHolder = new JPanel();
    spinnerHolder.setBorder(BorderFactory.createEmptyBorder(0, 0, 1, 0));
    spinnerHolder.setLayout(new BorderLayout());
    spinnerHolder.add(m_horizonSpinner, BorderLayout.EAST);
    spinnerHolder.add(new JLabel("Number of time units to forecast ",
        JLabel.LEFT), BorderLayout.CENTER);

    // tempHolder1.add(spinnerHolder, BorderLayout.CENTER);
    // JPanel spacer = new JPanel();
    // spacer.setMinimumSize(spinD);
    // tempHolder1.add(spacer, BorderLayout.SOUTH);

    add(colSelect, BorderLayout.CENTER);
    Box comboHolder = new Box(BoxLayout.PAGE_AXIS);
    comboHolder.add(spinnerHolder);
    JPanel timeHolder = new JPanel();
    timeHolder.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
    timeHolder.setLayout(new BorderLayout());
    // timeHolder.setBorder(BorderFactory.createTitledBorder("Time stamp"));
    timeHolder.add(new JLabel("Time stamp ", JLabel.RIGHT), BorderLayout.WEST);
    timeHolder.add(m_timeStampCombo, BorderLayout.EAST);
    comboHolder.add(timeHolder);
    JPanel periodicityHolder = new JPanel();
    periodicityHolder.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
    periodicityHolder.setLayout(new BorderLayout());
    // periodicityHolder.setBorder(BorderFactory.createTitledBorder("Periodicity"));
    periodicityHolder.add(new JLabel("Periodicity", JLabel.RIGHT),
        BorderLayout.WEST);
    periodicityHolder.add(m_periodicityCombo, BorderLayout.EAST);
    comboHolder.add(periodicityHolder);
    m_periodicityCombo.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        checkSkipEnabledStatus();
        checkPeriodicity(null);
      }
    });

    //
    JPanel skipPanel = new JPanel();
    skipPanel.setLayout(new BorderLayout());
    skipPanel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
    String skipTipText = "<html>Set date time stamp values that should be 'skipped'<br>"
        + "i.e. times that shouldn't count as a time step increment.<br><br>"
        + "E.g. financial trading does not occur on the weekend, so the <br>"
        + "difference between Friday and the following Monday is actually one<br>"
        + "time step (not three).<br><br>Examples:<br><br>"
        + "\"sat,weekend,aug,2011-01-11@yyyy-MM-dd\"</html>";
    JLabel skipLab = new JLabel("Skip list", JLabel.RIGHT);
    skipLab.setToolTipText(skipTipText);
    skipPanel.add(skipLab, BorderLayout.WEST);
    skipPanel.add(m_skipText, BorderLayout.EAST);
    m_skipText.setToolTipText(skipTipText);
    comboHolder.add(skipPanel);

    m_computeConfidence.setHorizontalTextPosition(SwingConstants.LEFT);

    JPanel confHolder = new JPanel();
    confHolder.setLayout(new BorderLayout());
    confHolder.add(new JLabel("Confidence intervals", JLabel.RIGHT),
        BorderLayout.WEST);
    confHolder.add(m_computeConfidence, BorderLayout.EAST);
    comboHolder.add(confHolder);

    JPanel confLevHolder = new JPanel();
    confLevHolder.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
    confLevHolder.setLayout(new BorderLayout());
    final JLabel levelLab = new JLabel("Level (%) ", JLabel.RIGHT);
    levelLab.setEnabled(false);
    snm = new SpinnerNumberModel();
    snm.setValue(95);
    snm.setMinimum(1);
    snm.setMaximum(99);
    m_confidenceLevelSpinner = new JSpinner(snm);
    m_confidenceLevelSpinner.setEnabled(false);
    confLevHolder.add(m_confidenceLevelSpinner, BorderLayout.EAST);
    confLevHolder.add(levelLab, BorderLayout.CENTER);

    comboHolder.add(confLevHolder);

    m_computeConfidence.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        boolean enable = m_computeConfidence.isSelected();
        levelLab.setEnabled(enable);
        m_confidenceLevelSpinner.setEnabled(enable);
      }
    });

    JPanel evalHolder = new JPanel();
    evalHolder.setLayout(new BorderLayout());
    evalHolder.add(new JLabel("Perform evaluation", JLabel.RIGHT),
        BorderLayout.WEST);
    m_performEvaluation.setHorizontalAlignment(SwingConstants.LEFT);
    evalHolder.add(m_performEvaluation, BorderLayout.EAST);
    comboHolder.add(evalHolder);
    m_performEvaluation.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        m_advancedConfig.m_trainingCheckBox.setSelected(m_performEvaluation
            .isSelected());
        // don't enable test set evaluation, only disable
        if (!m_performEvaluation.isSelected()) {
          m_advancedConfig.m_holdoutCheckBox.setSelected(false);
        }
      }
    });

    // comboHolder.add(m_horizon);

    JPanel temp = new JPanel();
    temp.setLayout(new BorderLayout());
    temp.setBorder(BorderFactory.createTitledBorder("Parameters"));

    temp.add(comboHolder, BorderLayout.NORTH);
    add(temp, BorderLayout.EAST);

    m_timeStampCombo.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        if (m_advancedConfig != null) {
          m_advancedConfig.updateDateDerivedPanel();
          checkSkipEnabledStatus();
        }
      }
    });

    /*
     * m_periodicityCombo.addActionListener(new ActionListener() { public void
     * actionPerformed(ActionEvent e) { if (m_forecaster != null) {
     *
     * } } });
     */

    // m_targetPanel
    /*
     * Dimension d = tempHolder1.getPreferredSize(); Dimension d2 =
     * spinnerHolder.getPreferredSize(); tempHolder1.setMinimumSize(new
     * Dimension(tempHolder1.getPreferredSize().width, d.height + d2.height));
     * tempHolder1.setPreferredSize(new
     * Dimension(tempHolder1.getPreferredSize().width, d.height + d2.height));
     */
  }

  private void checkSkipEnabledStatus() {
    boolean enable = false;
    if (m_instances != null) {
      if (m_timeStampCombo.getSelectedItem() != null) {
        String timeName = m_timeStampCombo.getSelectedItem().toString();
        Attribute timeAtt = m_instances.attribute(timeName);
        if (timeAtt != null) {
          if (m_periodicityCombo.getSelectedItem() != null) {
            String periodicity = m_periodicityCombo.getSelectedItem()
                .toString();
            enable = (timeAtt.isDate() && !periodicity.equals("<Unknown>") && !periodicity
                .equals("<Detect automatically>"));
          }
        }
      }
    }
    m_skipText.setEnabled(enable);
  }

  /**
   * Get the title for this panel suitable for displaying in a tab.
   *
   * @return the title for this panel.
   */
  public String getTabTitle() {
    return "Basic configuration";
  }

  /**
   * Get the tool tip for this panel.
   *
   * @return the tool tip for this panel.
   */
  public String getTabTitleToolTip() {
    return "Basic configuration";
  }

  /**
   * Get the value in the horizon spinner (i.e. the number of steps to forecast)
   *
   * @return the number of steps to forecast.
   */
  public int getHorizonValue() {
    SpinnerNumberModel snm = (SpinnerNumberModel) m_horizonSpinner.getModel();

    return snm.getNumber().intValue();
  }

  /**
   * Set a reference to the advanced configuration panel.
   *
   * @param adv a reference to the advanced configuration panel.
   */
  public void setAdvancedConfig(AdvancedConfigPanel adv) {
    m_advancedConfig = adv;
  }

  /**
   * Set the WekaForecaster that is to be configured by this panel.
   *
   * @param forecaster the WekaForecaster that is to be configured by this
   *          panel.
   */
  public void setForecaster(WekaForecaster forecaster) {
    m_forecaster = forecaster;
    if (m_instances != null) {
      if (!m_forecaster.getTSLagMaker().getAdjustForTrends()) {
        m_timeStampCombo.setSelectedItem("<None>");
        m_periodicityCombo.setSelectedIndex(0);
      } else {
        if (m_forecaster.getTSLagMaker().isUsingAnArtificialTimeIndex()) {
          m_timeStampCombo.setSelectedItem("<Use an artificial time index>");
        } else if (m_forecaster.getTSLagMaker().getTimeStampField() != null
            && m_forecaster.getTSLagMaker().getTimeStampField().length() > 0) {
          m_timeStampCombo.setSelectedItem(m_forecaster.getTSLagMaker()
              .getTimeStampField());
        }
      }

      int maxLag = m_forecaster.getTSLagMaker().getMaxLag();
      if (maxLag == 24) {
        m_periodicityCombo.setSelectedItem("Hourly");
      }
      if (maxLag == 7) {
        m_periodicityCombo.setSelectedItem("Daily");
      }
      if (maxLag == 5) {
        m_periodicityCombo.setSelectedItem("Weekly");
      }
      if (maxLag == 12) {
        m_periodicityCombo.setSelectedItem("Monthly");
      }
      if (maxLag == 4) {
        m_periodicityCombo.setSelectedItem("Quarterly");
      }
      if (maxLag == 5) {
        m_periodicityCombo.setSelectedItem("Yearly");
      } else {
        m_periodicityCombo.setSelectedItem("<Unknown>");
      }
    }
  }

  /**
   * Returns true if the forecaster is using a time stamp defined in the data
   * (rather than no time stamp or an artificially generated one)
   *
   * @return true if a native time stamp is in use.
   */
  public boolean isUsingANativeTimeStamp() {

    String selected = m_timeStampCombo.getSelectedItem().toString();

    if (!selected.equals("<None>")
        && !selected.equals("<Use an artificial time index>")) {
      return true;
    }

    return false;
  }

  /**
   * Get the selected time stamp field name.
   *
   * @return the selected time stamp field name.
   */
  public String getSelectedTimeStampField() {
    return m_timeStampCombo.getSelectedItem().toString();
  }

  /**
   * Get the WekaForecaster that is being configured.
   *
   * @return the WekaForecaster that is being configured.
   */
  public WekaForecaster getForecaster() {
    return m_forecaster;
  }

  /**
   * Set the horizon (i.e. the number of steps to forecast).
   *
   * @param horizon the number of steps to forecast.
   */
  public void setHorizon(int horizon) {
    m_horizonSpinner.setValue(horizon);
  }

  /**
   * Get the horizon (i.e. the number of steps to forecast)
   *
   * @return the number of steps to forecast
   */
  public int getHorizon() {
    SpinnerNumberModel model = (SpinnerNumberModel) m_horizonSpinner.getModel();
    return model.getNumber().intValue();
  }

  /**
   * Set the instances that will be used to train and/or test the forecaster.
   *
   * @param insts the instances for training/testing
   * @throws Exception if a problem occurs while configuring based on the
   *           supplied instances.
   */
  public void setInstances(Instances insts) throws Exception {
    m_instances = insts;

    String removeList = "";
    for (int i = 0; i < m_instances.numAttributes(); i++) {
      if (m_instances.attribute(i).isDate()
          || m_instances.attribute(i).isNominal()
          || m_instances.attribute(i).isString()
          || m_instances.attribute(i).isRelationValued()) {
        removeList += (i + 1) + ",";
      }
    }
    m_targetHeader = new Instances(m_instances, 0);
    if (removeList.length() > 0) {
      removeList = removeList.substring(0, removeList.lastIndexOf(","));

      Remove r = new Remove();
      r.setAttributeIndices(removeList);
      r.setInputFormat(m_instances);
      m_targetHeader = Filter.useFilter(m_instances, r);
      m_targetHeader = new Instances(m_targetHeader, 0);
    }
    m_targetPanel.setInstances(m_targetHeader);
    if (m_targetHeader.numAttributes() == 1) {
      // auto select the only target
      m_targetPanel.setSelectedAttributes(new boolean[] { true });
      if (m_parentPanel != null) {
        m_parentPanel.enableStartButton(true);
      }
    }
    setupTimeCombo();
    setupPeriodicityCombo();
  }

  /**
   * Initialize the time stamp combo box
   */
  protected void setupTimeCombo() {
    Vector<String> candidateNames = new Vector<String>();

    candidateNames.add("<Use an artificial time index>");
    candidateNames.add("<None>");
    String firstDateName = null;
    for (int i = 0; i < m_instances.numAttributes(); i++) {
      if (m_instances.attribute(i).isNumeric()) {
        candidateNames.add(m_instances.attribute(i).name());
      }
      if (m_instances.attribute(i).isDate() && firstDateName == null) {
        firstDateName = m_instances.attribute(i).name();
      }
    }

    m_timeStampCombo.setModel(new DefaultComboBoxModel(candidateNames));
    if (firstDateName != null) {
      m_timeStampCombo.setSelectedItem(firstDateName);
    }
  }

  /**
   * Initialize the periodicity combo box
   */
  protected void setupPeriodicityCombo() {
    Vector<String> candidateNames = new Vector<String>();

    candidateNames.add("<Unknown>");
    candidateNames.add("<Detect automatically>");
    candidateNames.add("Hourly");
    candidateNames.add("Daily");
    candidateNames.add("Weekly");
    candidateNames.add("Monthly");
    candidateNames.add("Quarterly");
    candidateNames.add("Yearly");

    m_periodicityCombo.setModel(new DefaultComboBoxModel(candidateNames));

    // check to see if a date is set in the time combo and, if so, select
    // <detect automatically> by default
    String timeSelected = (String) m_timeStampCombo.getSelectedItem();
    System.err.println("Selected " + timeSelected);
    if (timeSelected != null && timeSelected.length() > 0
        && !timeSelected.equals("<None>")
        && !timeSelected.equals("<Use an artificial time index>")
        && m_instances.attribute(timeSelected).isDate()) {
      m_periodicityCombo.setSelectedItem("<Detect automatically>");
    }
  }

  /**
   * Make some default settings for lag lengths based on the selected
   * periodicity.
   *
   * @param forecaster the forecaster to configure.
   */
  protected void checkPeriodicity(WekaForecaster forecaster) {

    if (m_advancedConfig != null) {
      String timeStampSelected = m_timeStampCombo.getSelectedItem().toString();
      String selectedP = m_periodicityCombo.getSelectedItem().toString();
      if (selectedP.equals("<Detect automatically>")
          && !timeStampSelected.equals("<Use an artificial time index>")
          && !timeStampSelected.equals("<None>") && forecaster != null) {

        forecaster.getTSLagMaker().setPeriodicity(
            TSLagMaker.Periodicity.UNKNOWN);
        TSLagMaker.PeriodicityHandler detected = TSLagMaker
            .determinePeriodicity(m_instances, forecaster.getTSLagMaker()
                .getTimeStampField(), forecaster.getTSLagMaker()
                .getPeriodicity());
        switch (detected.getPeriodicity()) {
        case HOURLY:
          selectedP = "Hourly";
          break;
        case DAILY:
          selectedP = "Daily";
          break;
        case WEEKLY:
          selectedP = "Weekly";
          break;
        case MONTHLY:
          selectedP = "Monthly";
          break;
        case QUARTERLY:
          selectedP = "Quarterly";
          break;
        case YEARLY:
          selectedP = "Yearly";
          break;
        }
      }

      if (forecaster != null) {
        if (selectedP.equals("Hourly")) {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.HOURLY);
        } else if (selectedP.equals("Daily")) {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.DAILY);
        } else if (selectedP.equals("Weekly")) {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.WEEKLY);
        } else if (selectedP.equals("Monthly")) {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.MONTHLY);
        } else if (selectedP.equals("Quarterly")) {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.QUARTERLY);
        } else if (selectedP.equals("Yearly")) {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.YEARLY);
        } else {
          forecaster.getTSLagMaker().setPeriodicity(
              TSLagMaker.Periodicity.UNKNOWN);
        }
        if (m_skipText.isEnabled() && m_skipText.getText() != null
            && m_skipText.getText().length() > 0) {
          forecaster.getTSLagMaker()
              .setSkipEntries(m_skipText.getText().trim());
        } else {
          forecaster.getTSLagMaker().setSkipEntries(""); // clear any previously
                                                         // set ones
        }
      }

      // only set these defaults if the user is not using custom lag lengths!
      if (!m_advancedConfig.isUsingCustomLags()) {
        if (forecaster != null) {
          forecaster.getTSLagMaker().setMinLag(1);
        }
        m_advancedConfig.m_minLagSpinner.setValue(1);

        if (selectedP.equals("Hourly")) {
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 24));
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 24));
        } else if (selectedP.equals("Daily")) {
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 7));
            // forecaster.getTSLagMaker().setSkipEntries("sat,sun");
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 7));
        } else if (selectedP.equals("Weekly")) {
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 52));
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 52));
        } else if (selectedP.equals("Monthly")) {
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 12));
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 12));
        } else if (selectedP.equals("Quarterly")) {
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 4));
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 4));
        } else if (selectedP.equals("Yearly")) {
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 5));
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 5));
        } else {
          // default (<Unknown>)
          if (forecaster != null) {
            forecaster.getTSLagMaker().setMaxLag(
                Math.min(m_instances.numInstances() / 2, 12));
          }
          m_advancedConfig.m_maxLagSpinner.setValue(Math.min(
              m_instances.numInstances() / 2, 12));
        }
      }

      if (!m_advancedConfig.getCustomizeDateDerivedPeriodics()
          && forecaster != null) {
        // configure defaults based on the above periodicity
        if (selectedP.equals("Hourly")) {
          forecaster.getTSLagMaker().setAddAMIndicator(true);
        } else if (selectedP.equals("Daily")) {
          forecaster.getTSLagMaker().setAddDayOfWeek(true);
          forecaster.getTSLagMaker().setAddWeekendIndicator(true);
        } else if (selectedP.equals("Weekly")) {
          forecaster.getTSLagMaker().setAddMonthOfYear(true);
          forecaster.getTSLagMaker().setAddQuarterOfYear(true);
        } else if (selectedP.equals("Monthly")) {
          forecaster.getTSLagMaker().setAddMonthOfYear(true);
          forecaster.getTSLagMaker().setAddQuarterOfYear(true);
        }
      }
    }
  }

  /**
   * Apply the selected settings of this panel to the supplied WekaForecaster.
   *
   * @param forecaster the WekaForecaster to configure
   * @throws Exception if there is a problem configuring.
   */
  public void applyToForecaster(WekaForecaster forecaster) throws Exception {
    if (forecaster != null) {
      TSLagMaker lagMaker = forecaster.getTSLagMaker();

      String selected = m_timeStampCombo.getSelectedItem().toString();
      if (!selected.equals("<Use an artificial time index>")
          && !selected.equals("<None>")) {
        lagMaker.setTimeStampField(selected);
      } else {
        lagMaker.setTimeStampField("");
      }

      if (selected.equals("<None>")) {
        lagMaker.setAdjustForTrends(false);
      } else {
        lagMaker.setAdjustForTrends(true);
      }

      if (m_periodicityCombo.getSelectedItem().toString()
          .equals("<Detect automatically>")
          && (selected.equals("<Use an artificial time index>") && !m_advancedConfig
              .isUsingCustomLags())) {

        /*
         * JOptionPane.showConfirmDialog(this,
         * "Cannot automatically detect periodicity" +
         * " when using an artificial time index.", "Forecasting",
         * JOptionPane.OK_OPTION);
         */
        throw new Exception(
            "Cannot automatically detect periodicity when using "
                + "an artificial time index.");
      }

      if (m_periodicityCombo.getSelectedItem().toString()
          .equals("<Detect automatically>")
          && !selected.equals("<Use an artificial time index>")
          && !selected.equals("<None>")
          && (!m_instances.attribute(selected).isDate() && !m_advancedConfig
              .isUsingCustomLags())) {
        throw new Exception(
            "Cannot automatically detect periodicity when using "
                + "a non-date time stamp (select manually or use custom lags.");
      }

      // reset any date-derived periodics to false
      lagMaker.setAddAMIndicator(false);
      lagMaker.setAddDayOfWeek(false);
      lagMaker.setAddMonthOfYear(false);
      lagMaker.setAddQuarterOfYear(false);
      lagMaker.setAddWeekendIndicator(false);
      if (!selected.equals("<None>")) {
        checkPeriodicity(forecaster);
      }

      if (m_computeConfidence.isSelected()) {
        forecaster.setCalculateConfIntervalsForForecasts(getHorizon());
        double confLevel = ((SpinnerNumberModel) m_confidenceLevelSpinner
            .getModel()).getNumber().doubleValue();
        forecaster.setConfidenceLevel(confLevel / 100.0);
      } else {
        forecaster.setCalculateConfIntervalsForForecasts(0);
      }

      int[] selectedTargets = m_targetPanel.getSelectedAttributes();
      StringBuffer targetBuf = new StringBuffer();
      for (int i = 0; i < selectedTargets.length; i++) {
        targetBuf.append(m_targetHeader.attribute(selectedTargets[i]).name())
            .append(",");
      }
      String temp = targetBuf.substring(0, targetBuf.lastIndexOf(","));
      if (temp.length() == 0) {
        throw new Exception("You must select some fields to forecast!");
      }
      forecaster.setFieldsToForecast(temp);
    }
  }

  /**
   * Apply the selected settings of this panel to the supplied evaluation module
   * with respect to the supplied forecaster
   *
   * @param eval the evaluation module to configure
   * @param forecaster the forecaster in use
   * @throws Exception if a problem occurs during configuration.
   */
  public void applyToEvaluation(TSEvaluation eval, WekaForecaster forecaster)
      throws Exception {
    int horizon = ((SpinnerNumberModel) m_horizonSpinner.getModel())
        .getNumber().intValue();
    if (horizon < 1) {
      throw new Exception("Must specify a non-zero number of steps to"
          + "forecast into the future");
    }

    eval.setHorizon(horizon);
    eval.setPrimeWindowSize(forecaster.getTSLagMaker().getMaxLag());
  }

  /**
   * Tests the simple config panel from the command line.
   *
   * @param args must contain the name of an arff file to load.
   */
  public static void main(String[] args) {

    try {
      if (args.length == 0) {
        throw new Exception("supply the name of an arff file");
      }
      Instances i = new Instances(new java.io.BufferedReader(
          new java.io.FileReader(args[0])));
      SimpleConfigPanel scp = new SimpleConfigPanel(null);
      scp.setInstances(i);
      final javax.swing.JFrame jf = new javax.swing.JFrame(
          "Simple Config Panel");
      jf.getContentPane().setLayout(new BorderLayout());
      jf.getContentPane().add(scp, BorderLayout.CENTER);
      jf.addWindowListener(new java.awt.event.WindowAdapter() {
        @Override
        public void windowClosing(java.awt.event.WindowEvent e) {
          jf.dispose();
          System.exit(0);
        }
      });
      jf.pack();
      jf.setVisible(true);
    } catch (Exception ex) {
      ex.printStackTrace();
      System.err.println(ex.getMessage());
    }
  }
}
TOP

Related Classes of weka.classifiers.timeseries.gui.SimpleConfigPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.