mahout之canopy聚類算法

mahout中數據挖掘算法是運行在hadoop之上的分佈式算法,可以分佈式運行也可以在單機上運行。

這篇博文是本人你學習mahout算法的開始,以下是個人對mahout中實現的canopy的理解,如果錯誤,歡迎糾正


首先下載mahout-0.12的源碼,解壓後有個examples文件夾,該文件夾裏面有對mahout算法使用的例子,打開

\examples\src\main\java\org\apache\mahout\clustering\syntheticcontrol\canopy\job.java。該文件裏面寫了如何使用canopy算法。以下以此爲主線進行講解


該文件也可以在以下地址下載到:



首先,可以很直觀的看到,Job類繼續了AbstractJob類,何爲AbstractJob類呢,它是org.apache.mahout.common包下的一個抽象類,該類封裝運行時輸出輸出路徑,以及通過命令行運行jar包時,參數的解析和存儲等,所以自己寫改寫mahout算法或者基於原有的mahout算法添加等都要繼承它。AbstractJob抽象類也繼承了 Configured類和 Tool 接口。Configured類是運行配置類相關。Tool接口中有個run方法,所以繼續AbstractJob都要實現run方法。run中一般實現命令行運行時參數的解析和賦值,然後調用mahout中canopy算法進行使用。


在job.java文件中,main方法如下:

 public static void main(String[] args) throws Exception {
    if (args.length > 0) {
      log.info("Running with only user-supplied arguments");
      ToolRunner.run(new Configuration(), new Job(), args);
    } else {
      log.info("Running with default arguments");
      Path output = new Path("hdfs://192.168.95.131:9000/user/mahout/Canopyoutput");
      HadoopUtil.delete(new Configuration(), output);
      //輸入文件數據之間一定要以空格隔開,否則解析會出錯
      run(new Path("movement_libras.data1.txt"), output, new EuclideanDistanceMeasure(), 0.3, 0.6);
    }
  }

意思是:如果提交任務時有傳參數的話,則運行  ToolRunner.run(new Configuration(), new Job(), args)。其中ToolRunner類作用是讓繼承了AbstractJob類的 Job調用自己的run方法(重載tool中的run方法),其中args爲run方法的參數。

接下來,我們來看下job.java如何實現tool中的run方法,代碼如下:

@Override
  public int run(String[] args) throws Exception {

  //添加默認的輸入目錄
    addInputOption();

 //添加默認的輸出目錄
    addOutputOption();

//添加默認的距離計算方法
    addOption(DefaultOptionCreator.distanceMeasureOption().create());

//添加默認的t1門限值
    addOption(DefaultOptionCreator.t1Option().create());

//添加默認的t2門限值
    addOption(DefaultOptionCreator.t2Option().create());

//添加是否去輸出目錄進行覆蓋
    addOption(DefaultOptionCreator.overwriteOption().create());

    Map<String, List<String>> argMap = parseArguments(args);
    if (argMap == null) {
      return -1;
    }
    Path input = getInputPath();
    Path output = getOutputPath();
    if (hasOption(DefaultOptionCreator.OVERWRITE_OPTION)) {
      HadoopUtil.delete(new Configuration(), output);
    }
    String measureClass = getOption(DefaultOptionCreator.DISTANCE_MEASURE_OPTION);
    double t1 = Double.parseDouble(getOption(DefaultOptionCreator.T1_OPTION));
    double t2 = Double.parseDouble(getOption(DefaultOptionCreator.T2_OPTION));
    DistanceMeasure measure = ClassUtils.instantiateAs(measureClass, DistanceMeasure.class);
    run(input, output, measure, t1, t2);
    return 0;
  }

在run方法中,剛開始是添加默認的參數,然後解析comment line的命令,最後調用job.java自身寫的run方法


job.java自身的run方法如下:

private static void run(Path input, Path output, DistanceMeasure measure,
      double t1, double t2) throws Exception {
    Path directoryContainingConvertedInput = new Path(output,
        DIRECTORY_CONTAINING_CONVERTED_INPUT);//output是父目錄,DIRECTORY_CONTAINING_CONVERTED_INPUT是父目錄下的子目錄
    InputDriver.runJob(input, directoryContainingConvertedInput, //data裏面存放着數據序列化的文件
        "org.apache.mahout.math.RandomAccessSparseVector");
    CanopyDriver.run(new Configuration(), directoryContainingConvertedInput,
        output, measure, t1, t2, true, 0.0, false);
    // run ClusterDumper
    ClusterDumper clusterDumper = new ClusterDumper(new Path(output,
       "clusters-0-final"), new Path(output, "clusteredPoints"));
    //String aa="C:\\Users\\whl\\Desktop\\WHL\\common-knowleage\\hadoop\\mahout-exec\\canopy\\output\\a.txt";
    //clusterDumper.setTermDictionary(aa, "text");AbstractJob
    //Job job=new Job();
    //this.outputFile=new File(aa);
    clusterDumper.printClusters(null);
    
    //cluster-0-finall文件夾存放的是聚類中心的信息
    //clusteredPoints存放的是點的聚類結果信息
  }

其中InputDriver job中,只有mapper處理類,是爲了將數據輸出爲cannopy能夠處理的數據類型,要求原始數據類型行代表一條記錄,記錄內不同屬性的值用空格隔開。

其中cannopy要求輸入的數據爲sequencefileinputformat類型,在sequenceFile中,mapper的輸入的value類型是vectorwritable,輸出是clusterwritable;ruducer的輸入輸出都是clusterwritable。在hdfs中,序列化的類型都繼承了writable接口,實現了read和write函數,read函數作用將從序列化文件讀入內存,而write函數的作用是將類序列化,在hadoop中,已經實現了intwritable,doublewritable,longwritable。而mahout.math中實現了算法相關的序列化類。同時,hadoop中mapper向reducer傳遞的數據也是序列化表示形式。

 CanopyDriver以inputDriver的輸出文件作爲它的輸入文件,運行map,reduce聚類算法,其中true表示進行數據的聚類過程,如果爲false則表示只計算了中心點向量,不對數據進行聚類劃分。0.0參數表示聚類的門限值(vectors having pdf below this value will not be clustered. Its value should be between 0 and 1.,具體還未搞清楚),false參數表示是否序列化( execute sequentially if true)。

ClusterDumper類可以將聚類結果打印出來


爲清楚的點:

    addInputOption();
    addOutputOption();
    addOption(DefaultOptionCreator.distanceMeasureOption().create());

   默認參數的添加,內部是如何解析賦值的,如何覆蓋默認參數?

option的使用見:

http://blog.csdn.net/utopia_1919/article/details/51832471博文

接下來學習如何使用canopy

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章