Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Rustでトライ木による辞書検索のベンチマークをとってみた

こんにちは
アルゴリズム関係の勉強が趣味のmaron8676です。

今回は、Rustでトライ木のベンチマークをとってみた結果を紹介します。

プログラムの速さを考える際に、アルゴリズムやデータ構造は重要な要素となります。
自然言語処理を勉強している中だと、トライ木と呼ばれるデータ構造が辞書検索タスクに有効であると良く言われます。
そこで実際どのくらい速さに違いが出てくるか確かめようと思い、最近勉強しているRustを使って、トライ木のベンチマークをとってみました。

1. プログラミング言語 Rust

簡単にRustについて紹介しておきます。
Rustは、2010年に登場した、比較的新しいプログラミング言語です。
比較的新しいコンパイル言語という点でGo言語と似たような立ち位置ですが、それと比べると

  1. Rustはより低レイヤのチューニングが行えるため、実行速度を上げやすい
  2. パターンマッチングなど、言語機能が充実している

といった良さがあります。

2. トライ木

トライ木は木構造と呼ばれるデータ構造です。
保存されたパターンの中で、先頭からの最長一致を検索する処理に優れています。
辞書検索タスクを行う場合の、データの保存形式を示したのが図1です。

各ノードが1つの文字列を表しており、ルートノードが空文字に相当するノードになります。
ノードの下についている数字は、単語に紐づけられた値で、実際の応用においては品詞情報などになります。
数字がついていないノードは、辞書登録されていない文字列と対応します。

また、各ノードは、より短いプレフィックスを表すノードの子になるよう構成されます。
例えば、teaのノードは、teノードの子になっています

プレフィックスを検索する際には、根のノードから入力と一致するノードをたどっていきます。
たどるノードがなくなった時点で見ているノードが、最も長いプレフィックスを表すノードとなります。

例えば、図1に対してteapotという文字列から最も長いプレフィックスを探す場合は、
「t」「te」「tea」と順にノードをたどります。次のノードがないため、最も長いプレフィックスは「tea」だと分かります。

トライ木の図表現

図の引用元 トライ (データ構造) - Wikipedia

3. ベンチマークの比較対象

トライ木からの検索と実行速度を比較する対象として、以下の2つを準備しました。

  1. 二分探索
  2. ハッシュ探索

4. ベンチマークタスク

トライ木が有効なベンチマークタスクとして、辞書への最長一致を使った分かち書きを採用しました。
行う処理としては、以下になります。

  1. 文字列を入力とし、文字列が空になるまで処理を繰り返す。
  2. 辞書の中で一致する最も長い単語を検索する。見つからない場合は、入力文字列の1文字目が見つかったこととする。
  3. 見つかった単語で入力文字列を分割し、分割結果の後ろの文字列を入力として、1に戻る。
  4. 分割結果を出力する。

辞書の大きさは10万語とし、MeCab辞書から一部の名詞を抽出することで作成しました。
問題を簡潔にするために、単語表記は全てひらがなとしています。

また、実行環境は以下のようにしました。

OS Core i5 10400F
メモリ 16GB
GPU GTX Geforce 1650

トライ木による探索では、探索途中において最長一致する文字数が分かるようになっており、そこで処理を打ち切ることができます。
ハッシュ探索では、「1文字目」、「1~2文字目」、「1~3文字目」といった全てのパターンについて検索を実行しないと、
最長一致する文字列を特定することができません。
※事前情報として辞書登録された語の最大文字数が分かっていない場合を想定しています

5. ベンチマーク結果

結果は図2, 3のようになりました。
トライ木による探索を使った場合のタスク実行時間は、ハッシュ探索の場合の約半分となっています。
理由としては、「ベンチマークタスク」でも書いた、「最も長いプレフィックスを素早く検索できる」ことが主なものだと考えられます。

f:id:acro-engineer:20201023091847j:plain
二分探索を使った場合のタスク実行時間
f:id:acro-engineer:20201007080940j:plain
ハッシュ探索を使った場合のタスク実行時間
f:id:acro-engineer:20201007081020j:plain
トライ木を使った場合のタスク実行時間

6. まとめ

