羊をめぐるブログ

趣味の色々について書きます

knowledge graph構築のサーベイ論文:Architecture of Knowledge GraphConstruction Techniquesを読む

論文情報

https://acadpubl.eu/jsi/2018-118-19/articles/19b/24.pdf

概要

knowledge graph(KG)の構築に関するsurvey.

Architecture of Knowledge Graphs

KGの構築方法は大まかにtop-down方式とbottom-up方式に分けられる.

top-down方式はKGのontologyとschemaがあらかじめ定義されており,そこに新たな情報を追加していくというもの.ドメインをよく表現できるontologyの定義ついて議論されることが多い.

一方,bottom-up方式では,Linked Open Data(Wikiとか?)や他の知識ソース(テキストとか?)から情報の抽出及びKGの構築を行う.

この論文では主にbottom-up方式について解説をする.

Screen Shot 2020-10-19 at 20 39 47

Procedures of Bottom-up ApproachofKnowledge Graphs

bottom-upアプローチを構成する手法について解説する

Knowledge Extraction

data sources

主なデータソースとしてはhtml, xml, jsonのような構造データ,フリーテキストや画像のような非構造データがある.これらのデータを,機械が理解しやすいRDFJSON-LDformatに落とす.

初期のKGでは,単一のソースのみから情報抽出を行っていた.例えば,医療の分野では,診療録や医学雑誌などを対象にしていた.

一方で大規模KGの構築では様々なデータソースから情報抽出を行う.例えば,Google Knowledge Vaultはテキスト,HTML tree,HTML tables,人間がアノテーションしたページなどをソースとしていた.最近では特に,Wikipediaなどの情報抽出が非常に行いやすいソースが重要視されている.YAGOやDBpediaはWikipediaをソースとしている代表例である.

その他,医療業界など特定ドメインのKGにおいてもWikipediaは利用されている.

Wikipediaの他にも,WordNetやGeoNames, Concept Net, IMDB, MusicBrainzなども良いソースであると言える.

Types of Knowledge Extraction

extractionの手法は大まかに3つに分けられる.

  • Entity extration
  • Relation extraction
  • Attribute extraction

attribute extractionはrealtion extractionの特別な場合とも言える

Entity Extractionとはknowledge resourceからエンティティを見つけ,事前に定義されているカテゴリに分類する作業である.Entity Extractionの質は後続の処理に大きく関わるため,Knowledge Extractionの中でも最も重要なパートと言える.

Entity Extractionの後,entity間のrelationの解析を行い,relation extractionを行う.

relation extractionがdenotational semanticsを定義するのに対し,attribute extrationはエンティティのintentional semanticsを定義する(よくわからない.エンティティの属性をより明確に表す情報を取り出すということか?).

Approaches of Knowledge Extraction

Knowledge Extractionの手法は以下の分野と関わりが強い.

  • NLP
  • text mining
  • machine learning

初期のKnowledge Extrationは,人手でアノテーションされたコーパスに対してルールベース,辞書ベースの手法を適用することで行っていた.

機械学習的アプローチでは人手で訓練データセットを作って教師あり学習をするケースが多いが,アノテーションに多くの専門家と時間がが必要であることから,結果として得られるコーパスは小さくなりがちなため,KEとはミスマッチ感がある.また,教師あり学習アプローチは対応できる範囲が既存のコーパスの範囲内のみであり,新たなエンティティへの対応が必要なKEには利用しづらい.

近年では,アノテーションのコストを避けられる反教師あり,もしくは教師なし学習が主に研究されている. 主に以下のような分類モデルが利用されている

  • Hidden Markov Model
  • CRF
  • kNN
  • Maximum Entropy Model
  • SVM

評価指標としてはF-measureが主に利用される.

Knowledge Fusion

Knowledge Fusionのゴールはエンティティの順序関係を捉え,オントロジーを構築することである.これはiterativeに行われる.オントロジーの構築プロセスは,結果の質が一定の評価基準を超えるまで繰り返される.

