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


很早在实验室就看见钱宝宝用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:


 


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. this.getClass().getClassLoader().getResource("").getPath();  
24.         System.out.println(path);  
25. try {  
26. 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. 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. this.getClass().getClassLoader().getResource("models/dict.txt").getPath();  
56.   
57. null;  
58. try {  
59. 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<String> flitStopWords(String[] words) {  
71. try {  
72.             List<String> 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的依赖:

 


1. <dependency>  
2. <groupId>org.fnlp</groupId>  
3. <artifactId>fnlp-core</artifactId>  
4. <version>2.1-SNAPSHOT</version>  
5. </dependency>  
6.   
7. <dependency>  
8. <groupId>junit</groupId>  
9. <artifactId>junit</artifactId>  
10. <version>4.11</version>  
11. </dependency>

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

 


1. public void processFile() throws Exception{  
2. this.getClass().getClassLoader().getResource("text/tlbb.txt").getPath();  
3. new BufferedReader(new FileReader(filePath));  
4.   
5. new File("/Users/KrseLee/dataset/tlbb_t.txt");  
6. if (outfile.exists()) {  
7.            outfile.delete();  
8.        }  
9. new FileOutputStream(outfile);  
10.   
11. // 构建FileOutputStream对象,文件不存在会自动新建  
12.        String line = in.readLine();  
13. 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. // 关闭写入流,同时会把缓冲区内容写入文件  
21. // 关闭输出流,释放系统资源  
22.    }


三.     构建Word2Vector模型并训练

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


    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. new ClassPathResource("text/tlbb_t.txt").getFile().getAbsolutePath();  
    22.   
    23. "Load & Vectorize Sentences....");  
    24. // Strip white space before and after for each line  
    25. new BasicLineIterator(filePath);  
    26. // Split on white spaces in the line to get words  
    27.   
    28. "Building model....");  
    29. new Word2Vec.Builder()  
    30. 5)  
    31. 1)  
    32. 100)  
    33. 42)  
    34. 5)  
    35.             .iterate(iter)  
    36.             .build();  
    37.   
    38. "Fitting Word2Vec model....");  
    39.         vec.fit();  
    40.   
    41. "Writing word vectors to text file....");  
    42.   
    43. // Write word vectors  
    44. "tlbb_vectors.txt");  
    45. "tlbb_model.txt");  
    46. "萧峰","乔峰","段誉","虚竹","王语嫣","阿紫","阿朱","木婉清"};  
    47. "Closest Words:");  
    48.   
    49. for(String name:names) {  
    50. ">>>>>>");  
    51. 10);  
    52.             System.out.println(lst);  
    53.         }  
    54.     }  
    55. }


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

    四.     测试并输出

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


     

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