⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clusteringtreeview.java

📁 一个数据挖掘软件ALPHAMINERR的整个过程的JAVA版源代码
💻 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.
 */

/*
 * Created on 2005-1-17
 *
 */
package eti.bi.alphaminer.patch.standard.operation.result.view;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.io.File;
import java.util.ArrayList;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.table.TableColumnModel;
import javax.swing.tree.DefaultMutableTreeNode;

import weka.core.AttributeStats;
import weka.core.Instances;
import weka.core.Utils;

import com.prudsys.pdm.Adapters.Weka.WekaCoreAdapter;
import com.prudsys.pdm.Core.CategoricalAttribute;
import com.prudsys.pdm.Core.Category;
import com.prudsys.pdm.Core.MiningAttribute;
import com.prudsys.pdm.Core.MiningException;
import com.prudsys.pdm.Core.NumericAttribute;
import com.prudsys.pdm.Input.MiningStoredData;
import com.prudsys.pdm.Input.MiningVector;
import com.prudsys.pdm.Models.Clustering.Cluster;
import com.prudsys.pdm.Models.Clustering.ClusteringMiningModel;

import eti.bi.alphaminer.operation.result.ResultView;
import eti.bi.alphaminer.operation.result.datamodel.SortingDataGridModel;
import eti.bi.alphaminer.operation.result.export.TextExporter;
import eti.bi.common.Locale.Resource;
import eti.bi.exception.AppException;
import eti.bi.exception.SysException;

