DeepLearning4J入门——让计算机阅读《天龙八部》

DeepLearning4J入门——让计算机阅读《天龙八部》

原文网址:   http://blog.csdn.net/a398942089/article/details/51970691


很早在实验室就看见钱宝宝用Google的Word2Vector来阅读《天龙八部》并找出与指定词最相关的几个词,最近正好学习新出的深度学习开源项目DeepLearning4J,于是就拿这个例子来练手吧。DL4J快速入门请看 http://deeplearning4j.org/quickstart.html 。

DeepLearning4J的Example中自带了很多应用实例,Word2Vector也在其中,因此我的工作主要是以下几步:

1.    准备开发环境和原始数据

2.    分词,格式转换

3.    构建Word2Vector模型并训练

4.    测试并输出

 

一.     准备开发环境和原始数据

开发环境我使用的是IDEA(用eclipse也OK),JDK1.7,Maven3.3.1。

上武侠小说网下载一篇《天龙八部》,去掉文件首尾的不相关信息,重命名放到指定位置,OK。

二.     分词、格式转换

我比较喜欢使用复旦NLP,一是用惯了熟练,二是使用起来也方便,Maven引用FNLP有一点小问题,解决方法可以参考我以前的文章,这里不再赘述。

新建Java工程(或者直接使用DL4J-example工程),新建JavaClass,命名为FudanTokenizer:

