[SOLVED] Discretize by User Specification: multiple class problem

Q-DogQ-Dog Member Posts: 32 Contributor II
edited November 2018 in Help
Hi everyone,

my question is about the operator "Discretize by User Specification" in order to discretize numerical values.

Let's assume I want to discretize the four cardinal directions (north, east, south and west) as follows:

315-45: North
45-135: East
135-225: South
225-315: West

and in RapidMiner (at least I assume) as follows: class namesupper limitNorth45East135South225West315NorthInfinity
now the problem is that the first "North" class will be overwritten with the second "North" class and the values appear as missing values "?".

Is there any workaround?

Cheers Q-Dog

Answers

  • IngoRMIngoRM Administrator, Moderator, Employee, RapidMiner Certified Analyst, RapidMiner Certified Expert, Community Manager, RMResearcher, Member, University Professor Posts: 1,645  RM Founder
    Hi,

    yes, this can indeed not be done with the operator "Discretize by User Specification" due to the "wrapping" for high degrees around "north". However, it is pretty simple with the operator "Generate Attributes" as in this example:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <process version="5.1.017">
      <context>
        <input/>
        <output/>
        <macros/>
      </context>
      <operator activated="true" class="process" compatibility="5.1.017" expanded="true" name="Process">
        <process expanded="true" height="519" width="884">
          <operator activated="true" class="generate_data" compatibility="5.1.017" expanded="true" height="60" name="Generate Data" width="90" x="45" y="30">
            <parameter key="number_of_attributes" value="1"/>
            <parameter key="attributes_lower_bound" value="0.0"/>
            <parameter key="attributes_upper_bound" value="360.0"/>
          </operator>
          <operator activated="true" class="select_attributes" compatibility="5.1.017" expanded="true" height="76" name="Select Attributes" width="90" x="179" y="30">
            <parameter key="attribute_filter_type" value="single"/>
            <parameter key="attribute" value="label"/>
            <parameter key="invert_selection" value="true"/>
            <parameter key="include_special_attributes" value="true"/>
          </operator>
          <operator activated="true" class="rename" compatibility="5.1.017" expanded="true" height="76" name="Rename" width="90" x="313" y="30">
            <parameter key="old_name" value="att1"/>
            <parameter key="new_name" value="degree"/>
            <list key="rename_additional_attributes"/>
          </operator>
          <operator activated="true" class="generate_attributes" compatibility="5.1.017" expanded="true" height="76" name="Generate Attributes" width="90" x="447" y="30">
            <list key="function_descriptions">
              <parameter key="direction" value="if(degree&gt;315||degree&lt;45, &quot;North&quot;, if(degree&lt;135, &quot;East&quot;, if(degree&lt;225, &quot;South&quot;, &quot;West&quot;)))"/>
            </list>
          </operator>
          <connect from_op="Generate Data" from_port="output" to_op="Select Attributes" to_port="example set input"/>
          <connect from_op="Select Attributes" from_port="example set output" to_op="Rename" to_port="example set input"/>
          <connect from_op="Rename" from_port="example set output" to_op="Generate Attributes" to_port="example set input"/>
          <connect from_op="Generate Attributes" from_port="example set output" 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>
    Here, the generation parameter

    if(degree>315||degree<45, "North", if(degree<135, "East", if(degree<225, "South", "West")))

    has been used.

    Another option would indeed use the modulo function '%' after adding the offset of 45 degrees:

    if((degree+45)%360<90, "North", if((degree+45)%360<180, "East", if((degree+45)%360<270, "South", "West")))

    By this, you could also transform angles higher than 360 degrees which might happen for measuring rotations etc.

    Hope that helps,
    Ingo
  • Q-DogQ-Dog Member Posts: 32 Contributor II
    Thank you so much Ingo  :)
Sign In or Register to comment.