トライ木を用いるのが有効と言われているタスクに対するベンチマークをRustで実行し、
ハッシュ探索を用いた場合より速くなることを実際に確認することができました。
Rustは細かいチューニングまで行えるため、ベンチマーク対象間の検索処理以外の違いを少なくできました。
アルゴリズムの選択ミスはやっかいなバグです。
データが小さい時には問題なく動作してもデータが大量になったときに致命的な問題となります。
そのため、データの特徴に合わせて適切なアルゴリズムを選択することが重要ですね。

7. 使用したライブラリの紹介

radix_trie: トライ木のRust実装
GitHub - michaelsproul/rust_radix_trie: Fast generic radix trie implemented in Rust

Criterion: Rustでベンチマーク計測を行うためのツール
GitHub - bheisler/criterion.rs: Statistics-driven benchmarking library for Rust

8. 今回の検証にあたり作成したプログラム

github.com

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

ElasticON Global 2020 最速レポート!2

こんにちは、ノムラです。

以下の最速レポートの続きになります。
acro-engineer.hatenablog.com

私からは「ElasticON Global 2020」のセッションのうち、Keynote以外の各セッションのうち面白かったものをご紹介します。

セッション内容

Security analytics with Elastic at Square Enix

あのSquare Enixのセッションで、データ分析、SIEM関連の内容でした。

このセッションで印象的だったのは当初はデータ分析のために、導入をしたElastic StackがSIEMにおいても価値を発揮した、ということです。
Elastic Stackが多方面の課題を解決できる機能を備えたツールであり、かつ拡張性が高いからこその話だと思いました。
f:id:acro-engineer:20201015234723p:plainf:id:acro-engineer:20201015233847p:plainf:id:acro-engineer:20201015233854p:plain

1つのツールで検索、データ分析、機械学習、SIEM等様々な要件に対応でき、複数の軸において、利益を得ることができるのはElatic Stackの大きな強みだと思います。

Securing the Elastic Stack for free

昨年ElasticsearchのSecurity機能の一部がBASICライセンスで利用可能となりました。(詳細については以下のブログをご覧ください)
www.elastic.co

本セッションはそのBASICライセンスで利用可能な機能についての解説でした。
個人的にはRBACとSpaceを用いた権限管理についてデモも交えながらの解説で勉強になりました。
f:id:acro-engineer:20201015225008p:plainf:id:acro-engineer:20201015225245p:plain

Advanced tips for visualizing and presenting data in Kibana

本セッションは去年末に登場したKibana Lens、7.8で登場したダッシュボード同士を移動できるドリルダウン機能を用いた可視化についての解説でした。
特に今後利用したいと思ったのは、ダッシュボード同士を移動できるドリルダウン機能です。
f:id:acro-engineer:20201015231813p:plainf:id:acro-engineer:20201015231823p:plain

この機能を利用すると、分析/フィルタ条件を保持しながら移動することができます。
これまでユースケースによっては1つのダッシュボードに大量のビジュアライズを配置した結果分析画面として分かりにくく、かつ画面表示速度が遅くなることがありました。
しかし、複数のダッシュボードに分割してダッシュボード間の移動の仕組みを作ることで、よりシンプルな画面で効率的にかつ高速に分析を実施することができます。

まとめ

以前までは高速さやスケールアウトの容易さを打ち出していましたが、今回はそれは前提として、

 ・データ投入後の柔軟なデータ加工、分析
 ・他機能、サービスとの連携が容易

等の更なる強み、アピールポイントを打ち出していたように感じました。
これからもどんどん便利になるElastic Stackを使いこなしていきたいですね。

それでは。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

ElasticON Global 2020 最速レポート!

こんにちは、@shin0higuchiです😊

Elastic最大のイベントである、「ElasticON Global 2020」が 10/13~10/15で開催されました。
今年はオンラインでの開催となり、専用のウェブサイト上で配信を観たりコミュニケーションを取ったりする形式となっていました。
早速参加レポートをお届けします。

f:id:acro-engineer:20201015015908j:plain:w800
専用ウェブサイト

カンファレンス概要

アジェンダ

全部で、100近いセッションがありました。
今回は3日間の開催でしたが、厳密には2日分のセッションがあり、
後半2日間は、各地域のタイムゾーンに合わせて同一内容を配信する形になっています。

