查看: 5958|回复: 63
打印 上一主题 下一主题

[英英] 整理了一下《傲慢与偏见》中出现两次及以上的单词【含...

[复制链接]

该用户从未签到

19

主题

363

回帖

2553

积分

解元

Rank: 5Rank: 5

积分
2553

灌水大神章小蜜蜂章笑傲江湖章

跳转到指定楼层
1
发表于 2016-7-15 16:44:26 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

本帖被以下淘专辑推荐:

该用户从未签到

19

主题

363

回帖

2553

积分

解元

Rank: 5Rank: 5

积分
2553

灌水大神章小蜜蜂章笑傲江湖章

推荐
 楼主| 发表于 2016-7-18 12:08:06 | 只看该作者
本帖最后由 fnaviwwo1 于 2016-7-19 16:52 编辑

用 Scala 和 Stanford 的 NLP 工具重写了一遍,生成的质量和上面的 Python/Nltk 各有千秋。



  1. import java.io.File
  2. import java.io.FileReader
  3. import java.io.PrintWriter
  4. import java.io.Reader
  5. import java.io.StringReader

  6. import scala.annotation.migration
  7. import scala.collection.JavaConversions.asScalaBuffer
  8. import scala.collection.mutable.ArrayBuffer
  9. import scala.collection.mutable.HashMap
  10. import scala.io.Source

  11. import org.apache.lucene.morphology.english.EnglishLuceneMorphology

  12. import edu.stanford.nlp.ling.CoreLabel
  13. import edu.stanford.nlp.ling.HasWord
  14. import edu.stanford.nlp.process.CoreLabelTokenFactory
  15. import edu.stanford.nlp.process.Morphology
  16. import edu.stanford.nlp.process.PTBTokenizer
  17. import edu.stanford.nlp.tagger.maxent.MaxentTagger

  18. object ConvDoc extends App {
  19.   val DEBUG = false //|| true
  20.   def run(filename: String, title: String) = {
  21.     val luceneMorph = new EnglishLuceneMorphology();
  22.     def get_adj_or_adv(w: String) = luceneMorph.getNormalForms(w.toLowerCase()).sortBy(_.size).apply(0)
  23.     val comp = Set("JJR", "JJS", "RBR", "RBS")

  24.     val stopwords = Set("xi", "x", "_", "a", "about", "above", "after", "again", "against", "ain", "all", "am", "an", "and", "any", "are", "aren", "as", "at", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "ca", "can", "couldn", "d", "did", "didn", "do", "does", "doesn", "doing", "don", "down", "during", "each", "few", "for", "from", "further", "had", "hadn", "has", "hasn", "have", "haven", "having", "he", "her", "here", "hers", "herself", "him", "himself", "his", "how", "i", "if", "in", "into", "is", "isn", "it", "its", "itself", "just", "ll", "m", "ma", "me", "mightn", "more", "most", "much", "mustn", "my", "myself", "needn", "no", "nor", "not", "now", "o", "of", "off", "on", "once", "only", "or", "other", "our", "ours", "ourselves", "out", "over", "own", "re", "s", "same", "shan", "she", "should", "shouldn", "so", "some", "such", "t", "than", "that", "the", "their", "theirs", "them", "themselves", "then", "there", "these", "they", "this", "those", "through", "to", "too", "under", "until", "up", "ve", "very", "was", "wasn", "we", "were", "weren", "what", "when", "where", "which", "while", "who", "whom", "why", "will", "with", "won", "wouldn", "y", "you", "your", "yours", "yourself", "yourselves")
  25.     val words = Source.fromFile("userdata/words.txt").getLines().toSet
  26.     val ptbTokenizerFactory = PTBTokenizer.factory(new CoreLabelTokenFactory(), "invertible=true");
  27.     val m = new Morphology()
  28.     //var r: Reader = new StringReader("I'm using StanfordCore NLP Library for my project. It uses PTB Tokenizer for tokenization.");
  29.     var r: Reader = null
  30.     //r = new FileReader("Pride and Prejudice.txt")
  31.     var text = Source.fromFile(filename).getLines.mkString(" ").replaceAll("(\\s)+", " ")
  32.     //text = "Elizabeth listened in silence, but was not convinced; their behaviour at the assembly had not been calculated to please in general; and with more quickness of observation and less pliancy of temper than her sister, and with a judgment too unassailed by any attention to herself, she was very little disposed to approve them."
  33.     r = new StringReader(text)
  34.     val ss = MaxentTagger.tokenizeText(r, ptbTokenizerFactory);
  35.     println(ss.length)
  36.     var model:String=null
  37.     model= "english-left3words-distsim.tagger"//faster
  38.     model = "english-bidirectional-distsim.tagger"//more accurate
  39.     val tagger = new MaxentTagger(model)
  40.     val gg = new HashMap[String, ArrayBuffer[(Int, String)]]()
  41.     val pos_t = Set('V', 'N', 'J', 'R', 'I', 'M', 'W')
  42.     println()
  43.     def filter_word(word: String, tag: String) = {
  44.       pos_t.contains(tag(0)) && !tag.startsWith("NNP") && !stopwords.contains(word.toLowerCase()) // && !tag.startsWith(".")
  45.     }
  46.     def find_words(sent: java.util.List[HasWord]) = {
  47.       val s = tagger.tagSentence(sent)
  48.       if (DEBUG) println(s)
  49.       s.filter { x => filter_word(x.word(), x.tag()) }
  50.         .map(x =>
  51.           if (comp.contains(x.tag())) {
  52.             (get_adj_or_adv(x.word()), x.word())
  53.           } else
  54.             (m.lemma(x.word(), x.tag()), x.word())) //+ "_" + x.tag()
  55.     }
  56.     def get_sent(xs: java.util.List[HasWord]) = {
  57.       xs.flatMap { x =>
  58.         val o = x.asInstanceOf[CoreLabel]
  59.         Seq(o.originalText(), o.after())
  60.       }.mkString.trim().replaceAll("(\\s)+", " ")
  61.     }
  62.     for (i <- 0 until (if (DEBUG) Math.min(20, ss.size) else ss.length)) {
  63.       if (i % 100 == 1) println(i)
  64.       if (DEBUG) println("[" + get_sent(ss(i)) + "]")
  65.       val words = find_words(ss(i))
  66.       if (DEBUG) println(words)
  67.       words.foreach {
  68.         case (x, y) =>
  69.           gg.getOrElseUpdate(x, new ArrayBuffer()) += ((i, y))
  70.       }
  71.     }
  72.     println(gg.keys.toList)
  73.     println(gg("behaviour"))
  74.     //println(gg("behavior"))

  75.     if (!DEBUG) {
  76.       val out = new PrintWriter(new File(filename + ".wordlist.htm"))
  77.       val wordlist = gg.keys.map { x => (x, gg(x).length) }
  78.         .filter(x => x._2 > 1)
  79.         .filter(x => words.contains(x._1))
  80.         .toList.sortBy(x => x._1)
  81.       println(wordlist.size)
  82.       out.println("<html><body>")
  83.       out.println(title)
  84.       val escape = (x: String) => x.replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("&", "&amp;")
  85.       for (i <- 0 until (wordlist.size)) {
  86.         val e = wordlist(i)
  87.         val headword = e._1
  88.         val count = e._2
  89.         out.println(s"<h3>${i + 1} <font color=blue>$headword</font> (${count})</h3>")
  90.         val t = gg(headword)(0)
  91.         out.println("<p>")
  92.         out.println(escape(get_sent(ss(t._1))).replaceAll(s"\\b(${t._2})\\b", "<font color=red><b>$1</b></font>"))
  93.         out.println("</p>")
  94.       }
  95.       out.println("</body></html>")
  96.       out.close()
  97.       println("ok")
  98.     }

  99.   }
  100.   run("userdata/Pride and Prejudice.txt", "<h1>Pride and Prejudice</h1>")
  101. }