Entity Alighment

Entity AlighmentはEntity Resolution,Entity Matchingなどとも呼ばれたりする. 具体的には異なるEntityが現実世界における同一のオブジェクトを指すかなどの判断を行う作業である. Entity Alighmentでは通常,複数のEntity Matchingの手法をKGの特性に合わせて組み合わせて用いることをする.

以下がEntity Alighmentのフロー.

Screen Shot 2020-10-19 at 16 52 58

Data Processingはデータのstandardizationなどとも呼ばれ,Entity Alighmentの中の重要なステップの一つであり,以下のような問題に対応する必要がある.

  • 複数のソース上で異なる名称として存在する,定義が異なる,データの表現方法が異なるなどの問題に対応し,データの完全性,一貫性を保つ

Entity Alighmentのためには主にEntityの持つテキスト情報などのattributeから求められる類似度を使うfeature matchingが利用される.

Attributeのmatchや比較のためにはテキスト類似度が用いられ,relationのmatchなどには構造的類似度が用いられる

Entity Alighmentは,通常はWikipediaやentity情報などの外部情報に依存している.

近年では他のKGを補助情報として知識推論を行う手法などの研究が行われている.

Ontology Construction and Evaluation

KG構築のためには, entity及びrelationのalignの他にも次のような作業が必要となる.

  • taxonomy(分類体系)や階層構造のの構築
  • metadataの追加
  • 他のデータソースの情報の追加

KGの質の担保のため,オントロジーにはFOAFのような一般的なものを使い,また,metadataはschema.orgに対応することが必須となる.

Q

  • KGの質の評価の具体的方法
  • FOFA, schema.orgを導入するとはどういうこと?

ネイティブアプリでのOCRの性能を検証してみる(Tesseract, Cloud Vision API)

はじめに

小説などを読んでいると時々見たことのない単語に出会すことがあります.

最近だと

「傴僂」 「聯関」 「偏頗」

などに遭遇し,困りました.

全く知らない単語に出会した時,読み仮名がふってあれば良いのですが,ない場合も多く,そうなると検索が非常に困難です(紙だと単語コピーもできない).傴をにんべん口三つなどとググったのは黒歴史です,

手書きで漢字を判定するアプリはよくありますが,細かい漢字を指で書くのは面倒なので写真でできないかなと思い,ネイティブアプリでのOCRを検証してみました. 検証の対象としては,OCRエンジンとして有名そうなTesseractのswift版であるSwiftyTesseract,Cloud Vision APIの一部として提供されているOCR APIを利用しました.

github.com

cloud.google.com

検証内容

与えるデータ

まず,一般に認知されてる少し複雑な単語として以下を試します.単語の認識ソースとしては,ググって出てきたwebページを撮影し,単語箇所を切り抜いたものを利用します.

「溢れる」 「詳細」 「鬱病

f:id:sheep96:20201004012609j:plain f:id:sheep96:20201004012622j:plain f:id:sheep96:20201004012634j:plain

次に,あまり日常生活で見ない単語である

「傴僂」 「聯関」

f:id:sheep96:20201004012717j:plain f:id:sheep96:20201004012729j:plain

を試してみます.

最後に,OCRはそもそも単語でなく文章を読み取るためのものな気がするので,新潮文庫より出版されている小説「金閣寺」(三島由紀夫著)の裏表紙のあらすじを与えてみます.

f:id:sheep96:20200930185545j:plain:w300

使うモデル

モデルとしては以下を利用します

  • Tesseract (速度重視のtessdata_fast,精度重視のtessdata_best,公式ではfastがおすすめらしい)

  • Cloud Vision API

実装の参考は以下

shinjism.com

結果

単語の読み取り

