Can I break the loop attributes prematurely?

wesselwessel Member Posts: 537  Guru
edited November 2018 in Help
Dear all,

Can I break the loop attributes prematurely?
Alternatively, can I use some other loop operator that builds the resulting dataset in a similar way to loop attributes?

E.g.
Loop over all attributes, unless a certain amount of time has passed, then stop the loop and continue the process.

Best regards,

Wessel
Tagged:

Answers

  • awchisholmawchisholm RapidMiner Certified Expert, Member Posts: 458   Unicorn
    Hello

    The Loop operator has a "limit time" option. You'd have to work at it but I suppose it would be possible.

    regards

    Andrew
  • bkrieverbkriever RapidMiner Certified Analyst, Member Posts: 11 Contributor II
    You could put loop attributes inside a handle exceptions operator and essentially make it fail, then recall your dataset outside of the handle exceptions operator.
    To make it fail you can use a branch operator to send an empty data set into the example output so nothing will come back through for the loop.
    In my example my criteria was just "%{loop_attribute}"=="att5". Hope that helps!


    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <process version="6.1.000">
      <context>
        <input/>
        <output/>
        <macros/>
      </context>
      <operator activated="true" class="process" compatibility="6.1.000" expanded="true" name="Process">
        <process expanded="true">
          <operator activated="true" class="generate_data_user_specification" compatibility="6.1.000" expanded="true" height="60" name="Generate Data by User Specification" width="90" x="45" y="30">
            <list key="attribute_values">
              <parameter key="att1" value="1"/>
              <parameter key="att2" value="1"/>
              <parameter key="att3" value="1"/>
              <parameter key="att4" value="1"/>
              <parameter key="att5" value="1"/>
              <parameter key="att6" value="1"/>
              <parameter key="att7" value="1"/>
            </list>
            <list key="set_additional_roles"/>
          </operator>
          <operator activated="true" class="handle_exception" compatibility="6.1.000" expanded="true" height="76" name="Handle Exception" width="90" x="179" y="30">
            <process expanded="true">
              <operator activated="true" class="loop_attributes" compatibility="6.1.000" expanded="true" height="94" name="Loop Attributes" width="90" x="112" y="30">
                <process expanded="true">
                  <operator activated="true" class="select_attributes" compatibility="6.1.000" expanded="true" height="76" name="Select Attributes" width="90" x="112" y="30">
                    <parameter key="attribute_filter_type" value="single"/>
                    <parameter key="attribute" value="%{loop_attribute}"/>
                  </operator>
                  <operator activated="true" class="branch" compatibility="6.1.000" expanded="true" height="94" name="Branch (2)" width="90" x="313" y="30">
                    <parameter key="condition_type" value="expression"/>
                    <parameter key="condition_value" value="&quot;%{loop_attribute}&quot;==&quot;att5&quot;"/>
                    <process expanded="true">
                      <operator activated="true" class="remember" compatibility="6.1.000" expanded="true" height="60" name="Remember" width="90" x="112" y="30">
                        <parameter key="name" value="Test"/>
                      </operator>
                      <connect from_port="condition" to_op="Remember" to_port="store"/>
                      <connect from_op="Remember" from_port="stored" to_port="input 2"/>
                      <portSpacing port="source_condition" spacing="0"/>
                      <portSpacing port="source_input 1" spacing="0"/>
                      <portSpacing port="source_input 2" spacing="0"/>
                      <portSpacing port="sink_input 1" spacing="0"/>
                      <portSpacing port="sink_input 2" spacing="0"/>
                      <portSpacing port="sink_input 3" spacing="0"/>
                    </process>
                    <process expanded="true">
                      <connect from_port="input 1" to_port="input 1"/>
                      <portSpacing port="source_condition" spacing="0"/>
                      <portSpacing port="source_input 1" spacing="0"/>
                      <portSpacing port="source_input 2" spacing="0"/>
                      <portSpacing port="sink_input 1" spacing="0"/>
                      <portSpacing port="sink_input 2" spacing="0"/>
                      <portSpacing port="sink_input 3" spacing="0"/>
                    </process>
                  </operator>
                  <connect from_port="example set" to_op="Select Attributes" to_port="example set input"/>
                  <connect from_op="Select Attributes" from_port="example set output" to_op="Branch (2)" to_port="condition"/>
                  <connect from_op="Select Attributes" from_port="original" to_op="Branch (2)" to_port="input 1"/>
                  <connect from_op="Branch (2)" from_port="input 1" to_port="example set"/>
                  <connect from_op="Branch (2)" from_port="input 2" to_port="result 1"/>
                  <portSpacing port="source_example set" spacing="0"/>
                  <portSpacing port="sink_example set" spacing="0"/>
                  <portSpacing port="sink_result 1" spacing="0"/>
                  <portSpacing port="sink_result 2" spacing="0"/>
                </process>
              </operator>
              <connect from_port="in 1" to_op="Loop Attributes" to_port="example set"/>
              <connect from_op="Loop Attributes" from_port="example set" to_port="out 1"/>
              <portSpacing port="source_in 1" spacing="0"/>
              <portSpacing port="source_in 2" spacing="0"/>
              <portSpacing port="sink_out 1" spacing="0"/>
              <portSpacing port="sink_out 2" spacing="0"/>
            </process>
            <process expanded="true">
              <connect from_port="in 1" to_port="out 1"/>
              <portSpacing port="source_in 1" spacing="0"/>
              <portSpacing port="source_in 2" spacing="0"/>
              <portSpacing port="sink_out 1" spacing="0"/>
              <portSpacing port="sink_out 2" spacing="0"/>
            </process>
          </operator>
          <operator activated="true" class="recall" compatibility="6.1.000" expanded="true" height="60" name="Recall" width="90" x="313" y="30">
            <parameter key="name" value="Test"/>
          </operator>
          <connect from_op="Generate Data by User Specification" from_port="output" to_op="Handle Exception" to_port="in 1"/>
          <connect from_op="Recall" from_port="result" to_port="result 1"/>
          <portSpacing port="source_input 1" spacing="0"/>
          <portSpacing port="sink_result 1" spacing="0"/>
          <portSpacing port="sink_result 2" spacing="0"/>
        </process>
      </operator>
    </process>
  • wesselwessel Member Posts: 537  Guru
    Thanks for your reply!

    I was aware of this option.
    But the output from "Loop Attributes" is special.
    It doesn't create a collection of "resulting example sets".
    Instead it continuously keeps adding columns.
    In my result I really need 1 dataset to be the result, not a collection of datasets.

    edit:
    Currently playing around with the handle exception, as suggested by bkriever, I'll update later.

    Any suggestions?

    Best regards,

    Wessel
  • awchisholmawchisholm RapidMiner Certified Expert, Member Posts: 458   Unicorn
    You could use Recall and Remember inside the loop and have nothing explicitly output by the loop itself. After the loop do a final Recall. This has the side effect that much less memory is used.
  • wesselwessel Member Posts: 537  Guru
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <process version="5.3.015">
      <context>
        <input/>
        <output/>
        <macros/>
      </context>
      <operator activated="true" class="process" compatibility="5.3.015" expanded="true" name="Process">
        <process expanded="true">
          <operator activated="true" class="generate_data" compatibility="5.3.015" expanded="true" height="60" name="Generate Data" width="90" x="45" y="30"/>
          <operator activated="true" class="remember" compatibility="5.3.015" expanded="true" height="60" name="Remember" width="90" x="180" y="30">
            <parameter key="name" value="A"/>
            <parameter key="io_object" value="ExampleSet"/>
          </operator>
          <operator activated="true" class="loop" compatibility="5.3.015" expanded="true" height="76" name="Loop" width="90" x="313" y="30">
            <parameter key="set_iteration_macro" value="true"/>
            <parameter key="macro_name" value="Q"/>
            <parameter key="macro_start_value" value="10"/>
            <parameter key="iterations" value="12"/>
            <process expanded="true">
              <operator activated="true" class="recall" compatibility="5.3.015" expanded="true" height="60" name="Recall" width="90" x="179" y="75">
                <parameter key="name" value="A"/>
                <parameter key="io_object" value="ExampleSet"/>
              </operator>
              <operator activated="true" class="generate_attributes" compatibility="5.3.015" expanded="true" height="76" name="Generate Attributes" width="90" x="313" y="75">
                <list key="function_descriptions">
                  <parameter key="att1 * %{Q}" value="att1 * %{Q}"/>
                </list>
              </operator>
              <operator activated="true" class="remember" compatibility="5.3.015" expanded="true" height="60" name="Remember (2)" width="90" x="447" y="75">
                <parameter key="name" value="A"/>
                <parameter key="io_object" value="ExampleSet"/>
              </operator>
              <connect from_op="Recall" from_port="result" to_op="Generate Attributes" to_port="example set input"/>
              <connect from_op="Generate Attributes" from_port="example set output" to_op="Remember (2)" to_port="store"/>
              <portSpacing port="source_input 1" spacing="0"/>
              <portSpacing port="source_input 2" spacing="0"/>
              <portSpacing port="sink_output 1" spacing="0"/>
            </process>
          </operator>
          <operator activated="true" class="recall" compatibility="5.3.015" expanded="true" height="60" name="Recall (2)" width="90" x="450" y="30">
            <parameter key="name" value="A"/>
            <parameter key="io_object" value="ExampleSet"/>
          </operator>
          <connect from_op="Generate Data" from_port="output" to_op="Remember" to_port="store"/>
          <connect from_op="Remember" from_port="stored" to_op="Loop" to_port="input 1"/>
          <connect from_op="Recall (2)" from_port="result" to_port="result 1"/>
          <portSpacing port="source_input 1" spacing="0"/>
          <portSpacing port="sink_result 1" spacing="0"/>
          <portSpacing port="sink_result 2" spacing="0"/>
        </process>
      </operator>
    </process>
  • wesselwessel Member Posts: 537  Guru
    In my post above I managed to implement the remember and recall procedure as suggested by awchisholm.

    What I really dislike about this way of doing things, is that the recall block does not have an import port.
    So I need to be really careful not to get bugs from a incorrect execution order.

    Having said this, big thanks awchisholm.
    Never knew this could be used to remedy memory issues!

    Best regards,

    Wessel
  • awchisholmawchisholm RapidMiner Certified Expert, Member Posts: 458   Unicorn
    To force the execution order, a trick is to use a "Subprocess" operator containing the "Recall" operator.

    Here's an example http://rapidminernotes.blogspot.co.uk/2012/11/using-subprocess-operator-to-stop.html

    regards

    Andrew
  • wesselwessel Member Posts: 537  Guru
    Awesome, thanks! :)
Sign In or Register to comment.