Taste of Tech Topics

Taste of Tech Topics

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

Shopee - Price Match Guaranteeでゴールドメダルを獲得しました

皆さんこんにちは。
@tereka114です。
GPU熱により、部屋が熱くなってきており、冷房が欠かせません。

先日、Kaggleで開催された「Shopee - Price Match Guarantee」でゴールドメダル(5位/2426)を獲得しました。

※本件のプレスリリースをこちらで公開しています。
www.acroquest.co.jp

この記事ではコンペの概要と当チームの取り組みを紹介します。

概要

ECサイトを運営するShopee社が主催で開催されたECサイトの商品をグルーピングするコンペティションです。
期間は2021/3/8〜2021/5/10の約2ヶ月間に渡り、開催されました。
商品数34250, 商品種別11014に渡る商品のタイトル(テキスト)と画像が与えられ、同一の商品をまとめます。
これにより、ユーザ体験の向上やスパムの排除を実現できます。

テキストと画像といった複数のドメインを利用するといったマルチモーダルのタスクであること、
また、単純に分類や回帰をする問題でなかったことから非常に様々な検証の可能性が見えるのが面白そうと感じて参加していました。

www.kaggle.com

本コンペの評価指標は商品ごとに同一の商品をリストアップしますが、そのリストのF1 Scoreの平均(分母は商品)を算出します。

チームでの取り組み

終了一ヶ月ほど前、私がゴールドメダル獲得圏内に入ったあたりからチームを組みはじめ、最終的にはAhmet, Alvor、私の3人チームで進めてました。
体制としては、Ahmetと私で2つのベースラインとなる手法を構築し、Alvorが特徴量探索(EDA)やFeature Engineeringを進めてました。
チームメンバがそれぞれ得意なところを進めているような感じになりました。

この2つのベースラインの流れは大きく変わりませんが、細部で利用しているモデルは異なります。
利用しているモデルの統合したソリューションは制限時間の都合でできませんでした。
ただ、あえて、最後のスコアのShake対策も兼ねて、全くモデルの異なる2つのソリューションにすることにしていました。

※チームのソリューションはこちらのスレッドに掲載しています。(英語)
www.kaggle.com

課題やうまくいったことを共有しながら進めていたのもあり、日々議論しながら進められたことは学びが非常に大きかったと感じました。

解法

私達のソリューションの流れは次のとおりです。

1. 商品群の中でペアの候補群を作成する。
2. ペアの候補群から候補を絞り、最終的なペアを作成する。

1. 商品群の中でペアの候補群を作成する。

商品群の中からペアの候補群を作成します。
ここでは、タイトルと商品画像を別々に解析しました。
実を言えば、タイトル、商品画像を同時に学習させることも試みました。
しかし、各々から近しいものを候補としたものを最終的に結合するのが最も精度が高かったです。

1-1. 画像解析

画像の検索で利用されるArcFaceを用いました。
ArcFaceは画像検索で用いられる距離学習の手法です。Backboneとしては、次の種類を試しました。

  • ResNet200D
  • EfficientNetB3/B4/B5
  • Swin Transformer
  • ViT

まだまだ畳み込みを用いたもののほうがImageNetよりもデータの少ない場合には精度が高いと思っていました。
今回、Swin TransformerやViTでチームメンバーが精度改善していたのに驚きました。

※ArcFaceの解説はこちらの記事がわかりやすいです。
qiita.com

1-2. テキスト解析

Distilbert IndonesianとMLP+Character basedのCountVector(ngram=1,3)をベースにArcFaceを用いて特徴量を作成しました。
与えられたタイトルの言語は大きくインドネシア語と英語が占めていました。そのため、インドネシア語を学習させてあるDistilbertは特に効果がありました。

huggingface.co

MLP+CountVectorを用いた理由は、タイトル中の数値の違い(同じ種類の商品でも、1000mg, 100mgは商品として異なる)を捉えることでした。
これにより、当時のPublicは0.742->0.756まで向上しました。

1-3. 候補の検索

ArcFaceから得られた中間の特徴量を用いて、類似度が一定のしきい値以上のものを候補としました。
ここで、画像検索で用いられる近しいデータのベクトルから新しいデータを生成するDatabase Augmentation(=Query Expansionと等価)を利用しました。
ベクトルの生成方法は近傍2件(自分含め)の重み付け平均です。データから最低2件以上の同一商品が存在することが確定していたのでこの設定にしました。

ここまでで、すべて導入するとPublic 0.767には乗ります。

