package seqrulemining; import java.io.File; import java.io.IOException; import java.util.Iterator; import org.knime.core.data.DataCell; import org.knime.core.data.DataColumnSpec; import org.knime.core.data.DataColumnSpecCreator; import org.knime.core.data.DataRow; import org.knime.core.data.DataTableSpec; import org.knime.core.data.RowIterator; import org.knime.core.data.RowKey; import org.knime.core.data.def.DefaultRow; import org.knime.core.data.def.DoubleCell; import org.knime.core.data.def.IntCell; import org.knime.core.data.def.StringCell; import org.knime.core.node.BufferedDataContainer; import org.knime.core.node.BufferedDataTable; import org.knime.core.node.CanceledExecutionException; import org.knime.core.node.defaultnodesettings.SettingsModelDoubleBounded; import org.knime.core.node.defaultnodesettings.SettingsModelIntegerBounded; import org.knime.core.node.defaultnodesettings.SettingsModelString; import org.knime.core.node.ExecutionContext; import org.knime.core.node.ExecutionMonitor; import org.knime.core.node.InvalidSettingsException; import org.knime.core.node.NodeLogger; import org.knime.core.node.NodeModel; import org.knime.core.node.NodeSettingsRO; import org.knime.core.node.NodeSettingsWO; import ca.pfv.spmf.algorithms.sequential_rules.topseqrules_and_tns.AlgoTNS; import ca.pfv.spmf.algorithms.sequential_rules.topseqrules_and_tns.Rule; import ca.pfv.spmf.datastructures.redblacktree.RedBlackTree; import ca.pfv.spmf.input.sequence_database_array_integers.SequenceDatabase; /** * <code>NodeModel</code> for the "TNSRuleMiner" node, mining the Top-K * Non-Redundant Sequential Rules (TNS) from the spmf-library * (http://www.philippe-fournier-viger.com/spmf) * * @author Manuel Wildner */ public class TNSRuleMinerNodeModel extends NodeModel { // the logger instance private static final NodeLogger logger = NodeLogger .getLogger(TNSRuleMinerNodeModel.class); /** * The settings models for the dialog components to handle user settings. */ private SettingsModelIntegerBounded m_kSelection = createKModel(); private SettingsModelDoubleBounded m_minConfSelection = createMinConfModel(); private SettingsModelIntegerBounded m_deltaSelection = createDeltaModel(); private SettingsModelString m_SeqColumnSelection = createSeqColumnModel(); private int k = 10; private double minConf = 0.5; private int delta = 2; /** * Constructor for the node model. */ protected TNSRuleMinerNodeModel() { super(1, 1); } /** * {@inheritDoc} */ @Override protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception { if (inData == null || inData[0] == null) { return inData; } // stores meta data about the table DataTableSpec inDataSpec = inData[0].getDataTableSpec(); int rowNum = inData[0].getRowCount(); /* * store the positions of needed columns. */ int seqColPos = inDataSpec.findColumnIndex(m_SeqColumnSelection .getStringValue()); /* * update k, minconf and delta which is specified by the user */ k = m_kSelection.getIntValue(); minConf = m_minConfSelection.getDoubleValue(); delta = m_deltaSelection.getIntValue(); RowIterator rowIter = inData[0].iterator(); DataColumnSpec[] allColSpecs = new DataColumnSpec[3]; allColSpecs[0] = new DataColumnSpecCreator("Rule", StringCell.TYPE) .createSpec(); allColSpecs[1] = new DataColumnSpecCreator("Support(absolute)", DoubleCell.TYPE) .createSpec(); allColSpecs[2] = new DataColumnSpecCreator("Confidence", DoubleCell.TYPE) .createSpec(); DataTableSpec outputSpec = new DataTableSpec(allColSpecs); SequenceDatabase database = new SequenceDatabase(); while (rowIter.hasNext()) { String[] inputTokens = ((StringCell) (rowIter.next() .getCell(seqColPos))).getStringValue().split(" "); database.addSequence(inputTokens); // for (String s : inputTokens) { // System.out.print(s + " "); // } // System.out.println(""); } AlgoTNS algoTNS = new AlgoTNS(); RedBlackTree<Rule> kRules = algoTNS.runAlgorithm(k, database, minConf, delta); // algoTNS.writeResultTofile(".//output.txt"); algoTNS.printStats(); BufferedDataContainer container = exec.createDataContainer(outputSpec); Iterator<Rule> rulesIter = kRules.iterator(); int rowCount = 0; while (rulesIter.hasNext()) { Rule rule = (Rule) rulesIter.next(); RowKey key = new RowKey("Row " + rowCount); // the cells of the current row, the types of the cells must // match the column spec (see above) DataCell[] cells = new DataCell[3]; cells[0] = new StringCell(rule.toString()); cells[1] = new DoubleCell(rule.getAbsoluteSupport()); cells[2] = new DoubleCell(rule.getConfidence()); DataRow row = new DefaultRow(key, cells); container.addRowToTable(row); // check if the execution monitor was canceled exec.checkCanceled(); exec.setProgress(rowCount / (double) rowNum, "Adding row " + rowCount); rowCount++; } container.close(); BufferedDataTable out = container.getTable(); return new BufferedDataTable[] { out }; } /** * {@inheritDoc} */ @Override protected void reset() { // TODO Code executed on reset. // Models build during execute are cleared here. // Also data handled in load/saveInternals will be erased here. } /** * {@inheritDoc} */ @Override protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException { // TODO: check if user settings are available, fit to the incoming // table structure, and the incoming types are feasible for the node // to execute. If the node can execute in its current state return // the spec of its output data table(s) (if you can, otherwise an array // with null elements), or throw an exception with a useful user message return new DataTableSpec[] { null }; } /** * {@inheritDoc} */ @Override protected void saveSettingsTo(final NodeSettingsWO settings) { m_deltaSelection.saveSettingsTo(settings); m_kSelection.saveSettingsTo(settings); m_minConfSelection.saveSettingsTo(settings); m_SeqColumnSelection.saveSettingsTo(settings); } /** * {@inheritDoc} */ @Override protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException { m_deltaSelection.loadSettingsFrom(settings); m_kSelection.loadSettingsFrom(settings); m_minConfSelection.loadSettingsFrom(settings); m_SeqColumnSelection.loadSettingsFrom(settings); } /** * {@inheritDoc} */ @Override protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException { m_deltaSelection.validateSettings(settings); m_kSelection.validateSettings(settings); m_minConfSelection.validateSettings(settings); m_SeqColumnSelection.validateSettings(settings); } /** * {@inheritDoc} */ @Override protected void loadInternals(final File internDir, final ExecutionMonitor exec) throws IOException, CanceledExecutionException { // TODO load internal data. // Everything handed to output ports is loaded automatically (data // returned by the execute method, models loaded in loadModelContent, // and user settings set through loadSettingsFrom - is all taken care // of). Load here only the other internals that need to be restored // (e.g. data used by the views). } /** * {@inheritDoc} */ @Override protected void saveInternals(final File internDir, final ExecutionMonitor exec) throws IOException, CanceledExecutionException { // TODO save internal models. // Everything written to output ports is saved automatically (data // returned by the execute method, models saved in the saveModelContent, // and user settings saved through saveSettingsTo - is all taken care // of). Save here only the other internals that need to be preserved // (e.g. data used by the views). } /** * Creation of the different Settings Models to communicate with the node * dialog */ protected static SettingsModelString createSeqColumnModel() { return new SettingsModelString("seq_column_selection", "POLYLINE"); } protected static SettingsModelIntegerBounded createKModel() { return new SettingsModelIntegerBounded("k_selection", 20, 1, Integer.MAX_VALUE); } protected static SettingsModelDoubleBounded createMinConfModel() { return new SettingsModelDoubleBounded("min_conf_selection", 0.5, 0, 1); } protected static SettingsModelIntegerBounded createDeltaModel() { return new SettingsModelIntegerBounded("delta_selection", 2, 0, Integer.MAX_VALUE); } }