📄 clusteringtreeview.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 + -