Madogiwa Blog

主に技術系の学習メモに使っていきます。

MeCabとRubyで形態素解析をやってみる👩‍🔬

今回は、MeCabを使って形態素解析を行ってみたので、やり方とかをメモしておきます✍

MeCabとは?

MeCab京都大学情報学研究科−日本電信電話株式会社コミュニケーション科学基礎研究所 共同研究ユニットプロジェクトを通じて開発されたオープンソース 形態素解析エンジンです。 言語, 辞書,コーパスに依存しない汎用的な設計を 基本方針としています。

MeCab: Yet Another Part-of-Speech and Morphological Analyzer

MeCabのインストール

インストールの方法は、公式サイトをご確認ください。

http://taku910.github.io/mecab/#install

※公式サイトに書いてないですが、apt-gethomebrewを使ってもインストール出来るようです。

私はMeCabrailsをインストールするDockerfileを作って構築しました👀

gist.github.com

MeCabの使い方

mecabコマンドを実行するとMeCabが起動し形態素解析を行うことが出来ます🙌

$ mecab
鳴かぬなら鳴くまで待とうホトトギス
鳴か  動詞,自立,*,*,五段・カ行イ音便,未然形,鳴く,ナカ,ナカ
ぬ 助動詞,*,*,*,特殊・ヌ,基本形,ぬ,ヌ,ヌ
なら  助動詞,*,*,*,特殊・ダ,仮定形,だ,ナラ,ナラ
鳴く  動詞,自立,*,*,五段・カ行イ音便,基本形,鳴く,ナク,ナク
まで  助詞,副助詞,*,*,*,*,まで,マデ,マデ
待と  動詞,自立,*,*,五段・タ行,未然ウ接続,待つ,マト,マト
う 助動詞,*,*,*,不変化型,基本形,う,ウ,ウ
ホトトギス 名詞,一般,*,*,*,*,ホトトギス,ホトトギス,ホトトギス
EOS

RubyMecabを使う

mecabを扱うgemがあるので、Gemfileに追記してbundle installします。

gem 'mecab'

MeCab::Tagger.new.parseに文字列を渡すをmecab実行時と同様に形態素解析を行うことが出来ます。

irb(main):003:0> puts MeCab::Tagger.new.parse "鳴かぬなら鳴かせてみようホトトギス"
鳴か  動詞,自立,*,*,五段・カ行イ音便,未然形,鳴く,ナカ,ナカ
ぬ 助動詞,*,*,*,特殊・ヌ,基本形,ぬ,ヌ,ヌ
なら  助動詞,*,*,*,特殊・ダ,仮定形,だ,ナラ,ナラ
鳴かせ   動詞,自立,*,*,一段,連用形,鳴かせる,ナカセ,ナカセ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
みよ  動詞,非自立,*,*,一段,未然ウ接続,みる,ミヨ,ミヨ
う 助動詞,*,*,*,不変化型,基本形,う,ウ,ウ
ホトトギス 名詞,一般,*,*,*,*,ホトトギス,ホトトギス,ホトトギス
EOS
=> nil

今回は、下記のようなClassを使って扱いやすいような形で取得できるようにしてみました👀

class MecabClient
  attr_reader :text, :parsed_text, :words

  def initialize(text)
    @text = text
    parse
  end

  def parse
    @parsed_text = MeCab::Tagger.new.parse @text
    @words = parsed_text_rows.map { |row| build_word(row) }
    @parsed_text
  end

  private

  def parsed_text_rows
    rows = @parsed_text.split("\n")
    rows[0...(rows.length - 1)]
  end

  def build_word(row)
    text = row.split("\t")[0]
    properties = row.split("\t")[1].split(',')
    Word.new(
      text: text,
      category1: properties[0],
      category2: properties[1],
      category3: properties[2]
    )
  end

  class Word
    attr_reader :text, :category1, :category2, :category3

    def initialize(text: nil, category1: nil, category2: nil, category3: nil)
      @text = text
      @category1 = category1
      @category2 = category2
      @category3 = category3
    end

    def noun?
      @category1 == "名詞"
    end

    def number?
      @category2 == ''
    end
  end
end

こんな感じで使えます🙌

irb(main):010:0> pp keyword = MecabClient.new("鳴かぬなら鳴かせてみようホトトギス")
#<MecabClient:0x00005617509423f8
 @parsed_text=
  "鳴か\t動詞,自立,*,*,五段・カ行イ音便,未然形,鳴く,ナカ,ナカ\n" +
  "\t助動詞,*,*,*,特殊・ヌ,基本形,ぬ,ヌ,ヌ\n" +
  "なら\t助動詞,*,*,*,特殊・ダ,仮定形,だ,ナラ,ナラ\n" +
  "鳴かせ\t動詞,自立,*,*,一段,連用形,鳴かせる,ナカセ,ナカセ\n" +
  "\t助詞,接続助詞,*,*,*,*,て,テ,テ\n" +
  "みよ\t動詞,非自立,*,*,一段,未然ウ接続,みる,ミヨ,ミヨ\n" +
  "\t助動詞,*,*,*,不変化型,基本形,う,ウ,ウ\n" +
  "ホトトギス\t名詞,一般,*,*,*,*,ホトトギス,ホトトギス,ホトトギス\n" +
  "EOS\n",
 @text="鳴かぬなら鳴かせてみようホトトギス",
 @words=
  [#<MecabClient::Word:0x0000561750941db8
    @category1="動詞",
    @category2="自立",
    @category3="*",
    @word="鳴か">,
   #<MecabClient::Word:0x0000561750941a20
    @category1="助動詞",
    @category2="*",
    @category3="*",
    @word="">,
   #<MecabClient::Word:0x0000561750941688
    @category1="助動詞",
    @category2="*",
    @category3="*",
    @word="なら">,
   #<MecabClient::Word:0x00005617509412f0
    @category1="動詞",
    @category2="自立",
    @category3="*",
    @word="鳴かせ">,
   #<MecabClient::Word:0x0000561750940f58
    @category1="助詞",
    @category2="接続助詞",
    @category3="*",
    @word="">,
   #<MecabClient::Word:0x0000561750940bc0
    @category1="動詞",
    @category2="非自立",
    @category3="*",
    @word="みよ">,
   #<MecabClient::Word:0x0000561750940828
    @category1="助動詞",
    @category2="*",
    @category3="*",
    @word="">,
   #<MecabClient::Word:0x0000561750940490
    @category1="名詞",
    @category2="一般",
    @category3="*",
    @word="ホトトギス">]>

おわりに

今回は、MeCabrubyを使って形態素解析を行う方法についてまとめてみました。 形態素解析と聞くと難しい感じがしますが、ツールを使うと意外と簡単に出来ますね🙏