Mahout版本:0.7,hadoop版本:1.0.4,jdk:1.7.0_25 64bit。
在上篇blog中的最後終端的資訊可以看到,svd演算法一共有5個Job任務。下面通過Mahout中DistributedLanczosSolver原始碼來一個個分析:
為了方便後面的資料隨時對照,使用wine.dat修改後的資料,如下(5行,13列):
14.23,1.71,2.43,15.6,127,2.8,3.06,0.28,2.29,5.64,1.04,3.92,1065 13.2,1.78,2.14,11.2,100,2.65,2.76,0.26,1.28,4.38,1.05,3.4,1050 13.16,2.36,2.67,18.6,101,2.8,3.24,0.3,2.81,5.68,1.03,3.17,1185 14.37,1.95,2.5,16.8,113,3.85,3.49,0.24,2.18,7.8,0.86,3.45,1480 13.24,2.59,2.87,21,118,2.8,2.69,0.39,1.82,4.32,1.04,2.93,735
1.首先,演算法使用main方法進行調用,看到main方法中只用一句:
ToolRunner.run(new DistributedLanczosSolver().job(), args);
所以直接去找run方法,進入96行的run方法,這裡都是初始化我們設定的參數了,這裡有一些參數是相對好理解的,比如資料的輸入、輸出以及輸入資料的行數、列數,但是,這裡有一個working dir參數,不知道是幹什麼的,還有symmetric,這個應該是說輸入資料是否是對稱的?rank參數,這個不理解。cleansvd,好像是對輸出結果的一個修飾還是什麼的,看官網上面設定為true,那這裡也按照設定為true的思路來分析。如果cleansvd是true的話,那麼接下來就有一個if條件判斷了,就會進入:
if (cleansvd) { double maxError = Double.parseDouble(AbstractJob.getOption(parsedArgs, "--maxError")); double minEigenvalue = Double.parseDouble(AbstractJob.getOption(parsedArgs, "--minEigenvalue")); boolean inMemory = Boolean.parseBoolean(AbstractJob.getOption(parsedArgs, "--inMemory")); return run(inputPath, outputPath, outputTmpPath, workingDirPath, numRows, numCols, isSymmetric, desiredRank, maxError, minEigenvalue, inMemory); }
這裡先初始化三個參數,這裡都是按照預設的,maxError是0.05,minEigenvalue是0,inMemory是false;
然後進入run方法,這個run方法是調用142行的方法,這個方法中還有一個run方法以及另外一個Job,如下:
public int run(Path inputPath, Path outputPath, Path outputTmpPath, Path workingDirPath, int numRows, int numCols, boolean isSymmetric, int desiredRank, double maxError, double minEigenvalue, boolean inMemory) throws Exception { int result = run(inputPath, outputPath, outputTmpPath, workingDirPath, numRows, numCols, isSymmetric, desiredRank); if (result != 0) { return result; } Path rawEigenVectorPath = new Path(outputPath, RAW_EIGENVECTORS); return new EigenVerificationJob().run(inputPath, rawEigenVectorPath, outputPath, outputTmpPath, maxError, minEigenvalue, inMemory, getConf() != null ? new Configuration(getConf()) : new Configuration()); }
這裡看到有一個run方法,所以應該是這個run方法調用了三個Job,然後最後調用EigenVerificationJob.run()方法最後運行一個job,然後一共四個job,這個只是猜測。先看run方法裡面的吧。進入181行的run方法,額,好吧,還在這個類中。這個run方法中才有點實質的內容:
public int run(Path inputPath, Path outputPath, Path outputTmpPath, Path workingDirPath, int numRows, int numCols, boolean isSymmetric, int desiredRank) throws Exception { DistributedRowMatrix matrix = new DistributedRowMatrix(inputPath, outputTmpPath, numRows, numCols); matrix.setConf(new Configuration(getConf() != null ? getConf() : new Configuration())); LanczosState state; if (workingDirPath == null) { state = new LanczosState(matrix, desiredRank, getInitialVector(matrix)); } else { HdfsBackedLanczosState hState = new HdfsBackedLanczosState(matrix, desiredRank, getInitialVector(matrix), workingDirPath); hState.setConf(matrix.getConf()); state = hState; } solve(state, desiredRank, isSymmetric); Path outputEigenVectorPath = new Path(outputPath, RAW_EIGENVECTORS); serializeOutput(state, outputEigenVectorPath); return 0; }