※Database Augmentationについては、次のスライドのP23を見ていただくのが良いと思います。

www.slideshare.net

2. ペアの候補群から候補を絞り、最終的なペアを作成する。

上記のペアを用いていくつか特徴量を作り、ペアらしさを算出しました。
このペアらしさの候補群ですが、テキストは合致しているが、画像が違う、画像は同じだが、テキストが違う候補が含まれています。
このようなものを候補から省くことを目的としています。

2-1. XGBoostを用いて、候補を絞る

ペアの候補群から絞るためにXGBoostを利用しています。
2つのペアを使って、特徴として利用したのは次のとおりです。この特徴を学習し、最終的に一致しているか否かのスコアを算出するモデルを構築しました。

  • 画像特徴量の類似度
  • テキストの類似度
  • 画像類似度 + テキストの類似度(単純な加算)
  • 画像類似度 * テキストの類似度
  • FP類似度(学習データの特徴量との類似度を計算し最も近いものの値)
2-2. 凝集型クラスタリング(Agglomerative Clustering)

最後に凝縮型のクラスタリングを利用して同一商品群を求めます。
導入する前は閾値ベースでペアを作成していましたが、これを導入することにより、スコア自体もPublic 0.774->0.778へ向上しました。
最終的には少し画像のサイズを向上させるなどして精度を上げています。

凝縮型クラスタリングそのものに関しては、次のサイトがわかりやすいと思います。
qiita.com

このコンペで学べたこと

  • Transformerベースの画像認識モデル(ViT/Swin Transformer)は各コンペで今後、試す価値があり。
  • BERT+画像モデルは他のソリューションでは成功しているものがあったため、チューニング次第では十分コンペ用途には足りた。
  • 検索で利用されるDatabase AugmentationはECサイトの検索でも効果を示せた。検索タスクだと非常に有効そうに見える。

最後に

ECサイトの商品検索といった非常に面白く、実践的なコンペティションで刺激的な日々を過ごしていました。
非常に勉強になったのでまた面白いコンペに参加しようと思います。

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

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

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

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

cuGraph でページランクを計算したら爆速だった

概要

こんにちは、機械学習エンジニアの古賀です。
最近、人の動きを時系列で解析するためにグラフデータを扱ったのですが、データ量が大きくなると解析に時間がかかってしまい、効率が悪いと感じることがありました。
そんな中、cuGraph という高速にグラフ分析ができるライブラリが あることを知ったので、どれくらい高速なのか、有名なページランクの計算を題材に他のライブラリと速度を比較してみました。

目次は以下です。

グラフとは

グラフ(Graph)とは、頂点(node)と(edge)により構成された図形のことです。
グラフによって、路線図、ソーシャルネットワーク、分子構造など、ものとものとの繋がりを抽象的に表現することができます。
これにより様々なデータを分析することができますが、特にソーシャルネットワークのデータなどはデータ数が大きくなりがちななため、分析の際の計算に時間がかかってしまうのが課題の一つです。

グラフは主に、

  • 有向グラフ (directed graph)
    • 頂点と向きを持つ辺により構成されたグラフ
  • 無向グラフ (undirected graph)
    • 頂点と辺のみにより構成されたグラフ

の2つに分類されます(以下の図)。
またさらにその中にも、各辺に重みがあるもの(重み付きグラフ)、2頂点間に複数の辺があるもの(多重グラフ)などのグラフが存在します。

f:id:acro-engineer:20210430025659p:plain:w600
グラフの種類

グラフを表現するデータ構造には、

  • 隣接行列
    • 各要素が、頂点の対がグラフ中で隣接しているか否かを示す行列
  • 隣接リスト
    • グラフにある頂点または辺を全てリストで表現したもの

などがあり(以下の図)、利用用途によって使い分けられます。

f:id:acro-engineer:20210430030454p:plain:w600
隣接行列_隣接リスト

Python によるグラフデータの分析

上で書いたようにグラフには様々な種類があり、その分析のためのアルゴリズムも多種多様です。そのため、グラフの構築、グラフアルゴリズムの計算、グラフの可視化などを一から実装するのはとても大変です。
Python にはこれらを簡単に行うことができるライブラリがいくつかあり、代表的なライブラリに NetworkX があります。
NetworkX は機能が豊富で非常に便利なのですが、GPU に対応していないため、データ量が大きくなると計算速度が遅くなってしまうのが課題となっています。

networkx.org

cuGraphとは

cuGraph はNVIDIAさんが開発している、GPU でのグラフデータ分析のアルゴリズムを集めたライブラリです。
NetworkX など他の Python のグラフライブラリと違い GPU に対応しており、 GPU 上で高速に処理することができます。

