/**
   * evaluates a subset of attributes
   *
   * @param subset a bitset representing the attribute subset to be evaluated
   * @return the merit
   * @throws Exception if the subset could not be evaluated
   */
  public double evaluateSubset(BitSet subset, int decAttr) throws Exception {
    // need to set c_divisor appropriately
    double eval = 0.0;

    // This needs to be performed by the search method itself
    /*if (computeCore) {
        if (core==null) {
            core = computeCore();
        }
        subset.or(core);
    }*/

    if (subset.cardinality() > 0) {
      try {
        eval = m_FuzzyMeasure.calculate(subset, decAttr);
      } catch (Exception e) {
        System.err.println(e);
      }

      eval = Math.min(1, eval);
    }

    return eval;
  }
示例#2
0
  /**
   * Finds optimal point on line constrained by first (i1) and second (i2) candidate. Parameters
   * correspond to pseudocode (see technicalinformation)
   *
   * @param i1
   * @param alpha1
   * @param alpha1Star
   * @param C1
   * @param i2
   * @param alpha2
   * @param alpha2Star
   * @param C2
   * @param gamma
   * @param eta
   * @param deltaPhi
   * @return
   */
  protected boolean findOptimalPointOnLine(
      int i1,
      double alpha1,
      double alpha1Star,
      double C1,
      int i2,
      double alpha2,
      double alpha2Star,
      double C2,
      double gamma,
      double eta,
      double deltaPhi) {
    if (eta <= 0) {
      // this may happen due to numeric instability
      // due to Mercer's condition, this should not happen, hence we give up
      return false;
    }

    boolean case1 = false;
    boolean case2 = false;
    boolean case3 = false;
    boolean case4 = false;
    boolean finished = false;

    //		while !finished
    //		% this loop is passed at most three times
    //		% case variables needed to avoid attempting small changes twice
    while (!finished) {
      //			if (case1 == 0) &&
      //				(alpha1 > 0 || (alpha1* == 0 && deltaPhi > 0)) &&
      //				(alpha2 > 0 || (alpha2* == 0 && deltaPhi < 0))
      //				compute L, H (wrt. alpha1, alpha2)
      //				if L < H
      //					a2 = alpha2 ? - deltaPhi/eta
      //					a2 = min(a2, H)
      //					a2 = max(L, a2)
      //					a1 = alpha1 ? - (a2 ? alpha2)
      //					update alpha1, alpha2 if change is larger than some eps
      //				else
      //					finished = 1
      //				endif
      //				case1 = 1;

      if ((case1 == false)
          && (alpha1 > 0 || (alpha1Star == 0 && deltaPhi > 0))
          && (alpha2 > 0 || (alpha2Star == 0 && deltaPhi < 0))) {
        // compute L, H (wrt. alpha1, alpha2)
        double L = Math.max(0, gamma - C1);
        double H = Math.min(C2, gamma);
        if (L < H) {
          double a2 = alpha2 - deltaPhi / eta;
          a2 = Math.min(a2, H);
          a2 = Math.max(L, a2);
          // To prevent precision problems
          if (a2 > C2 - m_Del * C2) {
            a2 = C2;
          } else if (a2 <= m_Del * C2) {
            a2 = 0;
          }
          double a1 = alpha1 - (a2 - alpha2);
          if (a1 > C1 - m_Del * C1) {
            a1 = C1;
          } else if (a1 <= m_Del * C1) {
            a1 = 0;
          }
          // update alpha1, alpha2 if change is larger than some eps
          if (Math.abs(alpha1 - a1) > m_eps) {
            deltaPhi += eta * (a2 - alpha2);
            alpha1 = a1;
            alpha2 = a2;
          }
        } else {
          finished = true;
        }
        case1 = true;
      }

      //			elseif (case2 == 0) &&
      //				(alpha1 > 0 || (alpha1* == 0 && deltaPhi > 2 epsilon)) &&
      //				(alpha2* > 0 || (alpha2 == 0 && deltaPhi > 2 epsilon))
      //				compute L, H (wrt. alpha1, alpha2*)
      //				if L < H
      //					a2 = alpha2* + (deltaPhi ?- 2 epsilon)/eta
      //					a2 = min(a2, H)
      //					a2 = max(L, a2)
      //					a1 = alpha1 + (a2 ? alpha2*)
      //					update alpha1, alpha2* if change is larger than some eps
      //				else
      //					finished = 1
      //				endif
      //				case2 = 1;

      else if ((case2 == false)
          && (alpha1 > 0 || (alpha1Star == 0 && deltaPhi > 2 * m_epsilon))
          && (alpha2Star > 0 || (alpha2 == 0 && deltaPhi > 2 * m_epsilon))) {
        // compute L, H (wrt. alpha1, alpha2*)
        double L = Math.max(0, -gamma);
        double H = Math.min(C2, -gamma + C1);
        if (L < H) {
          double a2 = alpha2Star + (deltaPhi - 2 * m_epsilon) / eta;
          a2 = Math.min(a2, H);
          a2 = Math.max(L, a2);
          // To prevent precision problems
          if (a2 > C2 - m_Del * C2) {
            a2 = C2;
          } else if (a2 <= m_Del * C2) {
            a2 = 0;
          }
          double a1 = alpha1 + (a2 - alpha2Star);
          if (a1 > C1 - m_Del * C1) {
            a1 = C1;
          } else if (a1 <= m_Del * C1) {
            a1 = 0;
          }
          // update alpha1, alpha2* if change is larger than some eps
          if (Math.abs(alpha1 - a1) > m_eps) {
            deltaPhi += eta * (-a2 + alpha2Star);
            alpha1 = a1;
            alpha2Star = a2;
          }
        } else {
          finished = true;
        }
        case2 = true;
      }

      //			elseif (case3 == 0) &&
      //				(alpha1* > 0 || (alpha1 == 0 && deltaPhi < -2 epsilon)) &&
      //				(alpha2 > 0 || (alpha2* == 0 && deltaPhi < -2 epsilon))
      //				compute L, H (wrt. alpha1*, alpha2)
      //				if L < H
      //					a2 = alpha2 ?- (deltaPhi ?+ 2 epsilon)/eta
      //					a2 = min(a2, H)
      //					a2 = max(L, a2)
      //					a1 = alpha1* + (a2 ? alpha2)
      //					update alpha1*, alpha2 if change is larger than some eps
      //				else
      //					finished = 1
      //				endif
      //				case3 = 1;

      else if ((case3 == false)
          && (alpha1Star > 0 || (alpha1 == 0 && deltaPhi < -2 * m_epsilon))
          && (alpha2 > 0 || (alpha2Star == 0 && deltaPhi < -2 * m_epsilon))) {
        // compute L, H (wrt. alpha1*, alpha2)
        double L = Math.max(0, gamma);
        double H = Math.min(C2, C1 + gamma);
        if (L < H) {
          // note Smola's psuedocode has a minus, where there should be a plus in the following
          // line, Keerthi's is correct
          double a2 = alpha2 - (deltaPhi + 2 * m_epsilon) / eta;
          a2 = Math.min(a2, H);
          a2 = Math.max(L, a2);
          // To prevent precision problems
          if (a2 > C2 - m_Del * C2) {
            a2 = C2;
          } else if (a2 <= m_Del * C2) {
            a2 = 0;
          }
          double a1 = alpha1Star + (a2 - alpha2);
          if (a1 > C1 - m_Del * C1) {
            a1 = C1;
          } else if (a1 <= m_Del * C1) {
            a1 = 0;
          }
          // update alpha1*, alpha2 if change is larger than some eps
          if (Math.abs(alpha1Star - a1) > m_eps) {
            deltaPhi += eta * (a2 - alpha2);
            alpha1Star = a1;
            alpha2 = a2;
          }
        } else {
          finished = true;
        }
        case3 = true;
      }

      //			elseif (case4 == 0) &&
      //				(alpha1* > 0 || (alpha1 == 0 && deltaPhi < 0)) &&
      //				(alpha2* > 0 || (alpha2 == 0 && deltaPhi > 0))
      //				compute L, H (wrt. alpha1*, alpha2*)
      //				if L < H
      //					a2 = alpha2* + deltaPhi/eta
      //					a2 = min(a2, H)
      //					a2 = max(L, a2)
      //					a1 = alpha1* ? (a2 ? alpha2*)
      //					update alpha1*, alpha2* if change is larger than some eps
      //				else
      //					finished = 1
      //				endif
      //				case4 = 1;
      //			else
      //				finished = 1
      //			endif

      else if ((case4 == false)
          && (alpha1Star > 0 || (alpha1 == 0 && deltaPhi < 0))
          && (alpha2Star > 0 || (alpha2 == 0 && deltaPhi > 0))) {
        // compute L, H (wrt. alpha1*, alpha2*)
        double L = Math.max(0, -gamma - C1);
        double H = Math.min(C2, -gamma);
        if (L < H) {
          double a2 = alpha2Star + deltaPhi / eta;
          a2 = Math.min(a2, H);
          a2 = Math.max(L, a2);
          // To prevent precision problems
          if (a2 > C2 - m_Del * C2) {
            a2 = C2;
          } else if (a2 <= m_Del * C2) {
            a2 = 0;
          }
          double a1 = alpha1Star - (a2 - alpha2Star);
          if (a1 > C1 - m_Del * C1) {
            a1 = C1;
          } else if (a1 <= m_Del * C1) {
            a1 = 0;
          }
          // update alpha1*, alpha2* if change is larger than some eps
          if (Math.abs(alpha1Star - a1) > m_eps) {
            deltaPhi += eta * (-a2 + alpha2Star);

            alpha1Star = a1;
            alpha2Star = a2;
          }
        } else {
          finished = true;
        }
        case4 = true;
      } else {
        finished = true;
      }

      //			update deltaPhi
      // using 4.36 from Smola's thesis:
      // deltaPhi = deltaPhi - eta * ((alpha1New-alpha1StarNew)-(alpha1-alpha1Star));
      // the update is done inside the loop, saving us to remember old values of alpha1(*)
      // deltaPhi += eta * ((alpha2 - alpha2Star) - dAlpha2Old);
      // dAlpha2Old = (alpha2 - alpha2Star);

      //		endwhile

    }

    if (Math.abs(alpha1 - m_alpha[i1]) > m_eps
        || Math.abs(alpha1Star - m_alphaStar[i1]) > m_eps
        || Math.abs(alpha2 - m_alpha[i2]) > m_eps
        || Math.abs(alpha2Star - m_alphaStar[i2]) > m_eps) {

      if (alpha1 > C1 - m_Del * C1) {
        alpha1 = C1;
      } else if (alpha1 <= m_Del * C1) {
        alpha1 = 0;
      }
      if (alpha1Star > C1 - m_Del * C1) {
        alpha1Star = C1;
      } else if (alpha1Star <= m_Del * C1) {
        alpha1Star = 0;
      }
      if (alpha2 > C2 - m_Del * C2) {
        alpha2 = C2;
      } else if (alpha2 <= m_Del * C2) {
        alpha2 = 0;
      }
      if (alpha2Star > C2 - m_Del * C2) {
        alpha2Star = C2;
      } else if (alpha2Star <= m_Del * C2) {
        alpha2Star = 0;
      }

      // store new alpha's
      m_alpha[i1] = alpha1;
      m_alphaStar[i1] = alpha1Star;
      m_alpha[i2] = alpha2;
      m_alphaStar[i2] = alpha2Star;

      // update supportvector set
      if (alpha1 != 0 || alpha1Star != 0) {
        if (!m_supportVectors.contains(i1)) {
          m_supportVectors.insert(i1);
        }
      } else {
        m_supportVectors.delete(i1);
      }
      if (alpha2 != 0 || alpha2Star != 0) {
        if (!m_supportVectors.contains(i2)) {
          m_supportVectors.insert(i2);
        }
      } else {
        m_supportVectors.delete(i2);
      }
      return true;
    }

    return false;
  }