f:id:acro-engineer:20201015022130p:plain:w500

セッションの一覧は下記のURLから確認することができます。
www.elastic.co

ここからは、いくつかのセッションをピックアップして、内容を簡単にまとめます。

セッション内容

Building great search experience

Enterprise Search の検索UIに関する話でした。
簡単にUIを組み立てられる Reference UI と、より細かいカスタマイズをするための Search UI について、デモを交えて紹介されました。
Pagination、Sorting、Facet、AutoCompletion など、検索UIに必要な基本機能は一通り揃っており、非常に短時間で検索UIを構築することが可能です。

f:id:acro-engineer:20201015015222p:plain:w500

www.elastic.co
www.elastic.co

Opening Keynote

例年通り、CEOの Shay Banon 氏によるプレゼンテーションでキーノートが始まりました。

f:id:acro-engineer:20201015155835p:plain:w500


Ingest Managerの話や...
f:id:acro-engineer:20201015024542p:plain:w500

最近のKibana新機能たちの話...
f:id:acro-engineer:20201015024822p:plain:w300f:id:acro-engineer:20201015024828p:plain:w300f:id:acro-engineer:20201015024834p:plain:w300


他にも、Searchable Snapshotや、Schema on Read (runtime fields) の話などがありました。



Elastic Stack Keynote

f:id:acro-engineer:20201015020129p:plain:w500

このセッションでは、Opening Keynoteで紹介されたものを、より詳しく説明するような内容でした。
個人的には、耐障害性を担保してコストを削減できる Searchable Snapshotの話が興味深く、是非活用してみたいと思いました。
Amazon Elasticsearch Serviceの Ultra Warm Nodeに対抗する形になるのでしょうか)

f:id:acro-engineer:20201015025458p:plain:w500



他のセッションについては、別記事で紹介予定です。お楽しみに!

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

Elastic APMを武器にISUCONに参戦してきた話

皆さんこんにちは
@tereka114です。

9/12(土)にISUCON10が開催され、当社から3チーム参加しました。
ISUCONはLINE株式会社さんが主催でお題となるWebサービスをレギュレーションの中で高速化を図るチューニングバトルです。

開催案内 : ISUCON公式Blog

残念ながら全チーム予選落ちでしたが、今年、最も戦果を残せたのではないかと思っています。
その中でチーム「4回目の正直」が終了時点で1801点(全体48位)を獲得し、最も成績が良かったので、その取り組みについて紹介します。

チーム「4回目の正直」構成

名前からお察しですが、実はこれまで3回ISUCONに参加しています。メンバーは次の通りです。

佐々木 峻(Twitter:@Ssk1029Takashi):インフラ担当
野村 勇仁:アプリ、デプロイ担当
山本 大輝(Twitter:@tereka114):アプリ担当

当日はMS Teamsで電話会議をつなぎ、全員リモートで繋ぎながら参加しました。
自分の開発環境がそのまま利用でき、会話もできるので特に問題なかったと思います。
ただ、サーバ構成の検討のときにホワイトボード使えないのは苦労しました。

これまでと異なり、パフォーマンスを計測するのにElastic APMを利用しました。

Elastic APM

当社はElastic Stackのリセラーで、性能解析には積極的に活用しています。
JavaPython、Goなど各種言語にも対応しています。

ISUCONはまずパフォーマンスのボトルネックを素早く把握することが重要です。
そのため、Elastic Stackをベースに簡単にアプリケーションのパフォーマンスやボトルネックを計測できるElastic APMを使いました。

このElastic APMは今回の問題と特に相性がよかったです。Elastic Cloudを使うことで、環境構築も素早く行え、かつ、強力な効果を発揮していました。
Elastic CloudでのAPM構築方法はこちらを参考にしてください。

www.elastic.co

今回高速化するアプリ

今回のアプリはISUUMOと呼ばれるアプリで「イスに似合う不動産を検索できる」総合情報サイトです。
公式によれば、次の要望に基づいて高速化する必要が出てきたようです。

リモートワークの普及によって、自宅のイスが生産性に直結することがわかった。 その調査結果を受けて、よりよい座環境を求め郊外に住むことを考えるユーザーが増加。 また、注目度が増したことで bot からもアクセスが急増し、機会損失が発生している。 結果として ISUUMO にアクセスが集中し、負荷に耐えられないことが目立ってきた。

