boundarypanel.java

来自「Weka」· Java 代码 · 共 1,224 行 · 第 1/3 页

JAVA
1,224
字号
/* *    This program is free software; you can redistribute it and/or modify *    it under the terms of the GNU General Public License as published by *    the Free Software Foundation; either version 2 of the License, or *    (at your option) any later version. * *    This program 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 General Public License for more details. * *    You should have received a copy of the GNU General Public License *    along with this program; if not, write to the Free Software *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* *   BoundaryPanel.java *   Copyright (C) 2002 University of Waikato, Hamilton, New Zealand * */package weka.gui.boundaryvisualizer;import weka.classifiers.Classifier;import weka.core.FastVector;import weka.core.Instance;import weka.core.Instances;import weka.core.Utils;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.RenderingHints;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.image.BufferedImage;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.util.Random;import java.util.Vector;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.ToolTipManager;import com.sun.image.codec.jpeg.JPEGCodec;import com.sun.image.codec.jpeg.JPEGEncodeParam;import com.sun.image.codec.jpeg.JPEGImageEncoder;/** * BoundaryPanel. A class to handle the plotting operations * associated with generating a 2D picture of a classifier's decision * boundaries. * * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a> * @version $Revision: 1.22 $ * @since 1.0 * @see JPanel */public class BoundaryPanel  extends JPanel {  /** for serialization */  private static final long serialVersionUID = -8499445518744770458L;    /** default colours for classes */  public static final Color [] DEFAULT_COLORS = {    Color.red,    Color.green,    Color.blue,    new Color(0, 255, 255), // cyan    new Color(255, 0, 255), // pink    new Color(255, 255, 0), // yellow    new Color(255, 255, 255), //white    new Color(0, 0, 0)};      /** The distance we can click away from a point in the GUI and still remove it. */  public static final double REMOVE_POINT_RADIUS = 7.0;  protected FastVector m_Colors = new FastVector();  /** training data */  protected Instances m_trainingData;  /** distribution classifier to use */  protected Classifier m_classifier;  /** data generator to use */  protected DataGenerator m_dataGenerator;  /** index of the class attribute */  private int m_classIndex = -1;  // attributes for visualizing on  protected int m_xAttribute;  protected int m_yAttribute;  // min, max and ranges of these attributes  protected double m_minX;  protected double m_minY;  protected double m_maxX;  protected double m_maxY;  private double m_rangeX;  private double m_rangeY;  // pixel width and height in terms of attribute values  protected double m_pixHeight;  protected double m_pixWidth;  /** used for offscreen drawing */  protected Image m_osi = null;  // width and height of the display area  protected int m_panelWidth;  protected int m_panelHeight;  // number of samples to take from each region in the fixed dimensions  protected int m_numOfSamplesPerRegion = 2;  // number of samples per kernel = base ^ (# non-fixed dimensions)  protected int m_numOfSamplesPerGenerator;  protected double m_samplesBase = 2.0;  /** listeners to be notified when plot is complete */  private Vector m_listeners = new Vector();  /**   * small inner class for rendering the bitmap on to   */  private class PlotPanel    extends JPanel {    /** for serialization */    private static final long serialVersionUID = 743629498352235060L;        public PlotPanel() {      this.setToolTipText("");    }        public void paintComponent(Graphics g) {      super.paintComponent(g);      if (m_osi != null) {	g.drawImage(m_osi,0,0,this);      }    }        public String getToolTipText(MouseEvent event) {      if (m_probabilityCache == null) {	return null;      }            if (m_probabilityCache[event.getY()][event.getX()] == null) {	return null;      }            String pVec = "(X: "	+Utils.doubleToString(convertFromPanelX((double)event.getX()), 2)	+" Y: "	+Utils.doubleToString(convertFromPanelY((double)event.getY()), 2)+") ";      // construct a string holding the probability vector      for (int i = 0; i < m_trainingData.classAttribute().numValues(); i++) {	pVec += 	  Utils.	  doubleToString(m_probabilityCache[event.getY()][event.getX()][i],			 3)+" ";      }      return pVec;    }  }  /** the actual plotting area */  private PlotPanel m_plotPanel = new PlotPanel();  /** thread for running the plotting operation in */  private Thread m_plotThread = null;  /** Stop the plotting thread */  protected boolean m_stopPlotting = false;  /** Stop any replotting threads */  protected boolean m_stopReplotting = false;  // Used by replotting threads to pause and resume the main plot thread  private Double m_dummy = new Double(1.0);  private boolean m_pausePlotting = false;  /** what size of tile is currently being plotted */  private int m_size = 1;  /** is the main plot thread performing the initial coarse tiling */  private boolean m_initialTiling;  /** A random number generator  */  private Random m_random = null;  /** cache of probabilities for fast replotting */  protected double [][][] m_probabilityCache;  /** plot the training data */  protected boolean m_plotTrainingData = true;  /**   * Creates a new <code>BoundaryPanel</code> instance.   *   * @param panelWidth the width in pixels of the panel   * @param panelHeight the height in pixels of the panel   */  public BoundaryPanel(int panelWidth, int panelHeight) {    ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE);    m_panelWidth = panelWidth;    m_panelHeight = panelHeight;    setLayout(new BorderLayout());    m_plotPanel.setMinimumSize(new Dimension(m_panelWidth, m_panelHeight));    m_plotPanel.setPreferredSize(new Dimension(m_panelWidth, m_panelHeight));    m_plotPanel.setMaximumSize(new Dimension(m_panelWidth, m_panelHeight));    add(m_plotPanel, BorderLayout.CENTER);    setPreferredSize(m_plotPanel.getPreferredSize());    setMaximumSize(m_plotPanel.getMaximumSize());    setMinimumSize(m_plotPanel.getMinimumSize());    m_random = new Random(1);    for (int i = 0; i < DEFAULT_COLORS.length; i++) {      m_Colors.addElement(new Color(DEFAULT_COLORS[i].getRed(),				    DEFAULT_COLORS[i].getGreen(),				    DEFAULT_COLORS[i].getBlue()));    }    m_probabilityCache = new double[m_panelHeight][m_panelWidth][];      }  /**   * Set the number of points to uniformly sample from a region (fixed   * dimensions).   *   * @param num an <code>int</code> value   */  public void setNumSamplesPerRegion(int num) {    m_numOfSamplesPerRegion = num;  }  /**   * Get the number of points to sample from a region (fixed dimensions).   *   * @return an <code>int</code> value   */  public int getNumSamplesPerRegion() {    return m_numOfSamplesPerRegion;  }  /**   * Set the base for computing the number of samples to obtain from each   * generator. number of samples = base ^ (# non fixed dimensions)   *   * @param ksb a <code>double</code> value   */  public void setGeneratorSamplesBase(double ksb) {    m_samplesBase = ksb;  }  /**   * Get the base used for computing the number of samples to obtain from   * each generator   *   * @return a <code>double</code> value   */  public double getGeneratorSamplesBase() {    return m_samplesBase;  }  /**   * Set up the off screen bitmap for rendering to   */  protected void initialize() {    int iwidth = m_plotPanel.getWidth();    int iheight = m_plotPanel.getHeight();    //    System.err.println(iwidth+" "+iheight);    m_osi = m_plotPanel.createImage(iwidth, iheight);    Graphics m = m_osi.getGraphics();    m.fillRect(0,0,iwidth,iheight);  }  /**   * Stop the plotting thread   */  public void stopPlotting() {    m_stopPlotting = true;    try {    	m_plotThread.join(100);    } catch (Exception e){};  }  /** Set up the bounds of our graphic based by finding the smallest reasonable      area in the instance space to surround our data points.  */  public void computeMinMaxAtts() {    m_minX = Double.MAX_VALUE;    m_minY = Double.MAX_VALUE;    m_maxX = Double.MIN_VALUE;    m_maxY = Double.MIN_VALUE;        boolean allPointsLessThanOne = true;        if (m_trainingData.numInstances() == 0) {      m_minX = m_minY = 0.0;      m_maxX = m_maxY = 1.0;    }    else    {	for (int i = 0; i < m_trainingData.numInstances(); i++) {		Instance inst = m_trainingData.instance(i);		double x = inst.value(m_xAttribute);		double y = inst.value(m_yAttribute);		if (x != Instance.missingValue() && y != Instance.missingValue()) {			if (x < m_minX) {			m_minX = x;			}			if (x > m_maxX) {			m_maxX = x;			}					if (y < m_minY) {			m_minY = y;			}			if (y > m_maxY) {			m_maxY = y;			}			if (x > 1.0 || y > 1.0)				allPointsLessThanOne = false;		}	}    }        if (m_minX == m_maxX)    	m_minX = 0;    if (m_minY == m_maxY)    	m_minY = 0;    if (m_minX == Double.MAX_VALUE)    	m_minX = 0;    if (m_minY == Double.MAX_VALUE)    	m_minY = 0;    if (m_maxX == Double.MIN_VALUE)    	m_maxX = 1;    if (m_maxY == Double.MIN_VALUE)    	m_maxY = 1;    if (allPointsLessThanOne) {    	m_minX = m_minY = 0.0;    	m_maxX = m_maxY = 1.0;    }                m_rangeX = (m_maxX - m_minX);    m_rangeY = (m_maxY - m_minY);        m_pixWidth = m_rangeX / (double)m_panelWidth;    m_pixHeight = m_rangeY / (double) m_panelHeight;  }  /**   * Return a random x attribute value contained within   * the pix'th horizontal pixel   *   * @param pix the horizontal pixel number   * @return a value in attribute space   */  private double getRandomX(int pix) {    double minPix =  m_minX + (pix * m_pixWidth);    return minPix + m_random.nextDouble() * m_pixWidth;  }  /**   * Return a random y attribute value contained within   * the pix'th vertical pixel   *   * @param pix the vertical pixel number   * @return a value in attribute space   */  private double getRandomY(int pix) {        double minPix = m_minY + (pix * m_pixHeight);        return minPix +  m_random.nextDouble() * m_pixHeight;  }    /**   * Start the plotting thread   *   * @exception Exception if an error occurs   */  public void start() throws Exception {    m_numOfSamplesPerGenerator =       (int)Math.pow(m_samplesBase, m_trainingData.numAttributes()-3);    m_stopReplotting = true;    if (m_trainingData == null) {      throw new Exception("No training data set (BoundaryPanel)");    }    if (m_classifier == null) {      throw new Exception("No classifier set (BoundaryPanel)");    }

⌨️ 快捷键说明

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