复制代码


注:感觉nlp4j这个库的Morphology模块更符合需求啊...有个叫LanguageTool的库也很有趣...


附件为按照字典序的输出文件。

Pride and Prejudice.txt.wordlist.zip

202.01 KB, 下载次数: 93, 下载积分: 米 -5 粒

该用户从未签到

19

主题

363

回帖

2553

积分

解元

Rank: 5Rank: 5

积分
2553

灌水大神章小蜜蜂章笑傲江湖章

推荐
 楼主| 发表于 2016-7-18 20:08:52 | 只看该作者
本帖最后由 fnaviwwo1 于 2016-7-19 17:35 编辑
heyuan-cwh 发表于 2016-7-18 19:39
好工具,我以前做那个试卷词典时,在github中找了几个代码,分别尝试了,但都只能得到该单词在一个文本中“ ...


前辈您好!!当初就是受到您制作词典的启发,一直想能制作类似的词典。

我想法是利用一些NLP工具箱,并参考了一些语料库的使用说明。

首先进行分词分句把文本分割成 List<List<String>>这样的数据。
然后做词性标注,标注词性。
根据标注的词性,转换单词的变形为基本形式。
过滤掉 Stopwords(包括代词),专有名词(NNP),进行拼写检查。
最后建立索引,得到 Map<String,List<String>>这样每个单词到所有包含这个单词的各种形式的句子结构的映射
根据索引就可以排序排版输出了。

