美文网首页
lightLDA使用

lightLDA使用

作者: yxwithu | 来源:发表于2017-08-15 14:47 被阅读0次

    到目前为止,github上的LightLDA还没有出比较详尽的文档,所以我在使用前进行了一番摸索。本文主要是对LightLDA单机版使用的一些简单说明,包括输入输出的格式说明,参数说明和自己实现的java版本的输入输出接口。

    输入

    输入数据需要放在一个文件夹下,输入需要先把输入数据转化为libsvm格式,再由LightLDA提供的独立的dump_binary工具将libsvm格式转化为可用的格式。example目录下有text2libsvm.py文件,可以将UCI文件转化为libsvm文件。
    UCI文件格式见链接不再赘述。

    D
    W
    NNZ
    docID wordID count
    docID wordID count
    ...
    docID wordID count

    libsvm格式:两个文件 libsvm和 dict
    libsvm:

    文档号\t词id1:该词在文档中出现次数 词id2:次数 ...
    文档号从1开始代指某篇文档
    词id以0开始,与dict对应
    次数为文档号对应的文档中该词出现的次数不是总次数

    dict:

    词id\t对应词\t出现总数\n
    出现总数是所有文档出现总数

    我写了一个可以将分词后的结果转换为非严格UCI格式的工具,在工具:text2UCI,可供参考。
    可以遵循 text -> UCI -> libsvm -> dump这样的步骤得到lightLDA的输入文件。或者直接生成libsvm格式,再dump。dump_binary这一步是不可少的,是lightLDA为了提升性能转化为其自定义的文件格式。

    dump_binary用法
    dump_binary <libsvm_input> <word_dict_file_input> <binary_output_dir> <output_file_offset>

    训练参数

    void Config::PrintTrainingUsage()
    {
        printf("LightLDA usage: \n");
        printf("-num_vocabs <arg>        Size of dataset vocabulary \n");
        printf("-num_topics <arg>        Number of topics. Default: 100\n");
        printf("-num_iterations <arg>    Number of iteratioins. Default: 100\n");
        printf("-mh_steps <arg>          Metropolis-hasting steps. Default: 2\n");
        printf("-alpha <arg>             Dirichlet prior alpha. Default: 0.1\n");
        printf("-beta <arg>              Dirichlet prior beta. Default: 0.01\n\n");
        printf("-num_blocks <arg>        Number of blocks in disk. Default: 1\n");
        printf("-max_num_document <arg>  Max number of document in a data block \n");
        printf("-input_dir <arg>         Directory of input data, containing\n");
        printf("                         files generated by dump_block \n\n");
        printf("-num_servers <arg>       Number of servers. Default: 1\n");
        printf("-num_local_workers <arg> Number of local training threads. Default: 4\n");
        printf("-num_aggregator <arg>    Number of local aggregation threads. Default: 1\n");
        printf("-server_file <arg>       Server endpoint file. Used by MPI-free version\n"); 
        printf("-warm_start              Warm start \n");
        printf("-out_of_core             Use out of core computing \n\n");
        printf("-data_capacity <arg>     Memory pool size(MB) for data storage, \n");
        printf("                         should larger than the any data block\n");
        printf("-model_capacity <arg>    Memory pool size(MB) for local model cache\n");
        printf("-alias_capacity <arg>    Memory pool size(MB) for alias table \n");
        printf("-delta_capacity <arg>    Memory pool size(MB) for local delta cache\n");
        exit(0);
    }
    

    说明

    -num_vocabs 数据集中包含的单词数目,是词汇表中的词的数目,可以比实际值偏大
    -num_topics 要训练的主题数目,经验值是sqrt(#docs)/3,可以用HDP或交叉验证确定
    -num_iterations 迭代次数,越多越好
    -alpha 对称Dirichlet分布的参数alpha,经验值设置为 50/#topics
    -beta 对称Dirichlet分布的参数beta, 经验值设置为0.1
    -max_num_document 训练的文档数目
    -input_dir 训练数据所在目录,目录下需有转化为lightlda自定义的输入格式文件
    -data_capacity 至少要最大的block文件的size,block文件是由dump_binary生成的。
    -model/alias/delta capacity 可以指定任意值,一般model/alias大小是同义数量级,delta相对会小很多。

    例子

    $bin/lightlda -num_vocabs 111400 -num_topics 1000 -num_iterations 100 -alpha 0.1 -beta 0.01 -mh_steps 2 -num_local_workers 1 -num_blocks 1 -max_num_document 300000 -input_dir $dir -data_capacity 800

    输出结果

    每轮训练时间会随着迭代次数增加而减少,本地实验中,153W+个词汇,14W+篇文档,共耗时4h。输出结果主要是4个文件

    1. doc_topic.blockID 这个blockID下的doc_topic分布,格式: 文档id 主题id:次数
    2. server_0_table_0.model word_topic分布,格式:词id 主题id:次数
    3. server_0_table_1.model 只有一行,所有主题的出现次数统计, 主题id:次数
    4. log文件

    输出给出了每个词的主题次数分布和每篇文档的主题次数分布,没有给出文档-主题的概率分布和主题-词的概率分布。但是根据这个结果已经可以得到概率分布,需要自己写一个接口,进行频数统计。

    如果是来了一篇新文档,可以利用已知的词分布,也可以通过采样得到新文档的主题分布。也可以通过lightLDA的对新文档的接口infer方法,得到转化结果。

    我写了个转化接口,可以让结果看起来更直观一点,lightLDA输出接口-java版本

    相关文章

      网友评论

          本文标题:lightLDA使用

          本文链接:https://www.haomeiwen.com/subject/mmpmrxtx.html