`
445822357
  • 浏览: 740733 次
文章分类
社区版块
存档分类
最新评论

mahout源码分析之DistributedLanczosSolver(三)Job2

 
阅读更多

Mahout版本:0.7,hadoop版本:1.0.4,jdk:1.7.0_25 64bit。

1. 前奏:

本篇接着上篇继续分析,分析LanczosSolver中的:Vector nextVector = isSymmetric ? corpus.times(currentVector) : corpus.timesSquared(currentVector);之后。前篇说到这个是建立了一个job任务,并且按照一定的算法求得了一个nextVector,那么接下来是?

if (state.getScaleFactor() <= 0) {
        state.setScaleFactor(calculateScaleFactor(nextVector));
      }
这里首先判断getScaleFactor的值是否小于等于0,因为刚开始的时候初始化scaleFactor = 0;,所以这里要调用calculateScaleFactor(nextVector)函数:

protected double calculateScaleFactor(Vector nextVector) {
    return nextVector.norm(2);
  }
这个是如何计算的呢?else if (power == 2.0) {return Math.sqrt(dotSelf()); 这个就是norm函数中当参数是2的时候调用的代码了,所以这里返回的是先nextVector自点乘,然后开根号;(测试的时候这个值是:2029123.4011255247,excel计算的这个值是:2034667.82368468)接下来:

 nextVector.assign(new Scale(1.0 / state.getScaleFactor()));
nextVector 乘以1除以scaleFactor其实就是nextVector除以scaleFactor而已,数值太大了要变小点?经过这一步,nextVector变为:

{0:0.011875906226907599,1:0.0017759586067652153,2:0.0021729514771005837,3:0.014292365192727802,4:0.09660595016979406,5:0.002638859113021243,6:0.0026868791091140517,7:2.476888783392492E-4,8:0.001831833994868574,9:0.005012618192500366,10:8.604490527160895E-4,11:0.0029456317791350514,12:0.9951190694939772}
excel里面变为:

0.0118771 0.001776226 0.002173228 0.01429431 0.096617439 0.00263899 0.00268705 0 0 0.0050126 0 0 0.99511791
可见,由于误差,excel中的数据直接变为0了(比较小的数值);

接下来还是更新nextVector的:

 double alpha = currentVector.dot(nextVector);
      nextVector.assign(currentVector, new PlusMult(-alpha));
首先是currentVector和nextVector的点积,然后用nextVector中的项减去currentVector中的项乘以alpha的值更新nextVector中的项;上面的测试结果,alpha的值为:0.315642761491587,excel计算的值是0.31564687543564,这里就很接近了;然后是nextVector的值:

{0:-0.07566764464132066,1:-0.08576759226146304,2:-0.08537059939112766,3:-0.07325118567550044,4:0.009062399301565813,5:-0.08490469175520701,6:-0.0848566717591142,7:-0.087295861989889,8:-0.08571171687335968,9:-0.08253093267572789,10:-0.08668310181551216,11:-0.0845979190890932,12:0.9075755186257489}
excel中的值是:

-0.075668 -0.08576847 -0.08537146 -0.073250382 0.009072747 -0.0849057 -0.0848576 -0.1 -0.1 -0.082532 -0.1 -0.1 0.90757322
接着是:

endTime(TimingSection.ITERATE);
      startTime(TimingSection.ORTHOGANLIZE);
      orthoganalizeAgainstAllButLast(nextVector, state);
      endTime(TimingSection.ORTHOGANLIZE);
endTime和startTime应该只是和目录有关的设置吧,这里不管了,直接看orthoganalizeAgainstAllButLast函数:

protected void orthoganalizeAgainstAllButLast(Vector nextVector, LanczosState state) {
    for (int i = 0; i < state.getIterationNumber(); i++) {
      Vector basisVector = state.getBasisVector(i);
      double alpha;
      if (basisVector == null || (alpha = nextVector.dot(basisVector)) == 0.0) {
        continue;
      }
      nextVector.assign(basisVector, new PlusMult(-alpha));
    }
  }
这个函数的操作就是使用bisis来更新nextVector,更新采用原始值减去basisVector对应值乘以(nextVector和basisVector的点积)来更新;第一次basisVector中只有一个值,是13个1初始根号13的向量,那么更新后的nextVector是:

{0:-0.07566764464132064,1:-0.08576759226146302,2:-0.08537059939112765,3:-0.07325118567550043,4:0.009062399301565828,5:-0.084904691755207,6:-0.08485667175911418,7:-0.08729586198988899,8:-0.08571171687335967,9:-0.08253093267572788,10:-0.08668310181551214,11:-0.08459791908909318,12:0.9075755186257489}
感觉和之前没有啥差别,因为nextVector和basisVector的点积很小的缘故;接下来是:

beta = nextVector.norm(2);
额,这个函数之前分析过:就是nextVector自己点积,然后开根号即可,得到的beta值是:0.9488780991876485,然后判断alpha和beta是否超过某个数,如下:

if (outOfRange(beta) || outOfRange(alpha)) {
        log.warn("Lanczos parameters out of range: alpha = {}, beta = {}.  Bailing out early!",
            alpha, beta);
        break;
      }
看到outOfRange函数:

private static boolean outOfRange(double d) {
    return Double.isNaN(d) || d > SAFE_MAX || -d > SAFE_MAX;
  }
由于SAFE_MAX=1.0E150,所以肯定是不会超过的;那么就继续往下分析了;

nextVector.assign(new Scale(1 / beta));
      state.setBasisVector(i, nextVector);
      previousVector = currentVector;
      currentVector = nextVector;
      // save the projections and norms!
      triDiag.set(i - 1, i - 1, alpha);
      if (i < desiredRank - 1) {
        triDiag.set(i - 1, i, beta);
        triDiag.set(i, i - 1, beta);
      }
      state.setIterationNumber(++i);
感觉和刚才一样了,nextVector先出示beta的值,然后设置basisVector的第1个值(所谓第1个值是因为这时i为1,计数从0开始),那么basisVector就有两个值了,第0个是13个1除以根号13,第1个是nextVector了;然后重新赋值,previousVector、currentVector,最后就是triDiag的设置了,这个是一个3乘以3的矩阵,这个3是前面设置的rank值;triDiag设置后的值是:

[[0.315642761491587, 0.9488780991876485, 0.0], [0.9488780991876485, 0.0, 0.0], [0.0, 0.0, 0.0]]

2. 循环,job2

接着开始第二次while循环,使用nextVector更新后的currentVector再针对输入数据跑一边job1的算法;感觉这里的rank值有点像是控制循环的次数的感觉;由于这里i初始就被设置为1了,而且rank设置为3,所以这里只循环两次;最后循环完成后,triDiag的值是:

[[0.315642761491587, 0.9488780991876485, 0.0], [0.9488780991876485, 2.855117440373572, 0.0], [0.0, 0.0, 0.0]]
因为接下来就是只对这个值进行操作,所以记录下这个值;

3.处理triDiag(3*3矩阵)

首先是初始化:

EigenDecomposition decomp = new EigenDecomposition(triDiag);
看着个初始化做的事情:首先去判断triDiag是否是对称的,是的话就执行if里面的操作:

public EigenDecomposition(Matrix x, boolean isSymmetric) {
    n = x.columnSize();
    d = new DenseVector(n);
    e = new DenseVector(n);
    v = new DenseMatrix(n, n);

    if (isSymmetric) {
      v.assign(x);

      // Tridiagonalize.
      tred2();

      // Diagonalize.
      tql2();

    } else {
      // Reduce to Hessenberg form.
      // Reduce Hessenberg to real Schur form.
      hqr2(orthes(x));
    }
  }
assign就是把x赋值给v,tred2和tql2是做什么的呢?

额,吓我一跳,because 太他X长了,果然java不适合做矩阵处理。。。


分享,成长,快乐

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


分享到:
评论

相关推荐

    mahout Algorithms源码分析

    mahoutAlgorithms源码分析 mahout代码解析

    svd mahout算法

    svd算法的工具类,直接调用出结果,调用及设置方式参考http://blog.csdn.net/fansy1990 &lt;mahout源码分析之DistributedLanczosSolver(七)&gt;

    mahout-examples-0.10.1-job.jar

    mahout-examples-0.10.1-job.jar 已经包含分词程序,替换掉mahout默认的jar包

    Mahout源码

    Mahout是一个Java的机器学习库。Mahout的完整源代码,基于maven,可以轻易导入工程中

    mahout源码

    mahout,朴素贝叶斯分类,中文分词,mahout,朴素贝叶斯分类,中文分词,

    mahout-examples-0.9-job.jar(修改版)

    重新编译mahout-examples-0.9-job.jar,增加分类指标:最小最大精度、召回率。详情见http://blog.csdn.net/u012948976/article/details/50203249

    mahout-examples-0.9-job.jar

    mahout-examples-0.9-job.jar

    mahout-distribution-0.5-src.zip mahout 源码包

    mahout-distribution-0.5-src.zip mahout 源码包

    mahout-core-0.7-job.jar

    用于测试mahout中的决策树 ,即Partial Implementation用到的测试jar包。所谓的测试其实也只是把相应的数据可以打印出来,方便单机调试,理解算法实现原理而已。

    mahout0.9源码(支持hadoop2)

    mahout0.9的源码,支持hadoop2,需要自行使用mvn编译。mvn编译使用命令: mvn clean install -Dhadoop2 -Dhadoop.2.version=2.2.0 -DskipTests

    MAHOUT源码包

    Mahout 是 Apache Software Foundation(ASF) 旗下的一个开源项目,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。Mahout包含许多实现,包括聚类、分类、推荐过滤...

    mahout 0.7 src

    mahout 0.7 src, mahout 源码包, hadoop 机器学习子项目 mahout 源码包

    mahout-0.11.1 相关的jar

    mahout-examples-0.11.1-job mahout-h2o_2.10-0.11.1 mahout-h2o_2.10-0.11.1-dependency-reduced mahout-hdfs-0.11.1 mahout-integration-0.11.1 mahout-math-0.11.1 mahout-math-0.11.1 mahout-mr-0.11.1 mahout-...

    mahout in action源代码maven编译jar包

    mahout in action中的example codes进行maven编译时由于maven相关jar包的URL的重定位,故无法进行有效编译,需要下载相关jar包进行手动加载!

    mahout 0.7

    mahout0.7,基于hadoop的数据挖掘开源应用工具

    mahout-distribution-0.5.tar.gz + 源码

    mahout实战 源码 mahout实战 配套 mahout-distribution-0.5.tar.gz 版本

    mahout in action中的源码

    该资源是mahout in action 中的源码,适用于自学,可在github下载:https://github.com/tdunning/MiA

    Apache Mahout Cookbook code

    Thank you for requesting the download for Apache Mahout Cookbook. Please click the following link to download the code:

    mahout api 学习资料

    mahout_help,mahout的java api帮助文档,可以帮你更轻松掌握mahout

Global site tag (gtag.js) - Google Analytics