読者です 読者をやめる 読者になる 読者になる

Lチカ開発ブログ

https://l-chika.com/の開発ブログ

nattoとclassifier-rebornを利用してRubyで文書分類

Pythonの統計・数学ライブラリを利用した文書分類はあるが、Rubyで実現できる方法を模索。

目的

文書(データ) の内容から、いくつかのグループ毎に自動的に分類する

手順

  1. 訓練データを予め作成しておく
  2. 訓練データを形態素解析して、訓練する
  3. 実際のデータを形態素解析して、分類を実行

Gemfile

gem 'natto'
gem 'classifier-reborn'

訓練データ (db/fixtures/train.csv)

内容は、分類, 文章 となる。 - データのバリデーションが多ければ多いほど精度が向上した - 各分類間で訓練データ数に偏りがあるとうまく分類してくれないでの、A,B,C でそれぞれデータ数に偏りがないようにした

"A","ほげほげ..."
"B","ほげほげ..."
"C","ほげほげ..."
"A","ほげほげ..."
"C","ほげほげ..."
...

実装

require 'csv'

namespace :classifier do
  desc 'classify'
  task classify: :environment do

    # 品詞分解して名詞を取得する関数
    mecab = Natto::MeCab.new
    def mecab.filter(text)
      words = []
      parse(text) do |n|
        next unless n.feature.match(/名詞/)
        next if n.feature.match(/(非自立||代名詞)/)
        next if n.surface.match(/\./)
        words << n.surface
      end
      words
    end

    features = ['A', 'B', 'C']
    classifier = ClassifierReborn::Bayes.new(features, auto_categorize: true)

    # 訓練データから学習
    csv = CSV.read('db/fixtures/train.csv')
    csv.each do |data|
      classifier.train(data[0], mecab.filter(data[1]).join(' '))
    end

    # 分類
    result = []
    Product.all.each do |product|
      next if product.description.blank?
      # Product.descriptionカラムの内容から適切なfeatureに分類する
      feature_id = classifier.classify(mecab.filter(product.description).join(' '))
      result << { product_id: product.id, feature_id: feature_id }
    end

    result
  end
end

参考

はじめての自然言語処理

はじめての自然言語処理

実践 機械学習システム

実践 機械学習システム

qiita.com