時系列での取り組み紹介

12:20

README.mdを読む&サーバ接続の設定を行いました。
このあたりでBot対策が将来的に必要そうであること、特定の加点形式を確認しました。
私達が選んだ言語は普段使い慣れているPythonです。

13:30

このあたりでデプロイツール一式、実装の確認、パフォーマンス確認の準備を行いました。
今回は実装を見るだけではボトルネックの部分の判断が難しく、明確にここの精度が低いといったことはわかりませんでした。

適用したElastic APMベンチマークの結果を見ると次のことがわかります。

  • estates/chairsに対する検索が遅い。
  • nazotteのリクエスト頻度は遅いが、回数が少ないので全体のパフォーマンスに影響度はこの時点では低い。
  • low_pricedのリクエストも負荷がかかっている。
f:id:acro-engineer:20200915000614p:plain
Elastic APMリクエスト負荷画面

例えば、/api/estates/searchのリクエスト個別で見てみるとアプリよりもSQLによる負荷が高いことが判断できます。
そのため、このリクエストを改善するためにはSQLの修正が必要です。

f:id:acro-engineer:20200915000631p:plain
/api/estates/searchの詳細画面

14:00

ベンチマークが502例外を吐いているため、復旧を運営が進めていました。
その間Elastic APMを確認しながらの机上での検討やリクエストを投げて、修正の動作確認を行ってました。
このあたりでnginxにBOT対策用の正規表現を入れていました。あまりスコアは変わらなかったので効果のほどは不明です。

15:00

テーブルのINDEXを張りをしていました。
正直あまり効果は少なかったと思っています。
リクエストの平均速度は若干伸びましたがまだまだ不十分です。

16:00

nazotteリクエストを若干高速化しました。
nazotteの取得件数は最大50ですが、点が領域に含まれているかの実行が50件を超えても動いていました。
そのため、プログラムで打ち切ることで若干高速化しました。

16:30

Redisを利用した高速化を進めました。
テーブルへのレコード登録のAPIの発行回数が少なく、テーブルそのものへのレコード更新頻度が少ないことがわかりました。
また、検索は一見、連続値での条件取得に見えますが、よく見ると殆どがただの離散値です。
そのため、限られたパタンになるため、結果のキャッシュを行うのが案外容易であることがわかりました。

更新タイミングで手動ロックを実装し、この方式を実現しました。実装完了した時点でのAPMは次の通りです。
最初と比較するとかなり性能が向上しました。

f:id:acro-engineer:20200913211301p:plain
Elastic APMリクエスト負荷画面(複数台構成前)

18:20

複数台構成を検討し始めました。
複数台を構成するにあたり、DBの負荷が高いことがわかっていました。

また、chair/estatesで干渉する場所はほぼないので、完全に分断する方式を取りました。
最終的には次の構成になりました。

101:Web, Nginx, Redis, DB(chairs)
102:Web
103:DB(estates)

20:00

ここからアプリ改修ではなく、分散処理とベンチマークガチャを進めていました。
最終的にはElastic APM外しを行ってベンチマークガチャを行い1801点まで伸ばしました。

21:00以降

競技終了+参加した3チーム揃っての感想戦です。
生放送の結果報告を楽しみに待ってましたが、本選出場には届きませんでした。

まとめ

Elastic APMを利用してボトルネックは的確に当てることができました。
詳細画面でSQLが問題であり、全体的にMySQLに負荷がかかっていることがすぐに判断できました。
しかし、ボトルネックを当ててもメンバの地力が足りず、修正しきれなかった箇所があったのは反省です。
特にnazotteのN+1外しに失敗するところやMySQL8にはある降順INDEXの利用は勝敗にかなり影響したと思っています。

最後に

運営の皆さん大変な中、ありがとうございました。
今年のISUCON、これまでの参加の中で最もがんばれたと思っています。
惜しいところまで競ったからこそ悔しいと感じていますが、来年も懲りずにリベンジしたいと思います。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWebエンジニアの求人 - Wantedlywww.wantedly.com

小麦物体検出のKaggleコンペティションGlobal Wheat Detectionで6位になりました

皆さんこんにちは
@tereka114です。

