neural-networkconstraintspredictionrapidminer

How to constrain a neural network model's output in Rapidminer to non-negative values?


I am developing a simple neural network model in Rapidminer to predict the number of cars passing on a highway every hour. In the early hours of the day (from 2:00 am to 6:00 am) few cars are on the highway therefore, sometime my model predicts negative values.

How can I constrain the output variable to positive values?


Solution

  • It always depends on the data and what you want to do but one approach is to convert the numbers to polynominals. So 0 becomes the string "0", 1 becomes "1" and so on. This forces the neural network to use the available values alone.

    Here's an example process using dummy data.

    <?xml version="1.0" encoding="UTF-8"?><process version="7.3.001">
      <context>
        <input/>
        <output/>
        <macros/>
      </context>
      <operator activated="true" class="process" compatibility="7.3.001" expanded="true" name="Process">
        <process expanded="true">
          <operator activated="true" class="subprocess" compatibility="7.3.001" expanded="true" height="82" name="Subprocess" width="90" x="246" y="34">
            <process expanded="true">
              <operator activated="true" class="generate_data" compatibility="7.3.001" expanded="true" height="68" name="Generate Data" width="90" x="45" y="34">
                <parameter key="target_function" value="polynomial"/>
                <parameter key="attributes_lower_bound" value="0.0"/>
                <parameter key="attributes_upper_bound" value="3.0"/>
              </operator>
              <operator activated="true" class="normalize" compatibility="7.3.001" expanded="true" height="103" name="Normalize" width="90" x="179" y="34">
                <parameter key="attribute_filter_type" value="single"/>
                <parameter key="attribute" value="label"/>
                <parameter key="include_special_attributes" value="true"/>
                <parameter key="method" value="range transformation"/>
                <parameter key="max" value="4.99"/>
              </operator>
              <operator activated="true" class="real_to_integer" compatibility="7.3.001" expanded="true" height="82" name="Real to Integer" width="90" x="313" y="34">
                <parameter key="attribute_filter_type" value="single"/>
                <parameter key="attribute" value="label"/>
                <parameter key="include_special_attributes" value="true"/>
              </operator>
              <connect from_op="Generate Data" from_port="output" to_op="Normalize" to_port="example set input"/>
              <connect from_op="Normalize" from_port="example set output" to_op="Real to Integer" to_port="example set input"/>
              <connect from_op="Real to Integer" from_port="example set output" to_port="out 1"/>
              <portSpacing port="source_in 1" spacing="0"/>
              <portSpacing port="sink_out 1" spacing="0"/>
              <portSpacing port="sink_out 2" spacing="0"/>
            </process>
          </operator>
          <operator activated="true" class="numerical_to_polynominal" compatibility="7.3.001" expanded="true" height="82" name="Numerical to Polynominal" width="90" x="380" y="34">
            <parameter key="attribute_filter_type" value="single"/>
            <parameter key="attribute" value="label"/>
            <parameter key="include_special_attributes" value="true"/>
          </operator>
          <operator activated="true" class="concurrency:cross_validation" compatibility="7.3.001" expanded="true" height="145" name="Validation" width="90" x="514" y="34">
            <parameter key="sampling_type" value="shuffled sampling"/>
            <process expanded="true">
              <operator activated="true" class="neural_net" compatibility="7.3.001" expanded="true" height="82" name="Neural Net" width="90" x="323" y="34">
                <list key="hidden_layers"/>
              </operator>
              <connect from_port="training set" to_op="Neural Net" to_port="training set"/>
              <connect from_op="Neural Net" from_port="model" to_port="model"/>
              <portSpacing port="source_training set" spacing="0"/>
              <portSpacing port="sink_model" spacing="0"/>
              <portSpacing port="sink_through 1" spacing="0"/>
            </process>
            <process expanded="true">
              <operator activated="true" class="apply_model" compatibility="7.3.001" expanded="true" height="82" name="Apply Model" width="90" x="45" y="34">
                <list key="application_parameters"/>
              </operator>
              <operator activated="true" class="performance" compatibility="7.3.001" expanded="true" height="82" name="Performance" width="90" x="179" y="34"/>
              <connect from_port="model" to_op="Apply Model" to_port="model"/>
              <connect from_port="test set" to_op="Apply Model" to_port="unlabelled data"/>
              <connect from_op="Apply Model" from_port="labelled data" to_op="Performance" to_port="labelled data"/>
              <connect from_op="Performance" from_port="performance" to_port="performance 1"/>
              <connect from_op="Performance" from_port="example set" to_port="test set results"/>
              <portSpacing port="source_model" spacing="0"/>
              <portSpacing port="source_test set" spacing="0"/>
              <portSpacing port="source_through 1" spacing="0"/>
              <portSpacing port="sink_test set results" spacing="0"/>
              <portSpacing port="sink_performance 1" spacing="0"/>
              <portSpacing port="sink_performance 2" spacing="0"/>
            </process>
          </operator>
          <operator activated="true" class="nominal_to_numerical" compatibility="7.3.001" expanded="true" height="103" name="Nominal to Numerical (2)" width="90" x="715" y="136">
            <parameter key="attribute_filter_type" value="subset"/>
            <parameter key="attribute" value="label"/>
            <parameter key="attributes" value="prediction(label)|label"/>
            <parameter key="include_special_attributes" value="true"/>
            <parameter key="coding_type" value="unique integers"/>
            <list key="comparison_groups"/>
          </operator>
          <connect from_op="Subprocess" from_port="out 1" to_op="Numerical to Polynominal" to_port="example set input"/>
          <connect from_op="Numerical to Polynominal" from_port="example set output" to_op="Validation" to_port="example set"/>
          <connect from_op="Validation" from_port="model" to_port="result 1"/>
          <connect from_op="Validation" from_port="example set" to_port="result 2"/>
          <connect from_op="Validation" from_port="test result set" to_op="Nominal to Numerical (2)" to_port="example set input"/>
          <connect from_op="Validation" from_port="performance 1" to_port="result 4"/>
          <connect from_op="Nominal to Numerical (2)" from_port="example set output" to_port="result 3"/>
          <portSpacing port="source_input 1" spacing="0"/>
          <portSpacing port="sink_result 1" spacing="0"/>
          <portSpacing port="sink_result 2" spacing="0"/>
          <portSpacing port="sink_result 3" spacing="0"/>
          <portSpacing port="sink_result 4" spacing="0"/>
          <portSpacing port="sink_result 5" spacing="0"/>
        </process>
      </operator>
    </process>
    

    It makes dummy data and converts numeric values into polynominals. The prediction example set output of the Cross Validation contains polynominals and these are converted back to numbers.

    Needless to say, this might not be appropriate for what you want, but it's a start.

    Andrew