/* * 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()); } } }