/**
 * Take ClusteringMiningModel and its MiningAttribute[] as inputs.
 * Output a JPanel shown the cluster center information, as well
 * as the mean/standard deviation infor. for numerical attribute, 
 * the categorical distribution infor. for categorical attribute. 
 * 
 * @author TWang	On Jan 22, 2005.
 * 
 */
  public class ClusteringTreeView extends ResultView {
 
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	// JTree that contains the decision tree
	private JTree m_Tree;
	private StringBuffer m_outPutString = new StringBuffer("");
	
	// JTable that shows the cluster center vectors infor
	private JTable m_ClusterTable;  
	private String[] m_ClusterTableHeader;
	private Object[][] m_ClusterTableContent;
	private Class[] m_ClusterTableType; 
	
	// JScrollPane that contains the center vector table and tree
	private JScrollPane m_ScrollPane;
	private JScrollPane m_CenterPane;
	
	// The decision mining model object generated by the xelopes library
 	ClusteringMiningModel m_ClusteringModel;
 	MiningAttribute[] m_Attributes;  
 	
	public ClusteringTreeView(ClusteringMiningModel a_ClusteringModel, MiningAttribute[] a_Attributes) throws SysException, MiningException{
		super(Resource.srcStr("TreeView"));
	  
		m_ViewType = ResultView.TYPE_TEXT;
		
		m_ClusteringModel = a_ClusteringModel;  
		m_Attributes = a_Attributes;
	 
		m_ScrollPane = new JScrollPane();
		m_CenterPane = new JScrollPane();
		
		this.setLayout(new BorderLayout());
		this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
		this.add(m_CenterPane, BorderLayout.NORTH);
		this.add(m_ScrollPane, BorderLayout.CENTER);
 		createView();
 	}
	
	/** 
	 * create the cluster center vector table;  
	 */
	@SuppressWarnings("unchecked")
	private void createCenterVectorTable(ClusteringMiningModel a_clusteringModel, JScrollPane a_scrollPane) {
		//Local variables
		Cluster[] clusters = m_ClusteringModel.getClusters();  
		
		int column = m_Attributes.length + 1;
		m_ClusterTableType = new Class[column];
		m_ClusterTableHeader = new String[column]; 
		MiningAttribute attribute = null;
		
		// Prepare the output String
		m_outPutString.append("The Cluster Center Vectors:\n\n");
		
		// Init the table data type and table header 
		for (int i = 0; i < column; i++) {
			if (i == 0) {
				m_ClusterTableType[i] = String.class;
				m_ClusterTableHeader[i] = Resource.srcStr("CLUSTER");
				m_outPutString.append(m_ClusterTableHeader[i] + "\t\t");
				continue;
			}
			attribute = m_Attributes[i - 1];
			m_ClusterTableHeader[i] = attribute.getName();
			m_ClusterTableType[i] = String.class;
			m_outPutString.append(m_ClusterTableHeader[i] + "\t\t");
			
			if (attribute instanceof NumericAttribute) {
				
				int dataType = ((NumericAttribute) attribute).getDataType();
				
				if (dataType == NumericAttribute.DOUBLE)
					m_ClusterTableType[i] = Double.class;
				else if (dataType == NumericAttribute.FLOAT)
					m_ClusterTableType[i] = Float.class;
				else if (dataType == NumericAttribute.INTEGER)
					m_ClusterTableType[i] = Integer.class;
				else if (dataType == NumericAttribute.BOOLEAN)
					m_ClusterTableType[i] = Boolean.class; 
			} 
			else if (attribute instanceof CategoricalAttribute) {
				
				int dataType = ((CategoricalAttribute) attribute).getDataType();

				if (dataType == CategoricalAttribute.BOOLEAN)
					m_ClusterTableType[i] = Boolean.class; 
				else 
					m_ClusterTableType[i] = String.class; 
			} 
		}
		
		// The center vectors start from a new line. 
		m_outPutString.append("\n");

		// Table Data 
		Object[][] content = new Object[clusters.length][column];
		Vector<String> allVec = null;
		MiningVector vec = null;
		
		for (int i = 0; i < clusters.length; i++) {
			vec = clusters[i].getCenterVec();
			allVec = vec.toVector();
			allVec.add(0, clusters[i].getName());			
			content[i] = allVec.toArray();
			
			// Add the content of center vectors 
			m_outPutString.append(allVec.toString() + "\n");
		}
		m_ClusterTableContent = content;

		m_ClusterTable = new JTable();
		m_ClusterTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		//m_ClusterTable.setModel(new DataGridModel(m_ClusterTableContent, m_ClusterTableHeader, m_ClusterTableType));
		SortingDataGridModel model = new SortingDataGridModel(m_ClusterTableContent, m_ClusterTableHeader, m_ClusterTableType);
		m_ClusterTable.setModel(model);
		model.addMouseListenerToHeader(m_ClusterTable);

		
		// Adjust the column attribute
		TableColumnModel tcm = m_ClusterTable.getColumnModel();
		if (tcm.getColumn(0).getWidth() < 60) {
			for (int i = 0; i < tcm.getColumnCount(); i++)
				tcm.getColumn(i).setMinWidth(60);
			m_ClusterTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		} 
		tcm.getColumn(0).setPreferredWidth(70);  
	}
	
	/* 
	 * Create the view. 
	 */
	public void createView() throws SysException, MiningException
	{
		if (m_ClusteringModel == null){
			throw new SysException("clustering model is null");
		}
		if (m_ClusteringModel != null)
		{   
			createCenterVectorTable(m_ClusteringModel, m_CenterPane);
			m_CenterPane.setPreferredSize(new Dimension(200, 200));
			m_CenterPane.getViewport().add(m_ClusterTable);
			m_CenterPane.getViewport().setBackground(Color.WHITE);
			
			DefaultMutableTreeNode iRoot = new DefaultMutableTreeNode(Resource.srcStr("Root")); 
			createTree(iRoot);
			m_Tree = new JTree(iRoot);
			m_ScrollPane.setPreferredSize(new Dimension(200, 200));
			m_ScrollPane.setViewportView(m_Tree);
	 		m_Tree.updateUI();
		}
	}
	
	/**
	 * Transform Xelopes MiningStoredData into WEKA Instances
	 * 
	 * @param a_InputMiningStoredData
	 * @return Instances
	 * @throws MiningException
	 */
	public Instances transform(MiningStoredData a_InputMiningStoredData) throws MiningException
	{ 
		Instances wekaInstances;
		try {
			// Reset the cursor of the MiningStoredData set, so the transform starts from
			// the first reord. Otherwise, the returned object might be NULL.
			// By TWang. Jan 25, 2005.
			a_InputMiningStoredData.reset();
			wekaInstances = (Instances) WekaCoreAdapter.PDMMiningInputStream2WekaInstances(a_InputMiningStoredData); 
		} catch (Exception e) { 
			e.printStackTrace();
			throw new MiningException("Can not transform from MiningStoredData to Instances.");
		}
		return wekaInstances;
	}

	/**
	 * Create the Tree data structure. At the same time, create the output string
	 * in a tree format.
	 * 
	 * @param a_Root
	 * @throws MiningException
	 */
	@SuppressWarnings("unchecked")
	private void createTree(DefaultMutableTreeNode a_Root) throws MiningException { 
		
		m_outPutString.append("\n\n\nThe Clustering Tree View: \n");
		
		Cluster[] clusters = m_ClusteringModel.getClusters();		
		int clusterIndex;
		Instances instances = null;
		AttributeStats attributeStatus = null;
		
		for (clusterIndex = 0; clusterIndex < clusters.length; clusterIndex++) {
			// get the contained records, transform to WEKA instances.
			ArrayList instancesArrayList = new ArrayList(clusters[clusterIndex].getContainedVectors());
			if(instancesArrayList.size() >0){
				instances = transform(new MiningStoredData(instancesArrayList));
			 
				// add the cluster node
				DefaultMutableTreeNode clusterNode = null;
				DefaultMutableTreeNode attributeNode = null;
				clusterNode = new DefaultMutableTreeNode(clusters[clusterIndex].getName() + " ( " + instances.numInstances() +" records)");
				a_Root.add(clusterNode);  
				m_outPutString.append("\n|--" + clusterNode.toString() + "\n");
				
				// add the attribute nodes
				for (int j=0; j< m_Attributes.length; j++){
				  attributeStatus = instances.attributeStats(j);
				  
				  MiningAttribute attribute = m_Attributes[j];
				  String attName = attribute.getName(); 
				 
		          if (attribute instanceof NumericAttribute){
		          	    String mean = Utils.doubleToString(attributeStatus.numericStats.mean, 3);
		          	    attributeNode = new DefaultMutableTreeNode(attName + "(Mean: " + mean + ")");	          	    
			            clusterNode.add(attributeNode);
			            
			            m_outPutString.append("   |--" + attributeNode.toString() + "\n");
			            
			            String sd = Utils.doubleToString(attributeStatus.numericStats.stdDev, 3);
			            DefaultMutableTreeNode leafNode = new DefaultMutableTreeNode("Standard Deviation: " +  sd);
			            attributeNode.add(leafNode);
			             
			            m_outPutString.append("     |--" + leafNode.toString() + "\n");
		          }
		          else if (attribute instanceof CategoricalAttribute){
		          	   // add the attribute node
	  	               attributeNode = new DefaultMutableTreeNode(attName);	          	    
		               clusterNode.add(attributeNode); 
		               
		               m_outPutString.append("   |--" + attributeNode.toString() + "\n");
		               
		    		   ArrayList values = ((CategoricalAttribute) attribute).getValues();
		    		   
		    		   // first get the total number
		    		   int totalNum = 0;	    		  
		    		   for (int k=0; k<values.size(); k++){
		    		   	    totalNum += attributeStatus.nominalCounts[k];
		    		   }
		    		   // display the percentage and number for each leaf node
		    		   // BUG fix [Bug 16]: the CategoricalAttribute can have String/Double variables
		    		   // so use Object.toString() method to get the display name. Can not directly convert
		    		   // to String using (String)(Object a);
		    		   for (int k=0; k<values.size(); k++){
							String catLeaveName = ((Category) values.get(k)).getValue().toString();
						    int number = attributeStatus.nominalCounts[k];
							long percent = Math.round(100.0 * number / totalNum); 
							DefaultMutableTreeNode catLeaveNode = new DefaultMutableTreeNode(catLeaveName + " -> (" + number + ", " + percent + "%)");
							attributeNode.add(catLeaveNode);
							 
							m_outPutString.append("     |--" + catLeaveNode.toString() + "\n");
						}  
		          	
		          }	 
				}
			}
			else{
				// add the cluster node when the cluster has 0 records.
				DefaultMutableTreeNode clusterNode = null;
				clusterNode = new DefaultMutableTreeNode(clusters[clusterIndex].getName() + " ( " + 0 +" records)");
				a_Root.add(clusterNode);  
				m_outPutString.append("\n|--" + clusterNode.toString() + "\n");
			}
		}
	}
  	         		
  		  

	public void export() throws SysException, AppException
 	{
		// Use user home directory 
		File directory = new File(System.getProperty("user.dir"));
		
		// Create and initialize file chooser for pmml
		JFileChooser chooser = new JFileChooser(directory);
		chooser.setDialogTitle(Resource.srcStr("ExportTree"));
		chooser.setFileFilter(TextExporter.FILTER);
		chooser.setSelectedFile(TextExporter.DEFAULT_FILE);

		// pop up the file chooser dialog and return the file value
		int returnVal = chooser.showSaveDialog(this);	  
		if (returnVal == JFileChooser.APPROVE_OPTION) 
		{
			File exportFile = chooser.getSelectedFile();
			
			//<<tyleung 20/4/2005
			if (exportFile.exists()) {
				int option = JOptionPane
						.showConfirmDialog(
								(Component) this,
								"The file  \""
										+ exportFile.getName()
										+ "\""
										+ " already exists. Do you want to replace the existing file?",//						
								"AlphaMiner", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE);
				if (option != JOptionPane.CANCEL_OPTION) {
					if (option == JOptionPane.YES_OPTION) {
						if (m_outPutString!=null)
						{
							TextExporter aExporter = new TextExporter(m_outPutString.toString(), exportFile, true);
							aExporter.export();
						}
						
					}else{
						returnVal = chooser.showSaveDialog(this);
					}
				}
			}else {
			    if (m_outPutString!=null)
				{
					TextExporter aExporter = new TextExporter(m_outPutString.toString(), exportFile, true);
					aExporter.export();
				}
			}
			//tyleung 20/4/2005>>
		}		
 	}
}

⌨️ 快捷键说明

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