Mahout源码分析DistributedLanczosSolver(3)--Job2
来源:互联网 发布:添加网络打印机步骤 编辑:程序博客网 时间:2024/06/03 11:04
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.01187710.0017762260.0021732280.014294310.0966174390.002638990.00268705000.0050126000.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.0732503820.009072747-0.0849057-0.0848576-0.1-0.1-0.082532-0.1-0.10.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源码分析DistributedLanczosSolver(3)--Job2
- Mahout源码分析之DistributedLanczosSolver(5)
- Mahout源码分析之DistributedLanczosSolver(1)--实战
- Mahout源码分析之DistributedLanczosSolver(2)--Job1
- Mahout源码分析之DistributedLanczosSolver(4)--rawEigen
- Mahout源码分析之DistributedLanczosSolver(6)--完结篇
- Mahout源码分析之DistributedLanczosSolver(7)--总结篇
- Mahout决策树算法源码分析(3)
- Mahout贝叶斯算法源码分析(3)
- Mahout决策树算法源码分析(3-1)建树实战
- Mahout源码canopy聚类算法分析(3)
- Mahout源码K均值聚类算法分析(3)
- Mahout源码MeanShiftCanopy聚类算法分析(3)
- Mahout源码MeanShiftCanopy聚类算法分析(3-1)
- Mahout贝叶斯算法源码分析(2-3)
- Mahout随机森林算法源码分析(2-3)
- Mahout随机森林算法源码分析(3)--TestForest
- Mahout协同过滤算法源码分析(3)--parallelALS
- mysql将unix时间戳和时间字符串的相互转化
- 反汇编角度深入学习C++第一课:C++的命名空间
- 一步一步在Linux上安装Oracle 11gR2 RAC (4)
- Leetcode: Jump Game
- 备份数据库
- Mahout源码分析DistributedLanczosSolver(3)--Job2
- 编译时向内核添加新设备 模块的方式动态的将驱动加入内核,但这种方式加入的驱动程序,当系统重新启动时, 还需要重新用模块的方式进行插入,如果是系统内常用的设备驱动采用这种方式进行加载, 就会很不方便。
- 如何在Visual Studio项目中正确添加汇编代码
- ios开发有用的文档
- (字符串的模式匹配4.7.19——前缀数组suffix的应用)POJ 2752 Seek the Name, Seek the Fame(求解一个字符串中前缀和后缀一样的位置)
- YARN/MRv2 Resource Manager深入剖析—用户交互相关模块分析
- 依赖倒置原则
- [Usaco 2011 Dec]Umbrellas for Cows
- 一步一步在Linux上安装Oracle 11gR2 RAC (5)