github.com

ページランクとは

グラフデータで利用される有名なアルゴリズムとして、ページランク (PageRank) があります。
ページランクは、Web ページの相対的な重要度を決定し、順位付けするためのアルゴリズムです。 検索エンジンGoogle において、検索語に対する適切な結果を得るために用いられています。
この時、各 Web ページに固有の重要度を表す数値をページランク値と呼び、ページランクアルゴリズムで算出されます。

各 Web ページのページランク値は「重要なページからのリンクが多いページは価値が高い」となるよう、リンク元の Web ページのページランク値を元に算出されます(詳細は以下)。

ページランク値の定義

Web ページ  u ページランク r_{u}^{'} は、

 \displaystyle
r_{u}^{'} = d \sum_{v \in B_u} \frac{r_{v}^{'}}{n_v} + \frac{1-d}{N}

で定義されます。

ここで、 B_u は Web ページ  u リンク元のWeb ページの集合を、  n_v はWebページ  v から出ているリンクの総数を、 N はWeb ページの総数を表します。また、 d は damping factor とよばれ、リンク元の Web ページのページランクによる影響度を調整するパラメータです。0 ≦ d < 1 の間の数で、通常  0.85 に設定されます。

ページランクとグラフ

Web ページのリンク関係は、各 Web ページを頂点、Web ページへのリンクを辺とする有向グラフと考え、隣接行列で表現することができます。
したがって、上で定義したページランク値の式も行列で表現することができ、ページランクは「グラフの各ノードの重要度を算出するアルゴリズム」と考えることができます。

詳細については以下の文献を参考にしてください。
PageRank アルゴリズム およびそれに関連する研究について

検証

cuGraph がどの程度高速に処理できるのか、GPUを使わないグラフ計算のライブラリ NetworkX と比較します。

実行環境

手元にGPUがなくても簡単に試すことができるよう、Google Colaboratory を使用しました。
ランタイムは、ハードウェアアクセラレータをGPU、ランタイムの仕様をハイメモリに設定しました。

cuGraph ライブラリのインストール

Google Colaboratory 上で cuGraph を動かすため、以下のコマンドを実行してください。

!git clone https://github.com/rapidsai/rapidsai-csp-utils.git
!bash rapidsai-csp-utils/colab/rapids-colab.sh stable

import sys, os

dist_package_index = sys.path.index('/usr/local/lib/python3.7/dist-packages')
sys.path = sys.path[:dist_package_index] + ['/usr/local/lib/python3.7/site-packages'] + sys.path[dist_package_index:]
sys.path
exec(open('rapidsai-csp-utils/colab/update_modules.py').read(), globals())

ライブラリのインポート

以下のコマンドで cugraph ライブラリと、検証に必要なライブラリをインポートします。

import time
import cudf
import cugraph
import networkx as nx
import numpy as np
import pandas as pd

データセット

本検証では疑似データとして、ノード10万個、エッジ約2,000万個のグラフデータを作成します。

N = 20000000