如果把中间结果写入硬盘数据库的话,对单个文本大小没有限制,否则取决于内存大小。

细节的话,工具用到了NLTK和Stanford CoreNLP
NLTK转单词变形的时候是用查Wordnet的单词表,不能利用好词性标注上关于单词变形的信息。
Stanford CoreNLP的单词变形不处理形容词比较级,最后又用了其他模块额外处理一下。
各种分句模块必须要求句号后面有一个空格。没有空格会当成和句号前的是一个词,好奇怪。
还有就是NLTK自带的词性标注准确率不高,动词的-ing做名词时候是也都会被标注为名词(这样不好转词形)
Stanford CoreNLP标注的准确率感觉没有问题(据说有97%的准确率,NLTK可能只有94%)。
感觉还可以解析出词的依赖关系来分析出常见搭配,这里还没验证过。
我觉得Stanford CoreNLP最好用命令行管道调用,内部的接口不大好直接用。
絮絮叨叨就是这些。

----

请问前辈您所说的把文章拆分分别程序分析是怎样步骤?很希望能收到指点和启发。

该用户从未签到

258

主题

1651

回帖

1万

积分

状元

Rank: 9Rank: 9Rank: 9

积分
19159

灌水大神章小蜜蜂章笑傲江湖章

2
发表于 2016-7-15 16:46:51 | 只看该作者
啥软件整理出来的?

点评

http://www.pdawiki.com/forum/forum.php?mod=viewthread&tid=17486  发表于 2016-7-15 16:54

该用户从未签到

0

主题

9

回帖

115

积分

童生

Rank: 2

积分
115
3
发表于 2016-7-15 17:05:47 | 只看该作者
不简单。没有3000单词以上的水平,还真看不懂英文小说。

点评

不够的...小说中经常有不少蛮偏的单词...  发表于 2016-7-15 17:21

该用户从未签到

58

主题

933

回帖

3897

积分

被盗用户

积分
3897

灌水大神章小蜜蜂章笑傲江湖章

4
发表于 2016-7-15 17:34:59 | 只看该作者
本帖最后由 lxchen2001 于 2016-7-15 17:36 编辑

谢谢!!!


能否单独提供代码文件?

复制代码加了很多乱码

点评

用论坛自带的“复制代码”链接可以  发表于 2016-7-15 18:15

该用户从未签到

58

主题

933

回帖

3897

积分

被盗用户

积分
3897

灌水大神章小蜜蜂章笑傲江湖章

6
发表于 2016-7-15 19:06:41 | 只看该作者

也是同样的加了乱码进来  手动更改一下也行  代码并不多

学习中 ....   看这样的代码对我提高Python很有帮助  非常感谢   我只是个初学者  没什么编程基础

点评

谢谢你提出的很多想法,很多思路很有用呢!  发表于 2016-7-15 20:42

该用户从未签到

58

主题

933

回帖

3897

积分

被盗用户

积分
3897

灌水大神章小蜜蜂章笑傲江湖章

7
发表于 2016-7-15 21:12:17 | 只看该作者
lxchen2001 发表于 2016-7-15 19:06
也是同样的加了乱码进来  手动更改一下也行  代码并不多

学习中 ....   看这样的代码对我提高Python很 ...

呵呵  我是在辅导小孩英语中发现到的,英语写作好难提高。每次自己去看也很累,效果不佳。

我很想做到的是:导入一篇文章,在语料库中检查,然后把不恰当的句子,不合适的词语搭配找出来。

您看看有这样的可能吗?不过我想词法纠错可能稍微容易点,句法比较难。

点评

