Beispiel #1
0
  /**
   * Builds L2-regularized classifiers for a sequence of regularization parameter lambdas.
   *
   * @param trainSet the training set.
   * @param isSparse <code>true</code> if the training set is treated as sparse.
   * @param maxNumIters the maximum number of iterations.
   * @param lambdas the lambdas array.
   * @return L2-regularized binary classifiers.
   */
  public GLM[] buildClassifiers(
      Instances trainSet, boolean isSparse, int maxNumIters, double[] lambdas) {
    Attribute classAttribute = trainSet.getTargetAttribute();
    if (classAttribute.getType() != Attribute.Type.NOMINAL) {
      throw new IllegalArgumentException("Class attribute must be nominal.");
    }
    NominalAttribute clazz = (NominalAttribute) classAttribute;
    int numClasses = clazz.getStates().length;

    if (isSparse) {
      SparseDataset sd = getSparseDataset(trainSet, true);
      int[] attrs = sd.attrs;
      int[][] indices = sd.indices;
      double[][] values = sd.values;
      double[] y = new double[sd.y.length];
      double[] cList = sd.cList;

      if (numClasses == 2) {
        for (int i = 0; i < y.length; i++) {
          int label = (int) sd.y[i];
          y[i] = label == 0 ? 1 : 0;
        }

        GLM[] glms = buildBinaryClassifiers(attrs, indices, values, y, maxNumIters, lambdas);

        for (GLM glm : glms) {
          double[] w = glm.w[0];
          for (int j = 0; j < cList.length; j++) {
            int attIndex = attrs[j];
            w[attIndex] *= cList[j];
          }
        }

        return glms;
      } else {
        int p = attrs.length == 0 ? 0 : (StatUtils.max(attrs) + 1);
        GLM[] glms = new GLM[lambdas.length];
        for (int i = 0; i < glms.length; i++) {
          glms[i] = new GLM(numClasses, p);
        }

        for (int k = 0; k < numClasses; k++) {
          // One-vs-the-rest
          for (int i = 0; i < y.length; i++) {
            int label = (int) sd.y[i];
            y[i] = label == k ? 1 : 0;
          }

          GLM[] binaryClassifiers =
              buildBinaryClassifiers(attrs, indices, values, y, maxNumIters, lambdas);

          for (int l = 0; l < glms.length; l++) {
            GLM binaryClassifier = binaryClassifiers[l];
            GLM glm = glms[l];
            double[] w = binaryClassifier.w[0];
            for (int j = 0; j < cList.length; j++) {
              int attIndex = attrs[j];
              glm.w[k][attIndex] = w[attIndex] * cList[j];
            }
            glm.intercept[k] = binaryClassifier.intercept[0];
          }
        }

        return glms;
      }
    } else {
      DenseDataset dd = getDenseDataset(trainSet, true);
      int[] attrs = dd.attrs;
      double[][] x = dd.x;
      double[] y = new double[dd.y.length];
      double[] cList = dd.cList;

      if (numClasses == 2) {
        for (int i = 0; i < y.length; i++) {
          int label = (int) dd.y[i];
          y[i] = label == 0 ? 1 : 0;
        }

        GLM[] glms = buildBinaryClassifiers(attrs, x, y, maxNumIters, lambdas);

        for (GLM glm : glms) {
          double[] w = glm.w[0];
          for (int j = 0; j < cList.length; j++) {
            int attIndex = attrs[j];
            w[attIndex] *= cList[j];
          }
        }

        return glms;
      } else {
        int p = attrs.length == 0 ? 0 : attrs[attrs.length - 1] + 1;
        GLM[] glms = new GLM[lambdas.length];
        for (int i = 0; i < glms.length; i++) {
          glms[i] = new GLM(numClasses, p);
        }

        for (int k = 0; k < numClasses; k++) {
          // One-vs-the-rest
          for (int i = 0; i < y.length; i++) {
            int label = (int) dd.y[i];
            y[i] = label == k ? 1 : 0;
          }

          GLM[] binaryClassifiers = buildBinaryClassifiers(attrs, x, y, maxNumIters, lambdas);

          for (int l = 0; l < glms.length; l++) {
            GLM binaryClassifier = binaryClassifiers[l];
            GLM glm = glms[l];
            double[] w = binaryClassifier.w[0];
            for (int j = 0; j < cList.length; j++) {
              int attIndex = attrs[j];
              glm.w[k][attIndex] = w[attIndex] * cList[j];
            }
            glm.intercept[k] = binaryClassifier.intercept[0];
          }
        }

        return glms;
      }
    }
  }