Categories

Versions

You are viewing the RapidMiner Developers documentation for version 9.4 - Check here for latest version

Adding Input and Output Ports

To define ports, you simply add them as private variables using the following lines of code:

private InputPort exampleSetInput = getInputPorts().createPort("example set");
private OutputPort exampleSetOutput = getOutputPorts().createPort("example set");

You can add more input ports, but you must set unique names for input ports and output ports for each operator. To follow the name convention, write the names in lower case and use blanks to separate words.

To fill the doWork() method with content, add a new attribute with random values from 1 to 10 to the example set received from the input port. You receive the example set by calling:

ExampleSet exampleSet = exampleSetInput.getData(ExampleSet.class);

Now, create a new attribute by using the AttributeFactory. Define a name for the new attribute and select the type of the new attribute. The class Ontology contains constants for the different types.

// get attributes from example set
Attributes attributes = exampleSet.getAttributes();
// create a new attribute
String newName = "newAttribute";
// define the name and the type of the new attribute
// valid types are 
// - nominal (sub types: binominal, polynominal, string, file_path)
// - date_time (sub types: date, time)
// - numerical (sub types: integer, real)
Attribute targetAttribute = AttributeFactory.createAttribute(newName, Ontology.REAL);

Set the table index of the new attribute and add it to the attributes of the example set.

targetAttribute.setTableIndex(attributes.size());
exampleSet.getExampleTable().addAttribute(targetAttribute);
attributes.addRegular(targetAttribute);

Add a value for each example of the new attribute:

for(Example example:exampleSet){
    example.setValue(targetAttribute, Math.round(Math.random()*10+0.5));
}

After adding random values to the example set, deliver the resulting example set to the output port:

exampleSetOutput.deliver(exampleSet);

The complete operator class now looks like this:

Install the extension again (with the Gradle task) and restart RapidMiner Studio. You can see that the operator now has an input and output port.

When you run the process that loads sample data and applies the example operator on it, you can see that the new attribute appears in the resulting example set.

This example shows an operator, which creates a completely new example set with one nominal and one numerical attribute.

Check out the code:

package com.rapidminer.operator;

import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.table.AttributeFactory;
import com.rapidminer.example.table.DoubleArrayDataRow;
import com.rapidminer.example.table.MemoryExampleTable;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.ports.OutputPort;
import com.rapidminer.tools.Ontology;

public class MyOwnOperator extends Operator {

    private OutputPort exampleSetOutput = getOutputPorts().createPort("example set");

    /**
     * @param description
     */
    public MyOwnOperator(OperatorDescription description) {
        super(description);
        getTransformer().addGenerationRule(exampleSetOutput, ExampleSet.class);
    }

    @Override
    public void doWork() throws OperatorException {
        // create the needed attributes
        List<Attribute> listOfAtts = new LinkedList<>();
        ExampleSet exampleSet;

        Attribute newNominalAtt = AttributeFactory.createAttribute("ID", 
            Ontology.ATTRIBUTE_VALUE_TYPE.NOMINAL);
        listOfAtts.add(newNominalAtt);

        Attribute newNumericalAtt = AttributeFactory.createAttribute("random number",
                Ontology.ATTRIBUTE_VALUE_TYPE.NUMERICAL);
        listOfAtts.add(newNumericalAtt);

        // basis is a MemoryExampleTable, so create one and pass it the 
        // list of attributes it should contain
        MemoryExampleTable table = new MemoryExampleTable(listOfAtts);

        for (int i = 0; i < 10; i++) {
            // every row is a double array internally; create and fill in data
            double[] doubleArray = new double[listOfAtts.size()];
            doubleArray[0] = newNominalAtt.getMapping().mapString(
                UUID.randomUUID().toString());
            doubleArray[1] = Math.random();
            // create an example
            // create a DataRow from our double array and add it to our table
            table.addDataRow(new DoubleArrayDataRow(doubleArray));
        }

        // finally create the ExampleSet from the table
        exampleSet = table.createExampleSet();

        exampleSetOutput.deliver(exampleSet);
    }
}

This operator just creates 10 random examples. An enhancement could be to create a parameter that defines how many examples the operator creates.

The next step is to define preconditions to be sure that you only get the type of input you want to process.