我找找有没有相关的papers…有人说搭配问题可以用依存句法来处理,大概只有在句子结构对的情况可以用…  发表于 2016-7-15 22:14
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    9
    发表于 2016-7-15 22:59:17 | 只看该作者
    用的什么软件?
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    10
    发表于 2016-7-15 23:02:21 | 只看该作者
    楼主留个求求号,我想问你一些问题,希望能得到你的帮忙。

    该用户从未签到

    58

    主题

    933

    回帖

    3897

    积分

    被盗用户

    积分
    3897

    灌水大神章小蜜蜂章笑傲江湖章

    11
    发表于 2016-7-15 23:21:12 | 只看该作者
    shakahenryqht 发表于 2016-7-15 23:02
    楼主留个求求号,我想问你一些问题,希望能得到你的帮忙。

    我帮着楼主解答吧:
    - 需要 Python 2 或者3 (Copy代码的话是需要用Python 2)
    - 之后需要安装NLTK
    - 安装nltk后 按步骤安装资料库

    在 Mdict软件及经验交流  还有其他的介绍帖子

    该用户从未签到

    19

    主题

    363

    回帖

    2553

    积分

    解元

    Rank: 5Rank: 5

    积分
    2553

    灌水大神章小蜜蜂章笑傲江湖章

    13
     楼主| 发表于 2016-7-16 08:34:55 | 只看该作者

    稍微等一下,处理词的变形还要改进一下,目前有几个s结尾的复数和can't这样的缩写词处理得还不大好。。。之后如有可能,会包一个API出来,或者GUI出来的。

    有什么需求请赶紧提出来哦,如果有什么供测试的文本的话,也非常欢迎提供的。
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    14
    发表于 2016-7-16 09:05:38 | 只看该作者
    楼主,弄个软件出来吧。谢谢你!我一直在想着找个能摘句的软件。这样可以把字典的文本整合了
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    15
    发表于 2016-7-16 09:08:30 | 只看该作者
    lxchen2001 发表于 2016-7-15 23:21
    我帮着楼主解答吧:
    - 需要 Python 2 或者3 (Copy代码的话是需要用Python 2)
    - 之后需要安装NLTK

    大神,我的求求58225957,我想详细问问你这个代码怎么用

    点评

    进mdict群找我吧。。。现在发觉-ing词形有点难弄,比如looking是名词,interesting是形容词,还有现在进行时和动名词,现在的脚本对-ing的词的处理是乱的。。。怎么修正还没想好。  发表于 2016-7-16 12:05
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    16
    发表于 2016-7-16 21:24:27 | 只看该作者
    shakahenryqht 发表于 2016-7-16 09:08
    大神,我的求求58225957,我想详细问问你这个代码怎么用

    我在群里,请问你在群里的名字是?

    点评

    你群里随便发条消息我加你。  发表于 2016-7-16 21:38
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    17
    发表于 2016-7-16 21:44:49 | 只看该作者
    shakahenryqht 发表于 2016-7-16 21:24
    我在群里,请问你在群里的名字是?

    现在群里全员禁言
  • TA的每日心情
    奋斗
    2019-11-16 20:51
  • 签到天数: 178 天

    [LV.7]常住居民III

    7

    主题

    714

    回帖

    3887

    积分

    禁止发言

    积分
    3887

    灌水大神章笑傲江湖章QQ 章

    18
    发表于 2016-7-16 21:46:54 | 只看该作者

    我的网名是Mr. Qi
  • TA的每日心情
    开心
    昨天 19:36
  • 签到天数: 624 天

    [LV.9]以坛为家II

    539

    主题

    1981

    回帖

    5万

    积分

    超级版主

    Rank: 12Rank: 12Rank: 12

    积分
    53357

    翰林院专用章推广专家灌水大神章笑傲江湖章小蜜蜂章管理组专用章QQ 章

    19
    发表于 2016-7-17 05:54:22 | 只看该作者
    谢谢楼主的无私奉献!!!!!!
  • TA的每日心情
    开心
    2022-8-18 20:20
  • 签到天数: 345 天

    [LV.8]以坛为家I

    0

    主题

    856

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    13315

    灌水大神章

    20
    发表于 2016-7-17 16:32:13 | 只看该作者
    谢谢楼主分享
  • TA的每日心情
    开心
    2022-8-18 20:20
  • 签到天数: 345 天

    [LV.8]以坛为家I

    0

    主题

    856

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    13315

    灌水大神章

    21
    发表于 2016-7-17 16:32:30 | 只看该作者
    谢谢楼主分享

    该用户从未签到

    8

    主题

    104

    回帖

    715

    积分

    举人

    Rank: 4

    积分
    715

    灌水大神章小蜜蜂章笑傲江湖章

    23
    发表于 2016-7-18 19:39:15 | 只看该作者
    好工具,我以前做那个试卷词典时,在github中找了几个代码,分别尝试了,但都只能得到该单词在一个文本中“第一次出现”的位置,然后导出该句子。为了能得到多一些句子,就只能把文章拆分成几个小部分,分别用程序进行分析处理。不知道楼主的工具怎么样?能处理多大的单个文本?

    该用户从未签到

    0

    主题

    11

    回帖

    323

    积分

    秀才

    Rank: 3Rank: 3

    积分
    323
    25
    发表于 2016-7-19 21:46:11 | 只看该作者
    谢谢楼主分享!,不错不错