Package weka.gui.beans

Source Code of weka.gui.beans.TimeSeriesForecastingCustomizer

/*
* Copyright (c) 2011 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.
*/

/*
*    TimeSeriesForecastingCustomizer.java
*    Copyright (C) 2011 Pentaho Corporation
*
*/

package weka.gui.beans;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.Customizer;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

import weka.classifiers.timeseries.WekaForecaster;
import weka.core.Environment;
import weka.core.Instances;
import weka.gui.PropertySheetPanel;

/**
* Customizer for the TimeSeriesForecasting bean
*
* @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
* @version $Revision: 49983 $
*
*/
public class TimeSeriesForecastingCustomizer extends JPanel implements
    Customizer, CustomizerClosingListener, CustomizerCloseRequester {
 
  /**
   * For serialization
   */
  private static final long serialVersionUID = -8638861579301145591L;

  /** The forecaster to customize */
  protected TimeSeriesForecasting m_forecaster = null;
 
  /** The underlying WekaForecaster */
  protected WekaForecaster m_forecastingModel = null;
 
  /** The header of the data used to train the forecaster */
  protected Instances m_header;
 
  /** Handles the text field and file browser */
  protected FileEnvironmentField m_filenameField =
    new FileEnvironmentField();

  /** Label for the num steps field */
  protected JLabel m_numStepsLab;
 
  /** Number of steps to forecast */
  protected EnvironmentField m_numStepsToForecast =
    new EnvironmentField();
 
  /** Label for the artificial time stamp offset fields */
  protected JLabel m_artificialLab;
 
  /**
   * Number of steps beyond the end of the training data that incoming
   * historical priming data is
   */
  protected EnvironmentField m_artificialOffset =
    new EnvironmentField();
 
  /** Rebuild the forecaster ? */
  protected JCheckBox m_rebuildForecasterCheck = new JCheckBox();
 
  /** Label for the save forecaster field */
  protected JLabel m_saveLab;
 
  /** Text field for the filename to save the forecaster to */
  protected FileEnvironmentField m_saveFilenameField =
    new FileEnvironmentField();
 
  /** The text area to display the model in */
  protected JTextArea m_modelDisplay = new JTextArea(20, 60);
 
  /** Property sheet panel used to get the "About" panel for global info */
  protected PropertySheetPanel m_sheetPanel = new PropertySheetPanel();

  /** Environment variables to use */
  protected transient Environment m_env = Environment.getSystemWide();
 
  /** Frame containing us */
  protected Window m_parentWindow; 
 
  /**
   * Constructor
   */
  public TimeSeriesForecastingCustomizer() {
    setLayout(new BorderLayout());
   
    m_filenameField.addPropertyChangeListener(new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        // first check if the field is blank (i.e. been cleared) and
        // we have a loaded model - if so then just return. We'll
        // encode the forecaster to base 64 and clear the filename
        // field when the customizer closes.
        if (TimeSeriesForecasting.isEmpty(m_filenameField.getText())) {
          return;
        }
       
        loadModel();
        if (m_forecastingModel != null) {
          m_modelDisplay.setText(m_forecastingModel.toString());
          checkIfModelIsUsingArtificialTimeStamp();
          checkIfModelIsUsingOverlayData();
        }
      }
    });
  }
 
  /**
   * Set the object to edit
   *
   * @param object the object to edit
   */
  public void setObject(Object object) {
    setupLayout();
   
    m_forecaster = (TimeSeriesForecasting)object;
    m_sheetPanel.setTarget(m_forecaster);
    String loadFilename = m_forecaster.getFilename();
    if (!TimeSeriesForecasting.isEmpty(loadFilename) &&
        !loadFilename.equals("-NONE-")) {
      m_filenameField.setText(loadFilename);
      loadModel();
    } else {
      String encodedForecaster = m_forecaster.getEncodedForecaster();
      if (!TimeSeriesForecasting.isEmpty(encodedForecaster) &&
          !encodedForecaster.equals("-NONE-")) {
        try {
          List<Object> model = TimeSeriesForecasting.getForecaster(encodedForecaster);
          if (model != null) {
            m_forecastingModel = (WekaForecaster)model.get(0);
            m_header = (Instances)model.get(1);
            m_modelDisplay.setText(m_forecastingModel.toString());
          }
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
   
    if (!TimeSeriesForecasting.isEmpty(m_forecaster.getSaveFilename())) {
      m_saveFilenameField.setText(m_forecaster.getSaveFilename());
    }
    m_numStepsToForecast.setText(m_forecaster.getNumStepsToForecast());
    m_artificialOffset.setText(m_forecaster.getArtificialTimeStartOffset());
    m_rebuildForecasterCheck.setSelected(m_forecaster.getRebuildForecaster());
   
    m_saveLab.setEnabled(m_rebuildForecasterCheck.isSelected());
    m_saveFilenameField.setEnabled(m_rebuildForecasterCheck.isSelected());
   

    checkIfModelIsUsingArtificialTimeStamp();
    checkIfModelIsUsingOverlayData();
  }
 
  private void checkIfModelIsUsingArtificialTimeStamp() {
    if (m_forecastingModel != null) {
      boolean usingA = m_forecastingModel.getTSLagMaker().isUsingAnArtificialTimeIndex();
      m_artificialLab.setEnabled(usingA);
      m_artificialOffset.setEnabled(usingA);
    }
  }
 
  private void checkIfModelIsUsingOverlayData() {
    if (m_forecastingModel != null) {
      if (m_forecastingModel.isUsingOverlayData()) {
        m_numStepsToForecast.setEnabled(false);
        m_numStepsLab.setEnabled(false);
        // remove any number set here since size of the overlay data (with missing
        // targets set) determines the number of steps that will be forecast
        m_numStepsToForecast.setText("");
      } else {
        m_numStepsToForecast.setEnabled(true);
        m_numStepsLab.setEnabled(true);
      }
    }
  }
 
  private void setupLayout() {
    removeAll();
   
    JTabbedPane tabHolder = new JTabbedPane();
   
    JPanel modelFilePanel = new JPanel();
    modelFilePanel.setLayout(new BorderLayout());
    JPanel tempP1 = new JPanel();
   
    tempP1.setLayout(new GridLayout(5, 2));
    JLabel fileLab = new JLabel("Load/import forecaster", SwingConstants.RIGHT);
    tempP1.add(fileLab); tempP1.add(m_filenameField);
    m_numStepsLab = new JLabel("Number of steps to forecast", SwingConstants.RIGHT);
    tempP1.add(m_numStepsLab); tempP1.add(m_numStepsToForecast);
    m_artificialLab = new JLabel("Number of historical instances " +
        "beyond end of training data", SwingConstants.RIGHT);
    tempP1.add(m_artificialLab); tempP1.add(m_artificialOffset);
    JLabel rebuildLab = new JLabel("Rebuild/reestimate on incoming data",
        SwingConstants.RIGHT);
    tempP1.add(rebuildLab); tempP1.add(m_rebuildForecasterCheck);
    m_saveLab = new JLabel("Save forecaster", SwingConstants.RIGHT);
    tempP1.add(m_saveLab); tempP1.add(m_saveFilenameField);   
   
    modelFilePanel.add(tempP1, BorderLayout.NORTH);
   
    tabHolder.addTab("Model file", modelFilePanel);
   
    add(tabHolder, BorderLayout.CENTER);
   
    JPanel modelPanel = new JPanel();   
    modelPanel.setLayout(new BorderLayout());
    m_modelDisplay.setEditable(false);
    m_modelDisplay.setFont(new Font("Monospaced", Font.PLAIN, 12));
    m_modelDisplay.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    JScrollPane scrollPane = new JScrollPane(m_modelDisplay);
   
    modelPanel.add(scrollPane, BorderLayout.CENTER);
   
    tabHolder.addTab("Model", modelPanel);
   
    JButton okBut = new JButton("OK");
    JButton cancelBut = new JButton("Cancel");
    JPanel butHolder1 = new JPanel();
    butHolder1.setLayout(new GridLayout(1, 2));
    butHolder1.add(okBut); butHolder1.add(cancelBut);
    JPanel butHolder2 = new JPanel();
    butHolder2.setLayout(new GridLayout(1, 3));
    butHolder2.add(new JPanel());
    butHolder2.add(butHolder1);
    butHolder2.add(new JPanel());
   
    add(butHolder2, BorderLayout.SOUTH);
   
    cancelBut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        // just close the dialog
        m_parentWindow.dispose();
      }
    });
   
    okBut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        // apply the changes
        customizerClosing();
        m_parentWindow.dispose();
      }
    });
   
    m_saveLab.setEnabled(false);
    m_saveFilenameField.setEnabled(false);
    m_rebuildForecasterCheck.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        m_saveFilenameField.setEnabled(m_rebuildForecasterCheck.isSelected());
        m_saveLab.setEnabled(m_rebuildForecasterCheck.isSelected());
      }
    });
  }
 
  private void loadModel() {
    if (!TimeSeriesForecasting.isEmpty(m_filenameField.getText())) {
      try {
        String filename = m_filenameField.getText();
        try {
          if (m_env == null) {
            m_env = Environment.getSystemWide();
          }
          filename = m_env.substitute(filename);                   
        } catch (Exception ex) {
          // Quietly ignore any problems with environment variables.
          // A variable might not be set now, but could be when the
          // component is executed at a later time
        }
        File theFile = new File(filename);
        if (theFile.isFile()) {
          ObjectInputStream is =
            new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)));
          m_forecastingModel = (WekaForecaster)is.readObject();
          m_header = (Instances)is.readObject();
//          Instances header = (Instances)is.readObject();
          is.close();         
        }
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }
  }
 
  /**
   * Set the environment variables to use.
   *
   * @param env the environment variables to use
   */
  public void setEnvironment(Environment env) {
    m_env = env;
    m_filenameField.setEnvironment(env);
    m_numStepsToForecast.setEnvironment(env);
    m_artificialOffset.setEnvironment(env);
    m_saveFilenameField.setEnvironment(env);
  }

  /**
   * Called when the window containing the customizer is closed
   */
  public void customizerClosing() {
    if (m_forecaster != null) {
      if (!TimeSeriesForecasting.isEmpty(m_filenameField.getText())) {
        m_forecaster.setFilename(m_filenameField.getText());
        // clear base64 field with -NONE-
        m_forecaster.setEncodedForecaster("-NONE-");
      } else {
        if (m_forecastingModel != null) {
          // set base64 field and clear filename field with -NONE-
          try {
            String encodedModel =
              TimeSeriesForecasting.encodeForecasterToBase64(m_forecastingModel, m_header);
            m_forecaster.setFilename("-NONE-");
            m_forecaster.setEncodedForecaster(encodedModel);
          } catch (Exception ex) {
            ex.printStackTrace();
          }         
        }       
      }
      m_forecaster.setRebuildForecaster(m_rebuildForecasterCheck.isSelected());
      m_forecaster.setNumStepsToForecast(m_numStepsToForecast.getText());
      m_forecaster.setArtificialTimeStartOffset(m_artificialOffset.getText());
      if (m_rebuildForecasterCheck.isSelected() &&
          !TimeSeriesForecasting.isEmpty(m_saveFilenameField.getText())) {
        m_forecaster.setSaveFilename(m_saveFilenameField.getText());
      } else {
        m_forecaster.setSaveFilename("");
      }
    }
  }

  /**
   * Set the Window that contains this customizer
   *
   * @param parent the parent Window
   */
  public void setParentWindow(Window parent) {
    m_parentWindow = parent;
  }
}
TOP

Related Classes of weka.gui.beans.TimeSeriesForecastingCustomizer

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.