Tesseract Best Tesseract Fast CVA
処理時間 一瞬 一瞬 1秒
溢れる OK OK OK
詳細 OK OK OK
鬱病 OK OK OK
傴僂 価 佑 偏優 區傻
聯関 職 関 隊関 OK
  • 一般的に認知されている単語についてはどれも正確に読み取ることができた

  • 認知度の低い単語については,Vision APIはTesseractより秀でているようです(傴僂についても近い漢字を出せている).モデルの質よりは学習データ上の語彙数とかの問題な気がする.

  • 処理時間に関しては,ほぼ一瞬.Vision APIはレイテンシも含んでいるので少し遅い.

文章の読み取り

Tesseract Fast

処理時間:1,2秒ほど

一九五〇年七月一日、「国宝・金剛
寺焼失。放火犯人は寺の青年信」 と
いう衝撃のニュースが世人の耳目を
驚かせた。この事件の陰に潜められ
た若い学僧の悩みーーハンディを背
負った宿命の子の、生への消しがた
い呪いと、それゆえに金開の美の魔
力に魂を要われん、ついには幻想と心
中するにいたった悲劇……。31歳の
鬼オ三島が全青春の決算として告白
体の名文に組った不朽の金字塔。

精度に関しては所々間違うところはあるが,長文においても処理が速いのは魅力的.

Tesseract Best

処理時間:10秒ほど

ー 九 五 〇 年 七 月 一 日 、「 国 宝 ・ 金 閣
寺 焼 失 。 放 火 犯 人 は 寺 の 青年 僧 」 と
いう 衝撃 の ニュ ー ス が 世 人 の 耳目 を
藻 か せ た 。 こ の 事件 の 陰 に 潜め られ
た 若い 学 僧 の 悩み ーー ハン ディ を 背
負っ た 宿命 の 子 の 、 生 へ の 消し が た
い 上 呪い と 、 そ れ ゆ え に 金閣 の 美 の 訂
力 に 魂 を 奪わ れ 、 つ い に は 幻想 と 心
中 する に いた っ た 悲劇 ……。31 歳 の
鬼 オ 三島 が 全 青春 の 決算 と し て 告白
体 の 名 文 に 綴っ た 不朽 の 金 字 護 。

単語間に空白が混ざるが,精度に関しては2,3箇所間違える程度.

Cloud Vision API

処理時間:7秒ほど

一九五○年七月一日、「国宝 金閣\n寺焼失。放火犯人は寺の青年僧」 と\nいう衝撃のニュースが世人の耳目を\n驚かせた。この事件の陰に潜められ\nた若い学僧の悩み ハンディを背\n負った宿命の子の、生への消しがた\nい呪いと、それゆえに金閣の美の魔\n力に魂を奪われ、ついには幻想と心\n中するにいたった悲劇 。31歳の\n鬼才三島が全青春の決算として告白\n体の名文に綴った不朽の金字塔。\n

精度に関しては完璧.

所感

  • 一般的な単語の認識ならTesseractでも十分だが,複雑な語彙にも対応するならCloud Vision APIを使う方が良さそう.

    • 当初の目的の単語判別をするならCVA使うしかない
    • Vision APIは1000リクエスト/month 以上は課金なので節約を考えつつ組み込むのが怠そう...
    • 複雑な鬱はどのモデルも認識できているので,モデルの性能よりは学習データの語彙の差な気がする.
  • 文章長が処理速度に結構影響している

  • Tesseractは公式の通り,fastを使うのが良さそう(精度の差は少しだが,長文の処理は10倍ぐらい速い)

flutterで内蔵辞書検索(iOS)

はじめに

flutterで内蔵辞書検索 on iOSを実装してみたので,その備忘録を書きます.

方法

以下の手順で行いました

  1. iOS側で辞書検索のためのmethodを実装

  2. flutter側からmethod channelで呼び出す

単純ッ

実装

iOS側の実装

iOSでは内蔵辞書検索のためのAPIとしてUIReferenceLibraryViewControllerが用意されています

Apple Developer Documentation

こちらのapiは,単語を引数として受け取り,内蔵辞書に対する検索結果のViewControllerを返すという動作をします.辞書内に複数見つかった場合はリスト表示され,見つからなかった場合はNot Foundが表示されます.

