mahout源码分析之logistic regression(2)--RunLogistic


mahout:0.9 ;

首先说明一点:logistic regression不支持并行,也就是mahout实现的也是单机的,运行在hadoop上面也没有意义(个人观点)。其次,建模得到那个公式太复杂了,所以TrainLogistic不分析了,只分析RunLogistic,即分析如何通过那个公式得到预测值。(最近感觉心很浮躁,静不下来,完全不在状态。。。哎。。。)

 通过TrainLogistic可以得到一个公式,例如下面的样子:

-0.149*Intercept Term + -0.701*x + -0.427*y

先解释下Intercept Term吧,这个就是一个常量,在mahout里面实现的算法里面,其值为1.

其实本来我就是用测试的值,比如[0.97073650965467,0.989339149091393],对应于[x,y]然后使用1作为常量,相加,这样得到的值是:-1.25253208955095,和最后的结果0,0.222,-0.251366,的0.222相差很多,那么到底通过-1.25253208955095如何得到0.222呢?


RunLogistic的预测代码:

while (line != null) {
        Vector v = new SequentialAccessSparseVector(lmp.getNumFeatures());
        int target = csv.processLine(line, v);

        double score = lr.classifyScalar(v);
        if (showScores) {
          output.printf(Locale.ENGLISH, "%d,%.3f,%.6f%n", target, score, lr.logLikelihood(target, v));
        }
        collector.add(target, score);
        line = in.readLine();
      }
首先看下csv.processLine 其代码如下:

public int processLine(String line, Vector featureVector) {
    List<String> values = parseCsvLine(line);

    int targetValue = targetDictionary.intern(values.get(target));
    if (targetValue >= maxTargetValue) {
      targetValue = maxTargetValue - 1;
    }

    for (Integer predictor : predictors) {
      String value;
      if (predictor >= 0) {
        value = values.get(predictor);
      } else {
        value = null;
      }
      predictorEncoders.get(predictor).addToVector(value, featureVector);
    }
    return targetValue;
  }
这里返回的targetValue就是line里面的分类值(注意,这里是做了转换2-->0,1-->1)。predictors有三个值[-1,0,1],-1代表常量值,0代表x变量,1代表y变量。然后predictorEncoders。。。 是把line中的x、y取出来放在featureVector对应的位置。

double score = lr.classifyScalar(v);这里就是分类的主要代码了:

public double classifyScalar(Vector instance) {
    Preconditions.checkArgument(numCategories() == 2, "Can only call classifyScalar with two categories");

    // apply pending regularization to whichever coefficients matter
    regularize(instance);

    // result is a vector with one element so we can just use dot product
    return link(classifyScalarNoLink(instance));
  }
regularize,个人感觉基本没做什么。

主要还是最后一个return。

public double classifyScalarNoLink(Vector instance) {
    return beta.viewRow(0).dot(instance);
  }
这里就是把对应的值相乘,最后得到就是咱们前面算到的-1.25253208955095。

最后就是link函数了:

 public static double link(double r) {
    if (r < 0.0) {
      double s = Math.exp(r);
      return s / (1.0 + s);
    } else {
      double s = Math.exp(-r);
      return 1.0 / (1.0 + s);
    }
  }

这里的r 就是-1.25253208955095,带入上面的公式就可以得到最后的预测值0.222262129784177。



最后,顺便说下个人关于这个算法的一些并行的想法。其实,如果可以的话,应该可以建立多条直线方程的(相同变量的前提下),然后把它们评估效果最好的进行输出,其实这样也不算是并行,只是提高准确率的一种方法。这种思路其实是来自于随机森林算法,那里面就是多棵决策树,多棵决策树就是算作并行了。

分享,成长,快乐

转载请注明blog地址:http://blog.csdn.net/fansy1990






相关内容

    暂无相关文章