先日まで開催された物体検出のコンペティション「Global Wheat Detection」で6位になりました。
これまでチームではGoldを2度獲得したことがありましたが、ソロゴールドを獲得しました。
Kaggleはじめて6年目でようやく獲得できたので感慨深いです。

本記事では簡単にそのコンペの参加状況を記載します。

コンペティションのサイト
www.kaggle.com

コンペティション概要

コンペティションは、世界各地で撮影された多種の小麦の画像から、1つのモデルで小麦の穂の部分を検出する課題です。
小麦の穂の検出精度が向上することにより、農家の収穫の品質が上がったり、研究者が穂の密度やサイズを正確に計算できたりします。
コンペティションの開催期間は3ヶ月ほどで、5月5日開始、8月4日に終了しました。私は開催の初期の頃から参加していました。
そこから、主催者による終了2週間ほどの期間で提出物のチェックがあり、8月20日に確定しました。

結果、Public 1st/Private 6thでした。後述で説明するデータセットの扱いがなかなか難しく、PrivateとPublicの順位が離れる、いわゆる、Shake upの対策に難儀していました。

f:id:acro-engineer:20200831112235p:plain:w640
Private Leaderboard

難しかったところ

今回の難しいは主にデータセットにあります。
世界中の小麦の写真を集めていますが、品種や地域によって育成度合いや形が全く違います。
また、学習データと評価用のデータには共通となる品種、地域はありません。
そのため、新しい環境でも運用できるモデルを構築しなければなりません。

小麦は環境や品種などで、想像以上に見え方に差分があります。公式の小麦画像によればこれぐらい違います。

f:id:acro-engineer:20200821001705p:plain
小麦画像(Kaggle公式より)

解法

日本語で詳細を書く予定ですが、一応、英語でKaggle Discussionに書いています。
www.kaggle.com

そのため、本記述では詳細は省きますが、簡単に紹介します。
モデルはEfficientDetB3,B4,B5を利用しています。
処理は簡単に次の5段階に分かれています。

1. EfficientDetB3を使って学習データのみでモデルを構築し、評価データ(公開の10枚)に対して疑似ラベル(推論の結果)を作る。
2. 評価データと疑似ラベルに加え、学習データを入れて、EfficientDetB4とB5のモデルを作る。
3. Kernel上で予測したEfficientDetB5の結果を用いて、評価データ(全体)に対して疑似ラベル(推論の結果)を作る。
4. 3で利用したEfficientDetB5を学習データと評価データ(全体)でFinetuninigする。
5. EfficientDetB4(2) + EfficientDetB5(3) + EfficientDetB5(4)を組み合わせて最終的な予測をする。

基本的なソリューションコンセプトはいかにドメインが同じである評価データを利用するかです。
この情報をモデルに取り入れられると、ロバストなモデルの構築ができるのではと考えていました。
仕事でも違う場所にモデルを適用することに応用できそうなので、そのあたりのアプローチについて、自分なりに追求していました。

最後に

コンペ中は色々とありましたが、楽しかったです。
物体検出は仕事で使うことが多いので、仕事でも活かせると思ったテクニックは多々ありました。
仕事にも活かして、製品の改善などに貢献していきたいと思います。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

ElasticStack7.9新機能紹介

こんにちはElastic Certified Engineerのノムラです。

昨日、Elastic Stackの7.9がリリースされました。
今回も魅力的な機能が追加されました。

そこで、追加された機能のうち特に面白いと思う機能をご紹介します!

EQL(Event Query Language)

エンタープライズライセンスで利用可能となったSIEM向けの新機能です。
ネットワークログやシステムログのような時系列データに対して、マルウェア等の侵入から感染、不正操作までの一連のイベントを簡単に検索可能とします。
www.elastic.co

検索方法

マルウェアが侵入、インストールされたケースを想定し検索を実行します。
以下のような独自クエリで検索が可能となります。

GET /my-index-000001/_eql/search
{
  "query": """
    sequence
      [ process where process.name == "regsvr32.exe" ]
      [ file where (file.size > 0 and stringContains(file.name, "scrobj.dll")) ]
  """
}

条件として、通常のmatch検索だけでなく、sizeの指定やstringContains等のメソッドが利用可能です。

