Module: VivlioStarter::CLI::Metrics::ContentWords
- Defined in:
- lib/vivlio_starter/cli/metrics/content_words.rb
Constant Summary collapse
- NOUN_LABELS =
内容語として採用する名詞の細分類 → 表示ラベル。
{ '固有名詞' => '固有名詞', '形容動詞語幹' => '形容動詞', 'ナイ形容詞語幹' => '形容動詞', '一般' => '名詞', 'サ変接続' => '名詞', '副詞可能' => '名詞' }.freeze
- STOPWORDS =
ほぼ機能語として頻出し、内容語の一覧を埋めてしまう一般動詞は除く。
%w[する なる ある いる できる].freeze
- WORD_CHAR =
表の区切り(|)や記号など、単語文字を含まないトークンを内容語から除く。
/[\p{Han}\p{Hiragana}\p{Katakana}A-Za-z0-9]/
Class Method Summary collapse
-
.base_form(surface, features) ⇒ Object
基本形があればそれを、無ければ(固有名詞など)表層形を使う。.
-
.classify(surface, features) ⇒ Object
形態素 1 つを内容語に分類する。内容語でなければ nil。.
-
.label_for(pos, sub) ⇒ Object
--- 内部ヘルパー ---.
-
.rank(words, limit:) ⇒ Object
内容語の配列を頻度順(同数は語の昇順)に上位 limit 件へ集計する。.
Class Method Details
.base_form(surface, features) ⇒ Object
基本形があればそれを、無ければ(固有名詞など)表層形を使う。
83 84 85 86 |
# File 'lib/vivlio_starter/cli/metrics/content_words.rb', line 83 def base_form(surface, features) base = features[6] base && base != '*' ? base : surface end |
.classify(surface, features) ⇒ Object
形態素 1 つを内容語に分類する。内容語でなければ nil。
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/vivlio_starter/cli/metrics/content_words.rb', line 48 def classify(surface, features) pos = features[0] sub = features[1] word = base_form(surface, features) return nil if STOPWORDS.include?(word) return nil unless word.match?(WORD_CHAR) label = label_for(pos, sub) return nil unless label # 単漢字の「固有名詞」は MeCab の誤判定が大半(章・全・行 など)。 # 正当な固有名詞(PDF・Vivliostyle 等)は 2 字以上なので、ここで弾く。 return nil if label == '固有名詞' && word.length == 1 ContentWord.new(word:, pos: label) end |
.label_for(pos, sub) ⇒ Object
--- 内部ヘルパー ---
74 75 76 77 78 79 80 |
# File 'lib/vivlio_starter/cli/metrics/content_words.rb', line 74 def label_for(pos, sub) case pos when '名詞' then NOUN_LABELS[sub] when '動詞' then sub == '自立' ? '動詞' : nil when '形容詞' then sub == '自立' ? '形容詞' : nil end end |
.rank(words, limit:) ⇒ Object
内容語の配列を頻度順(同数は語の昇順)に上位 limit 件へ集計する。
65 66 67 68 69 70 |
# File 'lib/vivlio_starter/cli/metrics/content_words.rb', line 65 def rank(words, limit:) words.each_with_object(Hash.new(0)) { |w, tally| tally[[w.word, w.pos]] += 1 } .sort_by { |(word, _pos), count| [-count, word] } .first(limit) .map { |(word, pos), count| RankedWord.new(word:, pos:, count:) } end |