あくまで辞書の検索結果のページを返すだけであり,検索結果をデータとして取得して弄るなどのことはできないようです(著作権のせい?).

ただ,MacOS用なのででiOSでは使えないのですが,swift自体にはDCSCopyTextDefinitionという検索結果をデータとして得られそうなAPIが用意されているみたいです.

Apple Developer Documentation

とりあえず,今回はflutterからUIReferenceLibraryViewControllerを呼び出せるようにiOS側に実装します.method channelの実装は以下を参考にしました

FlutterでiOSのネイティブコードを呼び出す - Qiita

以下をmethod channelで呼び出します

    func searchDictionary(result: FlutterResult, controller: FlutterViewController, queryWord: String){
        let ref: UIReferenceLibraryViewController = UIReferenceLibraryViewController(term: queryWord)
        controller.present(ref, animated: true, completion: nil)
    }

}

flutter側

iOS側に書いたmethodを呼び出すだけなので省略.

実際の動作

実際に使ってみると,レスポンスは遅いですが,辞書検索の結果が表示されることがわかります. iOSが検索窓などで提供してる辞書検索は一瞬で結果が出るのに,なぜアプリからだとこんなに遅いんだ

streamable.com

その他

内蔵辞書検索機能は,それだけを提供するような単純なアプリだとrejectになるとドキュメントや以下のブログにて言及されています

Apple Developer Documentation [iOS] 内蔵辞書機能を使うとリジェクトされる? | Cocoamix.jp

どの程度シンプルだとrejectになってしまうのかはわかりませんが,サブ機能程度にしておいた方が落ち込む危険性が低そうです

email & socialログインを実装する際のRDBのスキーマについて

はじめに

email & twitterなどのsocialアカウントでのログインの実装をしようと思ったのですが,各サービス用の認証情報のためのRDBスキーマをどう設計するかで詰まりました. 現状のベストプラクティスなどを探してみたのですが,あまり情報が見つからなかったので,自分がやった方法を備忘録としてまとめます. 一旦,emailとtwitterでの認証を用意するという前提で設計しました.

結果

いきなりなのですが,以下が最終的に決定したスキーマになります

f:id:sheep96:20200715224911p:plain

userテーブルが基本的なユーザ情報を格納するテーブルです.

認証情報は,サービスごとにuser_auth_serviceというuserのidを外部キーとして持つテーブルを作り,そこに入れるという感じです.

userがどの方法で認証を行うかはuserテーブルの中に保存しておきます.

メリットとしては以下があるのではと考えています

  • 新たな認証方法を追加しやすい
    • 新たな認証用のテーブルを追加するだけでよく,既存のテーブルに変更を加える必要がない(と思う)
  • ユーザの退会がしやすい
    • ユーザの退会の際にユーザ情報を消そうとすると外部キー制約に引っかかりますが,この方法ならその影響を受けずに認証に関わる部分を一発で消せます

一方で以下のデメリットがあるような気がします

  • 複数の認証情報を持つようなケースに対応しづらい
    • emailと電話番号両方というようなケースに対応する場合はuser_auth_multiとかのテーブルを作るかauth_methodを増やすとかになるんでしょうか...
  • userと認証情報をjoinして列挙したりしづらい
  • デッドロックしないように配慮が必要そう MySQL 外部キー制約のデッドロック | 優技録

検討したけど無理そうだった方法

サービスごとの認証情報を同じテーブルで持つ方法

php - Database structure for social login implementation? - Stack Overflow

認証情報を同じテーブルで持ち,providerというカラムでどのプロバイダ用のものかを判定する方法です

以下のような方法で微妙そうだなとなりました

  • EAVはアンチパターン
    • providerごとにキーの性質が違うときつい
  • providerごとのキーがバッティングしない可能性がゼロではない
  • ユーザがどの方法で認証するかを判定するためにレコードを走査する必要がある

userテーブルにサービスごとのカラムを付け足す方法

空白箇所が増えるなど無駄が多そうなのでやめました

サービスごとにユーザのテーブルを作る方法

