免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2916 | 回复: 5
打印 上一主题 下一主题

结巴中文分词的Perl扩展 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2017-04-16 22:42 |只看该作者 |倒序浏览
最近抽空写了一个Lingua::ZH::Jieba模块。

https://metacpan.org/pod/Lingua::ZH::Jieba

我是用SWIG去包的CppJieba,那是结巴的一个C++实现。实际上用SWIG做这一类C++的Perl binding还是很方便的,到今天这个程度(0.003版)我断断续续写了几次,包括在github上把Travis和AppVeyor两个CI都设置起来,加起来估计也没到8小时。

欢迎大家试用。

评分

参与人数 1信誉积分 +10 收起 理由
523066680 + 10 感谢分享

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2017-04-17 09:13 |只看该作者
楼主++++++

论坛徽章:
0
3 [报告]
发表于 2017-04-17 17:19 |只看该作者
本帖最后由 L_WC 于 2017-04-19 12:49 编辑

回复 1# zhouzhen1

首先感谢lz, 刚好前段时间有个需求要用分词,我用perl调的python的jieba....如果这个perl的好用了,很有帮助。。。谢谢
刚使用了一下,
1. 有个问题想请教一下,extract的score 是根据什么来的。

2 . 在 $jieba->insert_user_word("中国人");  之后只有 {cut_all => 1} 模式才能输出 中国人 这个分词。

  1. <div>use Lingua::ZH::Jieba;</div><div>binmode STDOUT, ":utf8";</div><div>
  2. </div><div>my $jieba = Lingua::ZH::Jieba->new();</div><div>$jieba->insert_user_word("中国人");</div><div>
  3. </div><div>#my $words_cutall = $jieba->cut("我来到北京清华大学,我是中国人", { cut_all => 1 } );</div><div>#my $words_cutall = $jieba->cut("我来到北京清华大学,我是中国人" );</div><div>my $words_cutall = $jieba->cut("我来到北京清华大学,我是中国人", { no_hmm => 1 } );</div><div>print join('/', @$words_cutall), "\n";</div>
复制代码

。。。。update 一下 2017/4/19  用lz的分词包写了一个文本比对的例子
  1. [root@L121 tmp]# perl jieba.pl
  2. Similar is :0.815374248327211
  3. [root@L121 tmp]# cat  jieba.pl
  4. use Lingua::ZH::Jieba;
  5. use Smart::Comments;
  6. binmode STDOUT, ":utf8";

  7. my ($txt1, $txt2) = ("我来到北京清华大学,我是中国人","我来到北京清华大学,中国人民很友好");

  8. my $jieba = Lingua::ZH::Jieba->new();
  9. my $words_cutall1 = $jieba->cut( $txt1, { cut_all => 1 } );
  10. my $words_cutall2 = $jieba->cut( $txt2, { cut_all => 1 } );
  11. #print join('/', @$words_cutall1), "\n";
  12. #print join('/', @$words_cutall2), "\n";

  13. use v5.10;
  14. my $all_list = get_all_words($words_cutall1, $words_cutall2);
  15. my %h_1 = get_words_count($words_cutall1);
  16. my %h_2 = get_words_count($words_cutall2);

  17. my $sum = 0;
  18. my $sum_1 = 0;
  19. my $sum_2 = 0;
  20. foreach my $k (get_all_words($words_cutall1, $words_cutall2)){
  21. $h_1{$k} = 0 unless exists $h_1{$k};
  22. $h_2{$k} = 0 unless exists $h_2{$k};
  23. $sum_1 += $h_1{$k} * $h_1{$k};
  24. $sum_2 += $h_2{$k} * $h_2{$k};
  25. $sum += $h_1{$k} * $h_2{$k};
  26. }

  27. say "Similar is :", $sum/(sqrt($sum_1) * sqrt($sum_2));

  28. sub get_words_count{
  29. my $words = shift;
  30. my %h;
  31. $h{$_}++ for @$words;
  32. return %h;
  33. }


  34. sub get_all_words{
  35. my ($words1, $words2) = @_;
  36. my @words = (@$words1, @$words2);
  37. my %h;
  38. $h{$_}++ for @words;
  39. return   keys %h;
  40. }
复制代码


论坛徽章:
0
4 [报告]
发表于 2017-04-19 14:28 |只看该作者
感.谢. l.z.

论坛徽章:
0
5 [报告]
发表于 2017-05-05 22:20 |只看该作者
回复 3# L_WC

一段时间没上,忙成狗了。。不好意思你的两个问题我目前还不好回答,因为我只是wrap了CppJieba的项目(https://github.com/yanyiwu/cppjieba,它是Python Jieba用C++的一个实现),但是我并不了解其中的NLP原理。改天我研究一下再回复你吧。

论坛徽章:
0
6 [报告]
发表于 2017-06-04 17:34 |只看该作者
回复 3# L_WC

我今天看了一下,关于你的两个问题大致上是这么回事。

1. extract的score是根据什么来的。

cppjieba的KeywordExtractor用的是称为tf-idf的方法。具体可以看 wikipedia上的说明 。简而言之,这个方法综合了两个数据,一个是tf(term frequency)即词语在目标文章中的出现量,词语出现次数越多该tf值越大,反映了词语在目标文章中的重要程度;另一个idf(inverse document frequency)是对大量文章的统计结果,一个词越是普通在各种文章出现的概率越大(比如英文中的the, a,中文的“你”、“我”这种),其idf值越小,这样可以压低这种泛用的词语,因为这种词语显然没必要做关键词。最后总的权重就是tf与idf的乘积。

我的package里面用的是cppjieba的字典数据,里面有一个文件就是idf数据,它应该是其作者从大量文档中统计出来的。

2. 在 $jieba->insert_user_word("中国人");  之后只有 {cut_all => 1} 模式才能输出 中国人 这个分词。

结巴分词用到了Trie作为运行时内部字典存储的数据结构,分词的过程是在整个Trie字典中找到用户给定句子的所有可能的DAG子图。再从这些子图中找出权重最大的结果。具体可以看网上的一些文章比如http://blog.sina.com.cn/s/blog_8267db980102wq41.html 以及http://blog.csdn.net/rav009/article/details/12196623

具体到“中国人”这个自定义词上,简而言之就是它的DAG可以是“中国/人”,也可以是连起来的“中国人”。而现在insert_user_word()方法在cppjieba的默认实现是以最小权重插入,这导致了“中国/人”这种分法的权重更大。至于文档例子中的“男默女泪”(我直接从cppjieba的例子中拿的)插入后会优先得到连起来的“男默女泪”,估计是因为“男默/女泪”的分法是通过一种算法猜测出来的,其优先级更低。


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP