Module: VivlioStarter::CLI::Metrics::SentenceEndings
- Defined in:
- lib/vivlio_starter/cli/metrics/sentence_endings.rb
Constant Summary collapse
- MIN_RUN =
連続とみなす最小本数。です・ます中心の和文では 3〜4 連続は普通のため、 「気になるほどの単調さ」の目安として 5 連続以上を拾う。
5- POLITE =
長い順(最長一致)に判定する丁寧体・常体の語尾。
%w[ませんでした でしょう ましょう ですか ますか でした ました ません ます です].freeze
- PLAIN =
%w[であった である だった だ].freeze
- CATEGORIES =
内訳で示す大分類(表示順)。
['です・ます', '体言止め', 'だ・である', 'その他'].freeze
Class Method Summary collapse
- .build_run(first, key, length) ⇒ Object
-
.category(key) ⇒ Object
細かいキーを内訳の大分類へ畳む。.
-
.chapter_runs(sentences, min) ⇒ Object
--- 内部ヘルパー ---.
-
.classify(text) ⇒ Object
文末の細かいキー(連続判定・ラベル用)を返す。.
-
.distribution(sentences) ⇒ Object
大分類ごとの割合(%、四捨五入)を表示順のハッシュで返す。.
-
.monotone_runs(sentences, min: MIN_RUN) ⇒ Object
同一文末が MIN_RUN 以上連続する箇所を、章ごとに検出する。.
-
.run_label(key) ⇒ Object
語尾語は「です。」のように句点付き、体言止めはそのまま。.
-
.taigen?(char) ⇒ Boolean
文末の最後の 1 文字がひらがな以外(漢字・カタカナ・英数)なら名詞止めとみなす。.
Class Method Details
.build_run(first, key, length) ⇒ Object
89 90 91 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 89 def build_run(first, key, length) SentenceRun.new(chapter_num: first.chapter_num, line: first.line, label: run_label(key), count: length) end |
.category(key) ⇒ Object
細かいキーを内訳の大分類へ畳む。
51 52 53 54 55 56 57 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 51 def category(key) return 'です・ます' if POLITE.include?(key) return 'だ・である' if PLAIN.include?(key) return '体言止め' if key == '体言止め' 'その他' end |
.chapter_runs(sentences, min) ⇒ Object
--- 内部ヘルパー ---
75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 75 def chapter_runs(sentences, min) keys = sentences.map { classify(it.text) } runs = [] start = 0 while start < sentences.size stop = start stop += 1 while stop < sentences.size && keys[stop] == keys[start] length = stop - start runs << build_run(sentences[start], keys[start], length) if length >= min && keys[start] != 'その他' start = stop end runs end |
.classify(text) ⇒ Object
文末の細かいキー(連続判定・ラベル用)を返す。
39 40 41 42 43 44 45 46 47 48 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 39 def classify(text) body = text.sub(/[。.!?!?]+\z/, '').rstrip return 'その他' if body.empty? POLITE.each { |suffix| return suffix if body.end_with?(suffix) } PLAIN.each { |suffix| return suffix if body.end_with?(suffix) } return '体言止め' if taigen?(body[-1]) 'その他' end |
.distribution(sentences) ⇒ Object
大分類ごとの割合(%、四捨五入)を表示順のハッシュで返す。
60 61 62 63 64 65 66 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 60 def distribution(sentences) return CATEGORIES.to_h { [it, 0] } if sentences.empty? counts = sentences.each_with_object(Hash.new(0)) { |s, acc| acc[category(classify(s.text))] += 1 } total = sentences.size.to_f CATEGORIES.to_h { [it, (counts[it] / total * 100).round] } end |
.monotone_runs(sentences, min: MIN_RUN) ⇒ Object
同一文末が MIN_RUN 以上連続する箇所を、章ごとに検出する。
69 70 71 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 69 def monotone_runs(sentences, min: MIN_RUN) sentences.group_by(&:chapter_num).flat_map { |_num, group| chapter_runs(group, min) } end |
.run_label(key) ⇒ Object
語尾語は「です。」のように句点付き、体言止めはそのまま。
94 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 94 def run_label(key) = key == '体言止め' ? key : "#{key}。" |
.taigen?(char) ⇒ Boolean
文末の最後の 1 文字がひらがな以外(漢字・カタカナ・英数)なら名詞止めとみなす。
97 |
# File 'lib/vivlio_starter/cli/metrics/sentence_endings.rb', line 97 def taigen?(char) = char&.match?(/[\p{Han}\p{Katakana}A-Za-z0-9ー]/) || false |