またsequenceを利用することで、検索時の条件を時系列の順に指定可能です。
上記では、
 1ドキュメント目:process.nameが"regsvr32.exe"であるドキュメントを検索
 2ドキュメント目:fileフィールドのsizeパラメータが0より大きく、かつfile.nameフィールドの値に"scrobj.dll"を含むドキュメントを検索
と各シーケンス毎に条件を指定しています。

検索結果

検索結果は以下です

{
  "is_partial": false,
  "is_running": false,
  "took": 60,
  "timed_out": false,
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "sequences": [
      {
        "events": [
          {
            "_index": "my-index-000001",
            "_id": "OQmfCaduce8zoHT93o4H",
            "_version": 1,
            "_seq_no": 3,
            "_primary_term": 1,
            "_score": null,
            "_source": {
              "@timestamp": "2099-12-07T11:07:09.000Z",
              "event": {
                "category": "process",
                "id": "aR3NWVOs",
                "sequence": 4
              },
              "process": {
                "pid": 2012,
                "name": "regsvr32.exe",
                "command_line": "regsvr32.exe  /s /u /i:https://...RegSvr32.sct scrobj.dll",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              }
            }
          },
          {
            "_index": "my-index-000001",
            "_id": "yDwnGIJouOYGBzP0ZE9n",
            "_version": 1,
            "_seq_no": 4,
            "_primary_term": 1,
            "_score": null,
            "_source": {
              "@timestamp": "2099-12-07T11:07:10.000Z",
              "event": {
                "category": "file",
                "id": "tZ1NWVOs",
                "sequence": 5
              },
              "process": {
                "pid": 2012,
                "name": "regsvr32.exe",
                "executable": "C:\\Windows\\System32\\regsvr32.exe"
              },
              "file": {
                  "path": "C:\\Windows\\System32\\scrobj.dll",
                  "name": "scrobj.dll"
              }
            }
          }
        ]
      }
    ]
  }
}

既存のQuery DSLでは実現できない、時系列の順(マルウェアの侵入から不正操作までの順)で条件を指定して検索できるのはかなり便利な機能だと思います。

Data Streams

BASICライセンスから利用可能な時系列データの読み書きを簡単に管理することができる機能です。
Data Stream機能を利用することで、1インデックスの作成単位の設定(年月日、サイズ)をILM画面から設定可能となります。
www.elastic.co

特徴

通常、時系列ログを扱うときには複数のインデックスを作る必要があり、管理が複雑化していました。
例えば、「index-a-202008」「index-a-202009」「index-a-202010」... と月毎にインデックスを作成していました。

DataStreamを利用すると、単一のインターフェースを提供し、インデックス名を意識せず単一の名前で扱うことができます。
またインデックスの作成単位や、そのローテート期間等の管理をGUIから一括で行うことが可能です。

利用方法

利用方法は以下です

インデックスの作成単位を設定する

下記の設定では、25GB毎に新しいインデックスを作成するように定義しています

PUT /_ilm/policy/my-data-stream-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "25GB"
          }
        }
      }
    }
  }
}
Index Templateを定義する

SettingsにLife Cycle Policyを定義します。

PUT /_index_template/my-data-stream-template
{
  "index_patterns": [ "my-data-stream*" ],
  "data_stream": { },
  "priority": 200,
  "template": {
    "settings": {
      "index.lifecycle.name": "my-data-stream-policy"
    }
  }
}
Data Streamを作成する

「my-data-stream-alt」が読み書きの指定対象となります。

PUT /_data_stream/my-data-stream-alt

運用がかなり楽になりそうな機能だと思っており、是非実際に導入してみたい機能です。

Wildcard Datatypeの追加

最後は、Wildcard Datatypeです。
7.9から追加された新しいデータ型でWildcard検索の高速化に利用可能なデータ型です。

特にカーディナリティが高いフィールドに対して、Wildcard Query、Regexp Queryを利用する際、このWildcard Datatypeを利用することで従来のText、Keyword型よりもかなり高速に検索できるそうです。

利用方法

以下のようにIndex Mappingのデータ型にWildcard Datatypeを指定することで、利用可能です

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_wildcard": {
        "type": "wildcard"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "my_wildcard" : "This string can be quite lengthy"
}

