File Coverage

blib/lib/Lingua/ZH/Summary.pm
Criterion Covered Total %
statement 48 51 94.1
branch 14 20 70.0
condition 5 9 55.5
subroutine 6 6 100.0
pod 2 2 100.0
total 75 88 85.2


line stmt bran cond sub pod time code
1             package Lingua::ZH::Summary;
2              
3 2     2   20833 use warnings;
  2         4  
  2         68  
4 2     2   12 use strict;
  2         3  
  2         59  
5 2     2   901 use utf8;
  2         17  
  2         16  
6              
7 2     2   1710 use Net::YASA;
  2         136475  
  2         1451  
8              
9             =head1 NAME
10              
11             Lingua::ZH::Summary - Extract summary from Chinese text
12              
13             =head1 VERSION
14              
15             Version 0.03
16              
17             =cut
18              
19             our $VERSION = '0.03';
20              
21             =head1 SYNOPSIS
22              
23             Given a Chinese text, it will return the summary. Unlike Lingua-ZH-Summarize,
24             this module depends on term frequency instead of knowledge. If knowledge
25             analysis is required, use L instead.
26              
27             Perhaps a little code snippet.
28              
29             use Lingua::ZH::Summary;
30              
31             my $foo = Lingua::ZH::Summary->new();
32             my $summary = $foo->summary( or $text);
33             ...
34              
35             =cut
36              
37             my %punct = map { $_ => $_ } qw(。 ? ! ; …);
38             $punct{$_} = '。' for qw(, -);
39              
40             my %key = map { $_ => 1 } qw(是 會 曾 將 能 有);
41             my %stop = (
42             %key, map { $_ => 1 } qw(
43             的 裡 和 與 及 年 月 日 時 分 秒 可 對 於 但 也 且 或 中 而 為 叫
44             )
45             );
46              
47             =head1 METHODS
48              
49             =head2 new
50              
51             =cut
52              
53             sub new {
54 1     1 1 806 my $class = shift;
55 1         4 my $self = {
56             yasa => undef
57             };
58 1 50       6 if(@_) {
59 0         0 my %arg = @_;
60              
61 0         0 foreach (keys %arg) {
62 0         0 $self->{lc($_)} = $arg{$_};
63             }
64             }
65 1         8 $self->{yasa} = Net::YASA->new (minlength => 2);
66 1         3757 bless($self, $class);
67 1         5 return($self);
68             }
69              
70             =head1 FUNCTIONS
71              
72             =head2 summary
73              
74             =cut
75              
76             sub summary {
77 1     1 1 40 my $self = shift;
78 1         3 my ($text, %options) = @_;
79              
80 1 50       5 return unless $text;
81              
82             # Strip whitespace and formatting out of the text.
83 1         10 $text =~ s/^\s+//;
84 1         21 $text =~ s/\s+/ /sg;
85 1         12 $text =~ s/\s+$//;
86              
87 1 50 33     9 unless (exists $options{maxlength} and $options{maxlength} > 0) {
88 1         11 $options{maxlength} = log(length($text)) * 15;
89             }
90              
91 1         7 my $re = "(".join ("|",keys %punct).")";
92 1         92 my @textlines = split /$re/,$text;
93              
94             # First we get the meaningful terms with respect to their term frequency
95              
96 1         6 my $summary = '';
97 1         2 my $flag = 1;
98              
99 1         16 my $termset = $self->{yasa}->extract($text);
100              
101             # Get top 5
102 1         2601553 my @terms = map {s/\t.*//; $_;} (@{$termset}[0..4]);
  5         24  
  5         14  
  1         6  
103 1         11 $re = "(?:".join ("|",@terms).")";
104              
105 1         3 my $i=0;
106 1         2 my $chunk;
107 1   66     28 while (($chunk, my $punct) = (shift @textlines, shift @textlines) and defined($chunk)) {
108 25 50       59 ($flag = $punct{$punct}, next) unless $flag;
109 25 50       1653 $flag = $punct{$punct} or next;
110              
111 25 100       78 next unless length($chunk) > 5;
112 23 100       480 next unless $chunk =~ /.+(?:\Q是\E|\Q會\E|\Q曾\E|\Q將\E|\Q能\E|\Q有\E|\Q為\E)/;
113 12 100       709 next unless $chunk =~ /$re/;
114 4 100 66     133 next if $stop{substr($chunk, 0, 1)} or $stop{substr($chunk, -1)};
115              
116 3         13 $summary .= $chunk . $punct{$punct};
117              
118 3 50       42 last if length($summary) >= $options{maxlength};
119             }
120              
121             ### Done! Do any necessary postprocessing before returning.
122              
123 1         21 return $summary;
124             }
125              
126             =head1 SEE ALSO
127              
128             L, L, L
129              
130             =head1 AUTHOR
131              
132             Cheng-Lung Sung, C<< >>
133              
134             =head1 BUGS
135              
136             Please report any bugs or feature requests to
137             C, or through the web interface at
138             L.
139             I will be notified, and then you'll automatically be notified of progress on
140             your bug as I make changes.
141              
142             =head1 SUPPORT
143              
144             You can find documentation for this module with the perldoc command.
145              
146             perldoc Lingua::ZH::Summary
147              
148             You can also look for information at:
149              
150             =over 4
151              
152             =item * AnnoCPAN: Annotated CPAN documentation
153              
154             L
155              
156             =item * CPAN Ratings
157              
158             L
159              
160             =item * RT: CPAN's request tracker
161              
162             L
163              
164             =item * Search CPAN
165              
166             L
167              
168             =back
169              
170             =head1 ACKNOWLEDGEMENTS
171              
172             Reference to the L module from
173             Audrey Tang Ecpan@audreyt.orgE.
174              
175             =head1 COPYRIGHT & LICENSE
176              
177             Copyright 2007-2009 Cheng-Lung Sung, all rights reserved.
178              
179             This program is free software; you can redistribute it and/or modify it
180             under the same terms as Perl itself.
181              
182             =cut
183              
184             1; # End of Lingua::ZH::Summary