外部キー制約をかけるのが辛かったりユーザの列挙が辛かったりその他様々な理由でダメそうでした

最後に

今は良さそうと思っていても,実装するうちに致命的な欠点などが見つかりそうで怖いです

また,サービスのアーキテクチャはよく公開されているのを見かけるのですが,長く運用されているDBのスキーマの変遷の歴史や,ベストプラクティスはあまり見ないので,とても気になるなぁ〜と思いました

「白い春」を見た

阿部寛さん主演,尾崎将也さん脚本の「白い春」を見たので感想を書きます.

概要

2009年に放送された阿部寛さん主演のドラマです.脚本は「結婚できない男」でも知られる尾崎将也さんです.彼女の病気を治す金を得るために止むなく殺人を犯した元ヤクザの男が,刑期を終え出所します.しかし,元気にいきているはずであった彼女は亡くなっていることがわかりました.納得がいかない主人公が公園でうなだれていると,絵を描く女の子に話しかけられ...というのが始まりです.家族愛を描いた感動ドラマでした.

なぜ見たか

2chtrickスレとかを見ていた際に阿部寛主演のおすすめドラマとして挙げられていたからだったと思います.丁度amazon primeにも入っていました.普段はほとんどドラマなどは見ないのですが,ふと1話目を見たら,すごく引き込まれてしまい.そのまま2,3日で全部を見終えてしまいました.その辺の映画のようなあまりに壮大な家族愛でなく,身近で,血と汗の通った,輝かしいだけでない家族の愛が描かれていたような気がします.

最初の印象

阿部寛さん主演のドラマというと「trick」や「結婚できない男」などコメディ色の強いものが多いイメージだったので,コメディ色強めの家族ドラマなのかなと思っていました.しかし,登場した阿部寛演じる主人公の顔があまりにドス黒く,見た瞬間にこれはマジなやつだなと感じました.遠藤憲一演じるパン屋も,幸せ満点という感じでなく,キツイ仕事を続ける中で得られるお客さんの幸せや家族の生活に,(ヤクザの主人公に比べ)小市民ながらプライドを持っているという感じがすごくリアルでした.

内容の感想

人生で見たドラマや映画の中でも,1,2を争うくらい面白かったです.2話の最後にパンをかじるシーンや,最終回の主人公が女の子に父親のすごさを語るシーンでは,ボロボロ泣きました.単なる家族愛ドラマでなく,色々なものを失い,帰る場所もない主人公の寂しさ,子供を守る父親の強さとその裏の不安など,泥臭い感情を注ぎ込んでくるような作品でした.見ていると両親の仕事で疲れた姿や,町の店の店員さんのささやかな笑顔とか,そういった日常の裏側を思わされ,そこでも涙が出ました.あり触れた日常がどれだけの努力の上になりたっているのかを考えさせられます.何回も見直し,シーン一つ一つを噛み締めたくなる作品でした.

色んなソース上で大きいサイズのテストデータを作る

はじめに

性能試験を行いたいとき,100GBを超えるようなデータをS3のようなストレージだったり,MysqlのようなRDBなどの上に用意したいことがあると思います.しかし,単純にやろうとすると以下のような問題に直面します.

  • ローカルで100GBのデータなんか作れない!!
  • 作れても転送に時間かかりすぎ!!
  • 101, 102GBみたいに刻んで作る必要があったりすると,もう無理!!

ということで今回はGCS,MySQL,Bigquery上に色んな大きいサイズのデータを作成することを行なったので,備忘録として書いてみようと思います.

方法

基本的に小さいデータを作って転送してから,それをコピーしまくる方針で行う

GCS

主に以下の手順で行います.

  1. 1GBぐらいのサイズのデータをローカルで作る
  2. gsutilを使ってGCS上にアップロードする.
  3. gsutilコマンドを使って,必要なデ. ータサイズ分コピーを繰り返す.

aws S3などの場合でも,awsコマンドで同じようなことができると思われる.