POST my-index-000001/_doc/_search
{
  "query": {
      "wildcard" : {
          "value": "*quite*lengthy"
        }
  }
}

より詳細が知りたい方は、昨日投稿されたElastic社のブログも参考になると思います。
www.elastic.co

最後に

今回も内容が濃いリリースでした。

特に、最近のリリースからは
 ・SIEM
 ・データ加工を簡単にする
という部分に力を注いでいるように感じます。

ますます便利になるElasticStackを引き続き使い倒していきたいです!

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

GiNZAの単語分散表現にchiVeを使って精度向上のお試し

こんにちは。最近シェアハウスのネットワークをIPv6に切り替えたら快適になった@Ssk1029Takashiです。

最近は学習済み単語分散表現が日本語でも充実してきており、語彙の多いもの・ドメインに特化しているものなど選択肢の幅が広がってきています。
日本語処理フレームワークであるGiNZAからもデフォルトで単語分散表現が使用可能です。
今回はワークスアプリケーションさんが作成しているchiVeという学習済み単語分散表現を使って、機械学習の精度を向上できるかを見てみます。

はじめに

単語分散表現とは単語に対して、ベクトルを埋め込む技術で、Word2Vecなどが代表的です。
すでに学習されている分散表現を使用することで、機械学習モデルを作らなくても、近しい単語の検索・文書分類などが可能になります。
例えば、単語分散表現を使用することで「令和」という単語から「平成」という単語が近しい意味であると検索出来たりします。

しかし、単語分散表現を使うときの課題としては、未知語への対応があります。
単語をベクトルに変換するとき、事前学習したモデルが知らない単語はベクトルに変換できないため、精度が落ちてしまうことがあります。
GiNZAにはデフォルトで使用できる単語分散表現モデルがあるのですが、新語への対応に弱い部分があり、例えば「令和」がベクトルに変換できないなどがあります。

しかし、ワークスアプリケーションさんが作成しているchiVeという単語分散表現であれば、新語なども学習されているので、より精度の高い結果が期待できます。
実際に学習している単語の語彙数でも、GiNZAのデフォルトのモデルが、約12万語なのに対して、chiVeは最大360万語となっているので、カバーしている単語の範囲もよりchiVeのほうが広くなっています。

f:id:acro-engineer:20200603075346p:plain

なので、今回はGiNZAの学習済み単語分散表現をchiVeに差し替えて、機械学習の精度が向上するのか試してみます。

GiNZAとは

GiNZAについての詳細な説明は過去の記事に記載しているので、参照してください。
acro-engineer.hatenablog.com

chiVeとは

chiVeとは形態素解析器のSudachiを開発しているワークスアプリケーションさんが作成した、学習済み単語分散表現です。
github.com

以下のような特徴があります。
1. Skip-gramアルゴリズムを元に、word2vec (gensim) を使用して構築した単語分散表現。
2. 約1億のウェブページ文章を含む国立国語研究所の日本語ウェブコーパス(NWJC)から、Sudachiで分かち書きして学習している。
3. Sudachiの短・中・長単位の3つの分割単位の形態素で学習している。

上でも書きましたが、豊富な語彙数が収録されており、最大で約360万語の語彙数を持ったモデルがあります。
GiNZAがデフォルトで使用しているモデルが約12万語のモデルなので、比較すると語彙数の多さがわかりますね。

GiNZAから学習済み単語分散表現を使用する

GiNZAはspacyベースのため、vector属性から学習済み分散表現を参照できます。

import spacy

nlp = spacy.load('ja_ginza')
doc = nlp("平成の次は令和です。")
for sent in doc.sents:
    for token in sent:
        print(token.vector) #単語のベクトルを参照

また、文書や文章単位でもvector属性を参照することが可能で、その場合は、各単語のベクトルを加算平均した値になります。

nlp = spacy.load('ja_ginza')
doc = nlp("平成の次は令和です。")
print(doc.vector) #文書のベクトルを参照

文書のベクトルを簡易的に扱いたいときでも、vector属性から簡単に参照できるので便利ですね。

GiNZAからchiVeの分散表現を使用する

GiNZAからWord2Vecの形式で保存されているchiVeの分散表現モデルを読み込むことで、chiVeを使用できるようにします。
今回は、約310万語収録されている、v1.1 mc5版のモデルを使用しています。