df = pd.DataFrame([{'src': np.random.randint(0,100000), 'dst': np.random.randint(0, 100000)} for _ in range(N)]
df = df.astype(np.int32)
df = df.drop_duplicates()
print(f'nodes: {len(df["src"].unique())}')
print(f'edges: {df.shape[0]}'

上記を実行した結果は

nodes: 100000  
edges: 19980133  

でした。

検証内容・結果

公式の README.md によると、cuGraph は cuGraph Graph classes だけでなく、NetworkX graph classes にも対応しているようなので、
今回は、ページランクアルゴリズムだけでなくグラフオブジェクトも cuGraph, NetworkX の両方を使い、計算速度を比較してみました。

1. NetworkX のグラフ、NetworkX のアルゴリズムを用いてページランクを計算

# source (src), destination (dst) ベクトルのペアからグラフを生成する
G = nx.from_pandas_edgelist(df, source='src', target='dst', create_using=nx.DiGraph())

# ページランクの計算時間を計測する
start_time = time.time()
pr = nx.pagerank(G)
print(f'{time.time() - start_time:.3f}秒')

上記を5回実行した平均は、19.158秒 でした。

2. NetworkX のグラフ、cuGraph のアルゴリズムを用いてページランクを計算

# source (src), destination (dst) ベクトルのペアからグラフを生成する
G = nx.from_pandas_edgelist(df, source='src', target='dst', create_using=nx.DiGraph())

# ページランクの計算時間を計測する
start_time = time.time()
df_page = cugraph.pagerank(G)
print(f'{time.time() - start_time:.3f}秒')

上記を5回実行した平均は、11.720秒 でした。

3. cuGraph のグラフ、cuGraph のアルゴリズムを用いてページランクを計算

cuGraph のグラフ(cuGraph Graph classes)作成時の入力には、Pandas の DataFrame ではなく、cuDF という GPU 上で高速に計算できるライブラリの DataFrame を使用します。
cuDF の詳細は以下の記事を参考にしてください。

acro-engineer.hatenablog.com

# Pandas.DataFrame を cudf に変換する
gdf = cudf.from_pandas(df)

# source (src), destination (dst) ベクトルのペアからグラフを生成する
cuG = cugraph.DiGraph()
cuG.from_cudf_edgelist(gdf, source='src', destination='dst')

# ページランクの計算時間を計測する
start_time = time.time()
df_page = cugraph.pagerank(cuG)
print(f'{time.time() - start_time:.3f}秒')

上記を5回実行した平均は、0.009秒 でした。

まとめると以下の結果になりました。

グラフのライブラリ ページランクアルゴリズムのライブラリ 計算時間(5回の平均)[秒]
NetworkX NetworkX 19.158
NetworkX cuGraph 11.720
cuGraph cuGraph 0.009

cuGraph のグラフ、cuGraph のアルゴリズムを用いたときの計算時間は、驚きの速さになりました!これだけ速いと実験もはかどりますね。

計算時間の順番も、
cuGraph のグラフ, cuGraph のアルゴリズム > NetworkX のグラフ, cuGraph のアルゴリズム > NetworkX のグラフ, NetworkX のアルゴリズム
という、予想と一致する内容となりました。

大規模なグラフデータを扱う際に GPU 環境が用意できるならば、cuDF + cuGraph の組み合わせが有力な候補になりそうです。

最後に

今回初めて cuGraph を使ってみましたが、とくに癖もなく使いやすく、かなり高速で驚きました。
ページランク以外にも便利なアルゴリズムがいくつも実装されているので、今後もグラフデータを扱う際には重宝しそうです。

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

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

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

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

Elastic Community Conference 2021に参加してきました!

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

Elastic社のイベントである、「Community Conference 2021」が02/27に開催されました。
その速報レポートをお届けしたいと思います。

目次は以下です。

カンファレンス概要

日本時間で27日 0時から始まり、なんと24時間セッションが開催されるカンファレンスです。
今回は事前にCFPの応募があり、その中から選ばれたスピーカーによる発表でした。

内容としては検索、データ分析、クラウド上での活用方法など幅広いジャンルのセッションがあり、レベル感も基本的なものから応用的なものまで多岐に渡ります。

また普段のカンファレンスは英語のセッションが多いのですが、今回は時間帯によってフランス語だったり、韓国語のセッションもあり普段のカンファレンスとはまた違う雰囲気で面白かったです。
今回はそのセッションの中からキーノートと、個人的に面白かったセッションをご紹介したいと思います。

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

キーノート

CEOの Shay Banon 氏によるプレゼンテーションからキーノートが始まりました。
f:id:acro_nomura:20210227161819p:plain:w500

先日発表されたライセンス変更の話や、最近力を入れているクラウドの話が主な内容でした。
ライセンス変更についての詳細は以下のブログを参照ください。
www.elastic.co

また上記の内容以外にも、App Search、ObservabilityそしてSecurityについて7.11で追加された最新機能の紹介も交えたデモが行われました。
特にApp SearchのWebクロール機能はGUI上で簡易に取り込み対象ドキュメントのルール設定や、実際のクローリングを実行することができ便利そうだと思いました。
f:id:acro_nomura:20210227162802p:plain:w500

面白かったセッション

ここからは2つほど面白かったセッションをご紹介します。

Boosting music search results based on popularity and user behavior in Elasticsearch

検索順位を決定するためのスコアリングに関するセッションでした。
f:id:acro_nomura:20210227165234p:plain:w500

Function Score Queryを利用したスコアリングや、編集距離(検索時の表記ゆれ、誤字の是正に利用する考え方)をどう扱うかについて話がありました。
また実際のAPIに落とし込んだ際のデモも実演されました。
f:id:acro_nomura:20210227170853p:plain:w500

スコアリングは検索を扱っていると避けて通れない道です。
そのスコアリングをデモも含めて発表されているので初学者の方におすすめです。

Replacing Google search with Elasticsearch

なぜGoogle Search ApplianceからElasticsearchへ乗り換えたのか、というセッションでした。
下のスライドの通り、ElasticStackは様々な要件を満たしていることが分かります。
f:id:acro_nomura:20210227182444p:plain:w500

以下はそのセッションのまとめスライドです。かっこいいですね。
f:id:acro_nomura:20210227183024p:plain:w500

まとめ

非常に多くの国/ユーザにElaticStackが利用されていることが実感できたイベントだったと思います。
またセッションも多岐にわたっておりElasticStackのユースケースの広さを改めて実感できました。

そして、今回のカンファレンスではElastic社だけではなく、実際のユーザ(エンジニア)の発表も多くありエンジニアとしての刺激を受けられたのも良かったです。

おまけ

今回のカンファレンスのお楽しみ企画としてElasticStack関連のクイズゲームがあったので参加しました。
こういう企画もカンファレンスの1つの楽しみですよね!

ルールとしては10題クイズが出題され、回答の正確さと回答までの速さでポイントが加算される仕組みのようです。
ということで参加してみました。

結果は、、、
f:id:acro_nomura:20210227163145p:plain:w500

9位でした。。。もうちょっと頑張りたかったですね。(問題文が英語だったせい、ということにさせてください)
それでは。

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

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

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

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

第40回 Elasticsearch勉強会で「Searchable Snapshot」について発表しました

こんにちは、@shin0higuchiです😊

昨日は 第40回となる、Elasticsearch勉強会がオンライン開催されました。
www.meetup.com

開催概要(Meetupイベントページより抜粋)

===============================================
■開催日時
2/25(木)19:30~21:00
■内容
登壇
1.株式会社ZOZOテクノロジーズ 有村和真さん
ZOZOTOWNとElasticsearch(ElasticCloud)のこれまで/これから」

2.Acroquest 樋口慎さん
「Searchable Snapshotでコスト削減」

3.Elastic社 鈴木章太郎さん
「Elastic Stack & Cloud 7.11 Technical Enablement ダイジェスト版」

===============================================

「Searchable Snapshotでコスト削減」の内容

今回私が発表した内容を簡単に紹介します。
詳細はこちらの発表資料をご覧ください。

www2.slideshare.net

今回のバージョンでGAとなった「Searchable Snapshot」に関する発表でした。
Searchable Snapshotとは、クラウドストレージなどに置いたSnapshotを、Elasticsearchにマウントして検索できるようにする機能です。
従来であればノード障害に備えてレプリカシャードを保持する必要があったケースでも、
Searchable Snapshotを利用すればプライマリシャードのみ持てば良いので、最大50%のストレージ削減が可能です。
結果としてコストの削減や、シャード数が減ることによるヒープ使用低減が期待できます。
f:id:shin0higuchi:20210225220209p:plain:w400
f:id:shin0higuchi:20210225215933p:plain:w400


使い方としては、Snapshotを従来通り取得し、Mount Snapshot API を利用して検索可能状態にします。
マウントする際に、SnapshotのファイルがElasticsearchのローカルにコピーされるため、検索のたびにSnapshotにアクセスすることはありません。
(つまりパフォーマンスの大きな劣化がない、クラウドストレージからの読み出しコストが抑えられる)

POST _snapshot/fs_backup/my_snapshot/_mount
{
  "index": "kibana_sample_data_logs",
  "renamed_index": "kibana_sample_data_logs_snapshot",
  "index_settings":{
    "index.number_of_replicas":0
  },
  "ignored_index_settings": ["index.refresh_interval"]
}

www.elastic.co

また、Index Lifecycle Management からも制御ができるので、
時系列データのライフサイクルに組み込むのは定石になりそうな予感です。
f:id:shin0higuchi:20210225220654p:plain:w600

次のマイナーバージョンである 7.12 では、
Snapshotのうち、検索に必要なメタデータのみをローカルにコピーするオプションも利用可能になる予定で、
ますますストレージを効率的に使うことができるようになりそうです。
リリースが今から楽しみですね。

さいごに

勉強会全体の動画アーカイブYoutubeにて公開される予定ですので、
興味があれば是非ご覧ください。

お読みいただきありがとうございました。
それでは。

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

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

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

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

Azure Cosmos DBを使って日本語をグラフで表現してみる

皆さんこんにちは。最近ちょっとずつ体重が増えて、若干年齢を感じている@Ssk1029Takashiです。

日常生活の中で、文章を読む機会というのは数多くありますが、もう少し簡単に要点を押さえたいということが多いかと思います。
読むというよりは、図に表示されて理解できると、直感的に理解できてわかりやすいです。

ということで、今回は日本語のSVOに注目してみます。
SVOだけを残すことで余分な単語がなく、ぱっと見の理解が早くなります。
また、これをグラフ表現に起こすことで、見やすくならないか試してみます。

やりたいこと

今回やりたいことは、文章からSVO(主語・述語・目的語)を抽出して、グラフ表現に落とし込んでみます。
例えば、「AcroquestはGPTWを受賞した。」という文章からは以下のような図を作っていきます。
f:id:acro-engineer:20210126075023p:plain

これらを複数の文章から作成することで、名詞と名詞の相関図を作ってみたら見やすくならないか試してみます。

グラフ表現には、Azureが提供しているNoSQLデータベースサービスであるAzure Cosmos DBを活用します。
Cosmos DBはグラフでのデータ構造を格納することができ、なおかつセットアップが簡単なので、選びました。

Azure Cosmos DBとは

Azure Cosmos DBはフルマネージドのNoSQLデータベースです。
高い可用性と応答時間の早さが特徴です。
詳細は以下のページを参照してください。
docs.microsoft.com

また、Azure Cosmos DBはグラフDBとしての機能も備えておりGremlinというAPIを使うことで、グラフデータを扱うことができます。
docs.microsoft.com

SVOを文章から抜き出す

今回はGiNZAの係り受け解析を使って、文章から主語・述語・目的語を抜き出します。
GiNZAの係り受け解析では、以下のように、述語を中心に、係り方の種類で判別できます。
f:id:acro-engineer:20210126080554p:plain
例えば、nsubjは主語・述語関係を表すので、上の図では、述語「受賞」に対する主語は「Acroquest」だとわかります。
また、「obj」は述語に対する目的語を表すので、「受賞」の目的語は「GPTW」であることもここからわかります。

このように、係り受け解析結果から、nsubjやobjなどの関係を抽出することで、文章のSVOを抽出することが可能です。

コードにすると以下のようになります。

def get_svo(token):
    """
    SVOを出力
    :param token:
    :return:
    """
    if token.dep_ == 'nsubj' or token.dep_ == 'iobj': # iobjがあるのはGiNZAが主格関係をiobjと誤認識する不具合があるため
        # 主語の場合、依存関係で動詞をたどる
        verb_token = token.head
        if verb_token.dep_ == 'verb' or verb_token.dep_ == 'ROOT':
            # 動詞から依存関係をたどる
            for object_token in verb_token.children:
                # 目的語があったら、SVOがそろう
                if object_token.dep_ == 'obj':
                    return {"verb": verb_token.orth_, "sub": token.orth_, "obj": object_token.orth_}

これによって、SVOの組み合わせを抽出できます。

Azure Cosmos DBにグラフ情報を格納する

主語述語関係を抽出したら、その情報をグラフDBに格納していきましょう。

Azure Cosmos DBにグラフ情報を格納するためには、Gremlinという言語を使ってグラフを記述します。

グラフを構成する要素としては、以下の2点になります。
1. ノード(頂点)
2. エッジ(辺)

Gremlinを使ってノード・エッジを追加するには以下のようなコードが必要になります。
ノード

g.addV('<グラフ名>').property('id', '<頂点名>').property('pk', '<プライマリキー>')

エッジ

g.V('<辺の元の頂点>').addE('<辺のラベル>').to(g.V('辺の先の頂点'))||<

例として、はじめに例文とした「AcroquestはGPTWを受賞した」という文章を例に考えてみましょう。
図に書いた通り、ここでのノードは「Acroquest」と「GPTW」になり、エッジは「受賞」になります。
それぞれDBに追加するには以下のようなコードになります。

# ノード
g.addV('sentence').property('id', 'Acroquest').property('pk', 'pk')
g.addV('sentence').property('id', 'GPTW').property('pk', 'pk')
# エッジ
g.V('Acroquest').addE('受賞').to(g.V('GPTW'))

実際の文章で試してみる

今回試すうえで、一つの文章の中に、主語・述語・目的語が現れるのが望ましいので、物語を対象にしてみます。
なので、例題として、以下で公開している「走れメロス」を題材にしてみます。
www.aozora.gr.jp

入れてみた結果は、Azure PortalのCosmos DBの画面にある、データエクスプローラーから確認できます。
f:id:acro-engineer:20210127013413p:plain

対象のグラフを選ぶグラフが出てきます。
f:id:acro-engineer:20210127013533p:plain
このように、頂点からどのような辺がどの頂点に伸びているかということが確認できます。

例えば、「メロス」に着目してみると、比較的多くの辺が伸びていることがわかります。
f:id:acro-engineer:20210127013655p:plain

とりあえず「セリヌンティウス」が「メロス」を抱きしめたことは解りましたね。
このように、ざっくりとした相関図がグラフDBで表現できました。

まとめ

今回はGiNZAとAzure Cosmos DBのグラフDBを使って、文章のSVOを可視化してみました。
グラフDBにすることで、「メロス」が「見つめる」のは何?というような検索も可能になります。
ただし、日本語というのは主語を省くことが多い言語なので、真面目にやろうと思うと照応解析や文脈解析などが平行して必要になってきます。
また、SVO以外の5W1Hのような関係も抽出してみると面白いかもしれません。
それではまだ。

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

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

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

外観検査がこんなに簡単に!?Amazon Lookout for Visionで欠陥検出をやってみた

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

さて、今回は2020年の「AWS re:Invent」で紹介された「Amazon Lookout for Vision」を評価していきます。
※記事公開の2021年1月25日時点ではプレビューサービスであるため、GAとなった時には結果が変わる、適用できないTipsもありますが、ぜひお試しください。

Amazon Lookout for Vision

Amazon Lookout for Visionは画像が正常か異常を判定する、異常検知のサービスです。
2020年の「AWS re:Invent」で発表されており、注目されています。

aws.amazon.com

このサービスは最低30枚の画像を準備すれば良く、簡単に試行できることが最大のメリットです。
実際に試した際にもサービスの操作も簡単で非常に扱いやすいと感じました。

Amazon Lookout for Visionの検証方法

先程簡単に説明しましたが、Amazon Lookout for Visionは使いやすく、便利です。
ただ、精度がどの程度実用的なのか、利用する上で非常に重要です。
そこで、本記事ではその「Amazon Lookout for Vision」の精度や性能を評価します。

検証データセット

産業検査の異常検知の画像データセット「MVTec AD」を利用します。
特徴として15種類の製品と複数の異なる異常となるパタンが含まれています。

データセットは以下のサイトからダウンロードできます。
www.mvtec.com

本検証では、次の製品を利用します。

  • Pill
  • Metal Nut

それぞれのサンプル画像は次の通りです。各製品ごとに様々な異常な画像が含まれていることがわかります。

f:id:tereka:20210111205833p:plain

検証内容

MVTecADから特定の物品をサンプリングし、データを評価します。
以下の軸で検証します。評価指標は異常検知でよく用いられるPrecison/Recall/F1 Scoreを用います。
本記事では、細かい評価の式の説明はしませんが各評価指標の意味は次の通りです。

  • Precision・・・異常と予測したデータのうち、異常と判断したデータの割合、異常と予測したデータの中が実際に異常であれば、高くなります。
  • Recall・・・異常のデータから異常と判断したデータの割合、異常データを見逃していなければ、高くなります。
  • F1 Score・・・Precision/Recallの調和平均、どちらの指標も高くなければ、F1Scoreの値は高くなりません。

1. 学習データセットの数量の追加
推奨されている「1つのデータセットを作成する」方式では学習データを最低30枚(正常データ20枚、異常データ10枚)から指定できます。
その方式に追加で正常なデータを増加させた場合の精度の傾向を確認します。

f:id:acro-engineer:20210120003234p:plain:h360
一つのデータセットを作成する

2. 学習データセットに異常データを追加する。
「1つのデータセットを作成する」といった標準の設定では異常データは評価のみ使われます。
「トレーニングデータセットとテストデータセットを作成する」方式ではユーザが指定をすれば異常データを学習に取り込むことができます。
これによる精度への影響を検証します。

f:id:acro-engineer:20210120003310p:plain:h360
レーニングデータセットとテストデータセットを作成する

検証

学習データセットの数量の追加

まずは、学習データセットの正常データの数量の増加を行います。
条件は20枚、50枚、100枚とデータセットを変更します。
データセットで得られた結果は次のとおりです。

  • 正常な学習データをただ増加させても、F1 Scoreの増加が安定していません。正常データを追加するだけでは、単純には精度に貢献しなさそうです。
  • 学習データの数量を増加しても学習時間が線形に伸びていかず、ほぼ一定になっています。数量を増やす場合にも単純に学習時間が2倍、3倍とならないのが学習データを追加しやすい良い点の一つです。

・Pill

枚数 学習時間 Precision Recall F1 Score
20 37分44秒 67% 100% 80%
50 39分41秒 86% 60% 71%
100 42分08秒 89% 80% 84%

次の結果はPill(20)の予測結果です。
確信度が高いものについては、きちんと異常と正常の判定ができています。番号+拡張子が正常(007.png)、単語+番号+拡張子(例:faulty_imprint_017.png)が異常を示しています。

f:id:acro-engineer:20210120002955p:plain:h480
Pillの予測結果

・Metal Nut

枚数 学習時間 Precision Recall F1Score
20 38分30秒 81% 40% 50%
50 40分35秒 100% 80% 88%
100 36分31秒 75% 90% 81%

次の結果はMetal Nut(50)の予測結果です。
先程のPillと同様、確信度が高いものはきちんと判定できています。

f:id:acro-engineer:20210120003933p:plain:h480
Metal Nutの予測結果

学習データセットの異常データ追加

先程の検証では、学習データの中に異常データが含まれていないものでした。
しかし、学習データに異常データを含めると異常の判定精度がよくなり、結果、精度が向上することを期待しています。
ここでは、学習データの正常データ数を10枚に固定します。その上で異常データを10, 20, 30枚と変化させました。

結果は次の通りです。データを増やせば、F1 Scoreが増加します。
特にRecallが増加しており、異常なものを見逃したくない場合には積極的に追加するのが良さそうです。

・Pill

枚数 学習時間 Precision Recall F1Score
10 50分37秒 67% 40% 50%
20 47分21秒 78% 70% 74%
30 51分58秒 69% 90% 78%

・Metal Nut

枚数 学習時間 Precision Recall F1Score
10 47分05秒 100% 60% 75%
20 49分08秒 100% 80% 89%
30 48分55秒 100% 90% 96%

その他便利な機能

トライアル検出を用いた再学習機能

トライアル検出と呼ばれる機能により、お試しで画像の判定が可能です。
このトライアル検出の機能を用いて判定した画像に対するラベリングとデータセットへの追加を行えます。

この処理の後でモデルを再学習することで精度改善に役立てます。
特にトライアル検出で判定が誤った画像は今までで学習されていない画像のパタンである可能性が高いので、精度が向上しそうです。

この機能によりモデル運用時に判定に失敗したデータをいち早く取り込めるので、非常に便利そうだと感じています。

f:id:acro-engineer:20210124234729p:plain:h480
トライアル検出を使ったデータセットの画像追加

最後に

Amazon Lookout for Visionが想像以上に便利で驚きました!
データが少なくとも、精度は申し分ないといえそうです。
異常検知を気軽に試したいときには積極的に活用していきます。

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

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

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

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

2020年アドベントカレンダー振り返り

皆さんあけましておめでとうございます。
@tereka114です。

昨年の最後は例年の如く、アドベントカレンダーが盛り上がりました!
皆さんはどのアドベントカレンダーが良かったでしょうか?

Acroquestは、有志がQiitaの各種アドベントカレンダーに参加し、執筆していました。
本記事ではアドベントカレンダーの投稿記事の一覧と注目度の高かった記事を紹介します。

おすすめ3記事

特徴量エンジニアリングのライブラリ xfeat を使ってみて便利だったこと

acro-engineer.hatenablog.com

この記事はxfeatと呼ばれる特徴量エンジニアリングを楽にするためのツールの紹介です。
私自身も使ったことがありますが、頻繁に使われる特徴量エンジニアリング手法が気軽に試せるのは良いですね。
個人的にはcuDFとも何も考えずに連携できるのが一番嬉しいです。

ぜひ、特徴量エンジニアリングを気軽に実施したい方におすすめです。

超爆速なcuDFとPandasを比較した

acro-engineer.hatenablog.com

私が書いたcuDFで良かったこと・困ったことをベースに執筆したものです。
最近頻繁に使っていて便利ではあるのですが、慣れないと癖もあります。
cuDFを使う前に一度読んでおくことをおすすめします。

Ver.7.11からElasticsearchのスキーマ設計が大きく変わる

acro-engineer.hatenablog.com

Elasticsearch Ver.7.11から導入された「Runtime Field」とこれまで導入されていた「非同期検索」により
従来までの「Schema on Write」だけではなく、「Schema on Read」でのElasticsearchの利用ができるようになりました。
詳しい説明はぜひ、記事をお読み下さい。

最後に

あらためて昨年を振り返ると、Elasticsearch、機械学習に加え、テストやAzureなど多種多様な記事をこのブログで提供できたのではないかと思います。
今年も引き続き良い情報を提供していきたいと思います!

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


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

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

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