MySql

  1. 1GBぐらいのサイズのCSVデータ(test_1GB.csv)をローカルで作る
  2. MySql上にtest_1GBという名前で,先ほどのCSVを入れるためのテーブルを作る
  3. mysqlimportを使って,先ほど作ったCSVをテーブルに入れる(mysqlimportコマンドで転送する対象のテーブル名はcsvのファイル名と同じでなくてはならないよう?)
  4. 以下のようなクエリを必要なデータサイズ分叩く
DROP TABLE IF EXISTS testdata_NGB;
CREATE TABLE testdata_NGB;
# 以下を繰り返し
INSERT INTO testdata_NGB SELECT * FROM test_1GB;

Bigquery

  1. 1GBぐらいのサイズのCSVデータ(test_1GB.csv)をローカルで作る
  2. 作ったCSVを入れるようのbigquery schemaをjsonで定義する
  3. bq loadコマンドでCSVをもとにテーブルを作成する(スキーマのauto detectも可能) bq --location=$LOCATION load \ --replace \ --source_format=CSV \ --skip_leading_rows=1 \ $PROJECT_ID:$DATASET."test_1GB" \ ../test_1GB.csv \ ./schema.json
  4. bq cpコマンドを必要なデータサイズ分繰り返す bq --location=$LOCATION cp \ --append_table \ $PROJECT_ID:$DATASET."test_1GB" \ $PROJECT_ID:$DATASET."test_${DATA_SIZE}GB"

重松清さんの「流星ワゴン」を読んだ

重松清さんの「流星ワゴン」を読んだので感想を書きます.

概要

ドラマ化もされた重松清さんの代表作だと思われます.家庭や仕事,全てが崩れかけになり自殺を考えていた主人公の前に過去へと向かうワゴンが現れるという内容です.ビタミンFに代表される,家族の現実,温かみなどを感じさせてくれる小説でした.いつもは心をどん底に落としてくるようなものを読んでいますが,たまにはこういうものもいいです.3週間ぐらいかけてちびちびと読みました.

なぜ読んだか

いつも読む小説の多くは突出した悲劇が書かれていました.そういうものは自分の心をどん底に突き落としてくれますが,やはり自分の生活とはかけ離れているので,日々の行動にポジティブな影響を与えるかというとなんとも言えません.最近,生きるうえで起こる悩みをどう捉えるか,どう捉えていくかについて考えていて,その中で,自分が社会を生きていく中で遭遇するような悩みをちゃんと受け止められるかというのが気になりました.流星ワゴンで書かれているのはまさに血の通った悩みの数々であり,そういうものを体験してみたかったのが大きな理由かもしれません.あと,流星の絆を読んでみようと思って探してたらこれを見つけたというのもあります.

最初の印象

私はファンタジーとかがあまり好きなタイプの人間ではないので,タイムスリップと書かれているあらすじを読んで,うーん,これはちゃんと生々しい部分を感じれるようなもんなのかなぁ〜,魔法でごまかしたりしないかなぁと思っていました.よくわからない超常現象に人間の心がグラグラ動かされるというのは,感情移入がしにくいです.この小説はそことは反対だったので,とてもよかったです.

内容の感想

人間関係における不器用で伝わりきらない部分,でもそこを生きてるからこそ感じられる希望みたいなのを自分も体験できたような気がします.人間どうしようもない部分がたくさんあって,それで人とすれ違ったりもするけど,ちゃんと繋がってる部分はあるよと教えてくれるようでした.タイムスリップというファンタジーな要素も,周りの人間の不器用さの裏側の思いを知るための舞台装置としてうってつけなように思えました.本人にしかわからない葛藤を考えず,表面に出てくる結果だけを見てしまうよくないコミュニケーションが発生することは多々ありそうです.そこを広く受け止められる心を持って,また,他人の裏の温かみを見落とさないように生きていこうと思います.ドラマは最後ファンタジーパワーで全部解決するらしいですが,やっぱどうにもならない日常に希望を見出して生きてくというほうが,私は好きです.