from gensim.models import KeyedVectors

chive_vectors = KeyedVectors.load_word2vec_format('./chive-1.1-mc5-20200318.txt', binary=False) #モデル読み込み
#ベクトル入れ替え
nlp.vocab.reset_vectors(width=chive_vectors.vectors.shape[1])
for word in chive_vectors.vocab.keys():
    nlp.vocab[word]
    nlp.vocab.set_vector(word, chive_vectors[word])

実際に語彙数が増えたのか確認すると、310万x100次元のベクトルが読み込まれています。

nlp.vocab.vectors.shape

(3572384, 300)

クラス分類の精度が向上するか試してみる

単語分散表現の有効性を示すためには、文書分類でどれくらい結果が向上するかがわかりやすいです。
livedoorニュースコーパスというデータセット、ニュース記事とその記事のジャンルがそろっているので、そちらを使って文書分類を学習してみます。

データセット・手法は以下のようになります。

データセット livedoorニュースコーパス
手法 単語ベクトルの加算平均+ランダムフォレスト

まずは学習用にデータを作成します。

import pandas as pd
from sklearn.model_selection import train_test_split
import numpy as np

def parse_doc(sentence):
  sentence = re.sub(r'https?\S+\n', " ", sentence)
  # 解析のノイズになる特殊文字を削除する
  sentence = re.sub(r'[\._-―─!@#$%^&\-‐|\\*\“()_■×+α※÷⇒—●★☆〇◎◆▼◇△□(:〜~+==)/*&^%$#@!~`){}[]…\[\]\"\'\”\’:;<>?<>〔〕〈〉?、。・,\./『』【】「」→←○《》≪≫\n\u3000]+', "", sentence)
  return sentence


df = pd.read_csv("./text/livedoor.tsv", delimiter="\t")
df["article"] = df["article"].apply(parse_doc)

X = []
y = df["category"]

with nlp.disable_pipes(["ner", "parser"]):
  for article in df["article"].tolist():
    doc = nlp(article)
    X.append(doc.vector)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

次に、学習して、精度を確かめてみます。

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.metrics import classification_report

rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
y_pred = rfc.predict(X_test)
print(classification_report(y_test, y_pred))

GiNZAのデフォルトの分散表現で学習した結果は以下になります。

                precision    recall  f1-score   support

dokujo-tsushin       0.83      0.84      0.83       185
  it-life-hack       0.81      0.70      0.75       200
 kaden-channel       0.71      0.73      0.72       177
livedoor-homme       0.77      0.62      0.69        90
   movie-enter       0.81      0.95      0.87       163
        peachy       0.75      0.70      0.72       170
          smax       0.85      0.86      0.86       154
  sports-watch       0.90      0.95      0.92       180
    topic-news       0.75      0.77      0.76       155

      accuracy                           0.80      1474
     macro avg       0.80      0.79      0.79      1474
  weighted avg       0.80      0.80      0.80      1474

これが、chiVeを使用すると、以下の結果になります。

                precision    recall  f1-score   support

dokujo-tsushin       0.77      0.83      0.80       180
  it-life-hack       0.82      0.75      0.78       161
 kaden-channel       0.81      0.79      0.80       187
livedoor-homme       0.87      0.54      0.67        96
   movie-enter       0.81      0.95      0.88       177
        peachy       0.76      0.76      0.76       181
          smax       0.92      0.88      0.90       168
  sports-watch       0.90      0.94      0.92       171
    topic-news       0.78      0.82      0.80       153

      accuracy                           0.82      1474
     macro avg       0.83      0.81      0.81      1474
  weighted avg       0.82      0.82      0.82      1474

結果としてはF1値が0.80から0.82と0.02ポイントの精度向上ができました。
語彙数が増えた分、精度は向上できました。

まとめ

今回は、ワークスアプリケーションさんが公開している学習済み単語分散表現のchiVeを紹介して、GiNZAから使用する方法を紹介しました。
学習済み単語分散表現はクラス分類や検索など、多数の使い道があるだけに、モデル自体の語彙数が重要になってきます。
chiVeは語彙数が豊富で、使いたい場面も多そうです。
それではまた。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com