[java]  view plain  copy
 
  1. package edu.zju.cst.krselee.example.word2vector;  
  2.   
  3. /** 
  4.  * Created by KrseLee on 16/7/20. 
  5.  */  
  6.   
  7.     import org.fnlp.nlp.cn.tag.CWSTagger;  
  8.     import org.fnlp.util.exception.LoadModelException;  
  9.   
  10.     import java.io.IOException;  
  11.     import java.util.List;  
  12.   
  13.     import org.fnlp.ml.types.Dictionary;  
  14.     import org.fnlp.nlp.corpus.StopWords;  
  15.   
  16. public class FudanTokenizer {  
  17.   
  18.     private CWSTagger tag;  
  19.   
  20.     private StopWords stopWords;  
  21.   
  22.     public FudanTokenizer() {  
  23.         String path = this.getClass().getClassLoader().getResource("").getPath();  
  24.         System.out.println(path);  
  25.         try {  
  26.             tag = new CWSTagger(path + "models/seg.m");  
  27.         } catch (LoadModelException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.   
  31.     }  
  32.   
  33.     public String processSentence(String context) {  
  34.         String s = tag.tag(context);  
  35.         return s;  
  36.     }  
  37.   
  38.     public String processSentence(String sentence, boolean english) {  
  39.         if (english) {  
  40.             tag.setEnFilter(true);  
  41.         }  
  42.         return tag.tag(sentence);  
  43.     }  
  44.   
  45.     public String processFile(String filename) {  
  46.         String result = tag.tagFile(filename);  
  47.   
  48.         return result;  
  49.     }  
  50.   
  51.     /** 
  52.      * 设置分词词典 
  53.      */  
  54.     public boolean setDictionary() {  
  55.         String dictPath = this.getClass().getClassLoader().getResource("models/dict.txt").getPath();  
  56.   
  57.         Dictionary dict = null;  
  58.         try {  
  59.             dict = new Dictionary(dictPath);  
  60.         } catch (IOException e) {  
  61.             return false;  
  62.         }  
  63.         tag.setDictionary(dict);  
  64.         return true;  
  65.     }  
  66.   
  67.     /** 
  68.      * 去除停用词 
  69.      */  
  70.     public List flitStopWords(String[] words) {  
  71.         try {  
  72.             List baseWords = stopWords.phraseDel(words);  
  73.             return baseWords;  
  74.         } catch (Exception e) {  
  75.             e.printStackTrace();  
  76.             return null;  
  77.         }  
  78.     }  
  79. }  


并将模型文件(可以从FNLP的主页下载)拷入到resources目录下:

pom.xml里面添加FNLP的依赖:

 

[html]  view plain  copy
 
  1. <dependency>  
  2.     <groupId>org.fnlpgroupId>  
  3.     <artifactId>fnlp-coreartifactId>  
  4.     <version>2.1-SNAPSHOTversion>  
  5. dependency>  
  6.   
  7. <dependency>  
  8.     <groupId>junitgroupId>  
  9.     <artifactId>junitartifactId>  
  10.     <version>4.11version>  
  11. dependency>  

       等Maven把工程编译好,将之前下载的数据文件放到resources目录下,新建一个主方法或者单元测试来执行分词:

 

[java]  view plain  copy
 
  1. public void processFile() throws Exception{  
  2.        String filePath = this.getClass().getClassLoader().getResource("text/tlbb.txt").getPath();  
  3.        BufferedReader in = new BufferedReader(new FileReader(filePath));  
  4.   
  5.        File outfile = new File("/Users/KrseLee/dataset/tlbb_t.txt");  
  6.        if (outfile.exists()) {  
  7.            outfile.delete();  
  8.        }  
  9.        FileOutputStream fop = new FileOutputStream(outfile);  
  10.   
  11.        // 构建FileOutputStream对象,文件不存在会自动新建  
  12.        String line = in.readLine();  
  13.        OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");  
  14.        while(line!=null) {  
  15.            line = tokenizer.processSentence(line);  
  16.            writer.append(line);  
  17.            line = in.readLine();  
  18.        }  
  19.        in.close();  
  20.        writer.close(); // 关闭写入流,同时会把缓冲区内容写入文件  
  21.        fop.close(); // 关闭输出流,释放系统资源  
  22.    }  

三.     构建Word2Vector模型并训练

引入DeepLearning4J的依赖包,新建Java Class ZhWord2Vector,代码如下:

[java]  view plain  copy
 
  1. package edu.zju.cst.krselee.example.word2vector;  
  2.   
  3. import org.canova.api.util.ClassPathResource;  
  4. import org.deeplearning4j.models.embeddings.loader.WordVectorSerializer;  
  5. import org.deeplearning4j.models.word2vec.Word2Vec;  
  6. import org.deeplearning4j.text.sentenceiterator.BasicLineIterator;  
  7. import org.deeplearning4j.text.sentenceiterator.SentenceIterator;  
  8. import org.slf4j.Logger;  
  9. import org.slf4j.LoggerFactory;  
  10.   
  11. import java.util.Collection;  
  12.   
  13. /** 
  14.  * Created by KrseLee on 16/7/20. 
  15.  */  
  16. public class ZhWord2Vector {  
  17.     private static Logger log = LoggerFactory.getLogger(ZhWord2Vector.class);  
  18.   
  19.     public static void main(String[] args) throws Exception {  
  20.   
  21.         String filePath = new ClassPathResource("text/tlbb_t.txt").getFile().getAbsolutePath();  
  22.   
  23.         log.info("Load & Vectorize Sentences....");  
  24.         // Strip white space before and after for each line  
  25.         SentenceIterator iter = new BasicLineIterator(filePath);  
  26.         // Split on white spaces in the line to get words  
  27.   
  28.         log.info("Building model....");  
  29.         Word2Vec vec = new Word2Vec.Builder()  
  30.             .minWordFrequency(5)  
  31.             .iterations(1)  
  32.             .layerSize(100)  
  33.             .seed(42)  
  34.             .windowSize(5)  
  35.             .iterate(iter)  
  36.             .build();  
  37.   
  38.         log.info("Fitting Word2Vec model....");  
  39.         vec.fit();  
  40.   
  41.         log.info("Writing word vectors to text file....");  
  42.   
  43.         // Write word vectors  
  44.         WordVectorSerializer.writeWordVectors(vec, "tlbb_vectors.txt");  
  45.         WordVectorSerializer.writeFullModel(vec,"tlbb_model.txt");  
  46.         String[] names = {"萧峰","乔峰","段誉","虚竹","王语嫣","阿紫","阿朱","木婉清"};  
  47.         log.info("Closest Words:");  
  48.   
  49.         for(String name:names) {  
  50.             System.out.println(name+">>>>>>");  
  51.             Collection lst = vec.wordsNearest(name, 10);  
  52.             System.out.println(lst);  
  53.         }  
  54.     }  
  55. }  

       将上一步得到的输出文件拷贝到resources目录下。

四.     测试并输出

更改你想要查看的单词,运行程序,等待约4分钟,得到输出。不同的电脑因性能原因需要的时间不一致,深度网络的训练本身也是一件费时费力的事情。

[plain]  view plain  copy
 
  1. 萧峰>>>>>>  
  2. [段誉, 叫骂, 一队队, 军官, 将, 狗子, 长矛, 指挥, 说, 传令]  
  3. 乔峰>>>>>>  
  4. [南, 大侠, 北, 大英雄, 四海, 厮, 听说, 奸谋, 威震, 全舵]  
  5. 段誉>>>>>>  
  6. [萧峰, 虚竹, 向, 玄渡, 等, 叫骂, 去, 辽兵, 一边, 城门]  
  7. 虚竹>>>>>>  
  8. [段誉, 向西, 萧峰, 向, 城门, 叫骂, 等, 辽兵, 玄鸣, 去]  
  9. 王语嫣>>>>>>  
  10. [巴天石, 钟灵, 木婉清, 草海, 朱丹臣, 老婆婆, 瘴气, 贾老者, 嗒嗒嗒, 途中]  
  11. 阿紫>>>>>>  
  12. [道, 穆贵妃, 抿嘴笑, 姊夫, 来, 叫, 又, 小嘴, 大人, 什么]  
  13. 阿朱>>>>>>  
  14. [深情, 想起, 换上, 父母, 想念, 恩情, 胡作非为, 迫, 情意, 永远]  
  15. 木婉清>>>>>>  
  16. [钟灵, 朱丹臣, 巴天石, 秦红棉, 范骅, 一行人, 王语嫣, 墙外, 阮星竹, 巴天]  


你可能感兴趣的:(Deep,Learning)