📄 boundarypanel.java
字号:
/* * 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 Mark Hall * */package weka.gui.boundaryvisualizer;import java.awt.*;import java.awt.event.*;import javax.swing.JPanel;import javax.swing.JOptionPane;import javax.swing.ToolTipManager;import java.util.Vector;import java.util.Random;import com.sun.image.codec.jpeg.*;import java.awt.image.*;import java.io.*;import weka.core.*;import weka.classifiers.Classifier;import weka.classifiers.bayes.NaiveBayesSimple;import weka.classifiers.bayes.NaiveBayes;import weka.classifiers.trees.J48;import weka.classifiers.lazy.IBk;import weka.classifiers.functions.Logistic;import weka.clusterers.EM;import weka.filters.Filter;import weka.filters.unsupervised.attribute.Remove;import weka.filters.unsupervised.attribute.Add;/** * 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.20 $ * @since 1.0 * @see JPanel */public class BoundaryPanel extends JPanel { // 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 { 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)"); } if (m_dataGenerator == null) { throw new Exception("No data generator set (BoundaryPanel)"); } if (m_trainingData.attribute(m_xAttribute).isNominal() || m_trainingData.attribute(m_yAttribute).isNominal()) { throw new Exception("Visualization dimensions must be numeric " +"(BoundaryPanel)"); } computeMinMaxAtts(); startPlotThread(); /*if (m_plotThread == null) { m_plotThread = new PlotThread();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -