文字のゆらぎをどう扱うか?

奥田裕樹氏:今回は「文字のゆらぎをどう扱うか? - Sansanにおける自然言語処理の活用」という話をさせていただきたいと思います。最初に、私が所属しているDSOCという組織について軽く紹介をした後に、「ビジネスの出会いを科学する」について小話をさせていただきます。その後、具体的な事例を2例ほど紹介したいと思います。

最初に自己紹介をさせてください。奥田裕樹と申します。

今年1月からR&Dグループの研究員としてジョインをして仕事しております。大学院時代は遺伝子の分野で研究をしておりまして、そこからリクルートテクノロジーズという会社に新卒入社をいたしました。

その後、機械学習や自然言語処理系の開発に携わりまして、今年1月にSansanにジョインをして、今に至るというようなかたちです。

Twitterは「@yag_ays」という名前で活動しておりますので、もしよろしければ見ていただければと思います。また、この資料は後日公開するので、そちらの方も参照いただければと思います。

まず、SansanのDSOCという組織についてです。

別名は「Data Strategy & Operation Center」という名前でして、法人向けのSansanと個人向けのEightから出てくる大量の名刺の画像というものを、いかに効率よく、そして低コストでデータ化するか、といったようなことを中心に行う組織となっております。

そこでお預かりしたデータをいかに活用するかというような部分も含めて、このR&Dグループの分野となっております。

私たちは「出会う、が、世界を変えていく」というようなことを掲げております。

名刺の交換というと、ただ紙をぱっと渡すだけかと思われるかもしれないんですけれども、実際にはあるビジネスマンとあるビジネスマンがそこで出会って、名刺交換をして、もしかしたら挨拶をするかもしれないし、商談をするかもしれない。そういったような、人と人との出会いというのが、この名刺1枚に現れる。

それをいかに活用するか、といったようなところで私たちは、データ化業務の自動化や精度向上、またはお預かりしたデータの活用みたいなことを通じて、みなさまに価値を届けたい、というようなことをやっております。

ディープラーニングを用いた項目判定

僕の同僚の話なんですけれども、いくつかディープラーニング的なところの紹介をしたいと思います。

まず名刺を画像からデータ化する際に項目を選択して「ここには名前が書いてある」「ここには住所が書いてある」みたいなことを、矩形検出のようなかたちでセグメンテーションする手法があります。

それを今実際に運用しておりまして、精度は98パーセント以上となっております。一方、名刺の画像から言語を判定するといったようなこともやっております。言語を判定するというと、テキストからそこに書かれてる文字が日本語なのか中国語なのか、といったようなことを思われる方が多いと思うんですけれども、実際は、画像の状態で私たちは判別をしております。

これはなぜかと言うと、名刺をデータ化する際には、最終的に精度を担保する際に人間が介在をして、人間が最終的なチェックをして、そのクオリティを維持するということをやっております。

そういった名刺のデータ化の際に、言語というのが大きな壁となるわけですね。例えば僕なんかは日本語と、まぁ英語はある程度わかってデータ化することはできます。ただ、中国語はたぶんわかんない漢字とかいっぱいありますし、韓国語とかはまったく読めなくて、人によってデータ化に得手不得手があると。そういった時に、名刺の情報から「じゃあこの人はこの担当者にお願いしたい」みたいなかたちで、言語を指定することによって、グローバルに展開する私たちのサービスをより精度の高いものとしております。

またこのあと中心になる話なんですけれども、「名寄せ」と呼ばれるようなものを開発しております。名寄せというのは、ある1つのものがある別のものと同じかどうかということを判定するもので、会社や人物に対して行っております。

例えば、私は今Sansan株式会社の奥田裕樹という人間ですけれども、1年前は別の会社の奥田裕樹で、その時は別の名刺を持っていました。その名刺と、今Sansanの奥田の名刺が同じ人物かどうかって判定するのは、けっこう難しい問題なんですね。

そういった時に、じゃあ前の会社の奥田裕樹と今の会社の奥田裕樹、どういう人とつながっているかを確認することによって、その人が同じ人物か違う人物かといったようなことを、自動的に処理をすることをやっております。

これは会社に対しても同じことで、ここのセッションで話している全員はSansan株式会社の同僚なんですけれども、彼らが違う名刺を持っている時に、果たしてSansan株式会社っていうものが私たちの会社なのか、もしかしたら同名の別の会社なのか、といったことを判定するものですね。

私たちは機械学習とか自然言語処理を通じて、その精度や効率化を高める努力をしてますけれども、なにも「機械に全部置き換わったらいい」と思ってるわけではありません。機械は機械、人間は人間の得手不得手みたいなものがありまして、それぞれに協力することによって初めて、精度高い効率的なシステムができると思っております。

なので、自動化できるところは自動化して、その自動化で間違ったりとか修正しなきゃいけない部分を人間が指摘をして、それをまた機械にフィードバックさせる。そのループを回すことによって、私たちはこの精度向上というものについて取り組んでいます。

「科学する」とはなにか?

ここまでがDSOCの内容なんですけれども、ここからちょっと話を変えます。

今、私たちはサイトで「私たちはビジネスの出会いを科学する唯一の組織です」ということをうたっています。なかなか大きいことを言ってますよね。

この中でちょっと気になる部分があって、「科学」というものについて話をしたいと思います。ところでみなさん、科学してますか? 科学してる人、してない人ってなんか、よくわかんないですよね(笑)。こういう響きは、僕はすごい好きなんですけれども。

「科学をしてる」ってどういうことなのかなっていうのを立ち止まって考えてみたいと思います。そういう時に、がむしゃらに科学っていうふうに考えてもしょうがないのでまず歴史から振り返ってみようと思います。

自己紹介で話したように、僕は遺伝子の解析をする分野から来ております。もともと学部はもろに生物学をやっておりまして、メスを握ったり、顕微鏡を覗いたりしながら、解剖したり、そういう学部におりました。

そういった専門的な生物学の授業がありまして、そこで最初に習うことは実は、「名前をつける」ことなんですね。よく「学名」っていうふうに聞きますよね。それが生物の名前です。

例えば、ここに犬の絵があります。

犬っていうのは学名的に言うと、「canis lupus familialis」という名前がついています。ここでは「canis」っていうのが属名、「lupus」というのは種小名と呼ばれておりまして、基本的にはこの2つで1つの生物の種を表す、というような取り決めがあります。

これを考えたのは、カール・フォン・リンネという人です。

18世紀ぐらいに活躍した人で、近代系統学の祖と言われております。この時代、すごいおおざっぱに話すと、ちょうど大航海時代の中期~後期ぐらいで。いろんなヨーロッパの船が世界各地に行って、その土地のものを持ち帰ってきたり、そこを植民地化したり、そういうような時代です。

その時にヨーロッパの人たちは、例えばアフリカとかアメリカという他の国に行く中で、現地の生物を見て「なんでこんな変な生き物がいるんだろう」というようなこと思って、ヨーロッパに持ち帰るわけですね。

ヨーロッパに持ち帰ったら、だいたい貴族とかに売ったりして。貴族はそれを見て「珍しい生き物がいるものね」みたいなことを言って興じたりするわけです。そういうようなかたちで、世界というのがこの大航海時代によって、だんだん距離が短くなって、いろんな生物を人間が見ることができるようになった。

そういった時に、じゃあそれに一つひとつ名前をつけていこう、分類していこう、という科学的な手法が発展してきました。これが、僕が考える近代的な生物学、それから今に至るまで脈々と続いている生物学の基礎的なところなんじゃないかというふうに思っております。

Sansanは名刺管理データ化会社ではない

翻って、私たちのやってることを考えてみると、私たちも実際に大量の名刺を取り込んで、その名刺に書かれている会社や個人というのを特定しようとがんばっています。

ただ私たちは名刺管理請負会社でもなくて、名刺管理データ化会社でもないと、胸を張って言えるポイントだと思います。

私たちはみなさんが持っている、もしくは日本で流通している、さまざまな名刺。それを対象に、その名刺を持っている会社や人を特定し、それを価値に活かそう、といったような手法を取っております。

それは生物学が持つ根本的な、生物を対象にして、「その生物」っていう「個」を考えよう、それから研究を始めようといったような、根本的かつ基礎的な行為にほかならないかなと思っております。

名刺のデータを整理するということ

さて、ここで1個クイズです。

「1,899,587」ってどういう数字だと思いますか? 先ほどの話に絡めた数字なんですけれども。

これは人間が識別することができる、実際に記載された生物種の総数なんですね。これは2009年の統計なので、今はもっと数字が多くなっております。おそらく200万種ぐらいになっていると思います。

みなさん、生き物のすべての数が200万種と聞いて、多いと思いますか、少ないと思いますか。例えば僕なんかは生き物好きですが、たぶん「生物の種類を言え」と言われて、「100種類言えたらいいほうかな、200種類とかはちょっと難しいかな」ぐらいな数です。今世界中の生物学者が生物を分類できる最大の数というのが、この約200万種になっています。

一方で、「400万」。

これは何の数字でしょうか。これは「日本に存在する企業の数」が約400万企業あるということです。実際には、大企業と呼ばれるものは1万数千社ほどで、その他は全部中小企業となっておりまして、大きいものから小さいものまですべてを含めて、あとは統合されたり廃業したりといったようなことも含めて、この400万という数字になっています。

生物学者はフィールドワークに行って、いろんな生物を集めてきて、その生物が知っている生物だったらそれを研究対象にする。知らない生物だったらそれに名前をつける、といったようなことをやってます。

その時に使うのが、その生物の形とか、それがどういうふうに生きているか、どこに生きているか。あとはその生物同士が交配可能かどうか、というものも生物の種を決める1つのポイントとなります。そういったいろんな情報を使って、生物を分類しています。

一方で私たちは、名刺しかないわけです。名刺というのは非常に多くの情報を含んでますけれども、それがすべてかと言われるとそうではない。会社名とか部署・役職名、名前、住所、電話番号、いろんなものが書いてあったり書いてなかったりする。多様な名刺を扱う中で、その裏にある個人や企業というものを的確に識別するということが必要になってきます。

そういった時に、生物ですと形とか色とか、いろんな情報が使えます。私たちは基本的に、この会社名を含んだ文字列を対象に、そのテキストだけを使って、いかに精度高い個人の特定、会社の特定をするかといったことをやっております。

名寄せの精度向上

では具体的な話に入りまして、1つは「名寄せの精度向上」という話をさせていただきます。私たちは名刺の取り込みからいろんな処理を経てデータを作成する。そのデータ化の精度は99.9パーセントを誇ると言っております。

一方で「残り0.1パーセントどこに行った」って話なんですけれども。なかなかこの0.1パーセントを上げるっていうのが、非常に苦しい・つらい作業となっております。例えばみなさん、Eightで名刺の写真を撮る時にぶれたりしていませんか。ぶれたりすると、名刺の画像がうまく読み取れなかったりするわけですね。

そういったいろんな状況から入ってくる大量の名刺をいかに正確にデータ化するか、っていうようなところに対して取り組んでいるんです。ここではちょっと、会社名に絞ってお話をさせていただこうと思います。

名刺から入ってくる会社名というのは、さまざまなゆらぎが生じています。例えば私たちはSansan株式会社で、昔は漢字の「三」を二つ並べた三三株式会社だったんですね。日本中探せば、どこかにこの漢字の三三株式会社の名刺が眠ってるはずです。

あとは英語名ですとSansan, Inc.という名前がついていたり、表記揺れがあると「SanSan」のSの2つ目が大文字になっている、みたいなものがあります。実はSansanは1つ目が大文字で、2つ目は小文字のSansanになっています。

あとは、たまたまデータ化のミスによっていろんな文字列、「代表」とかが入ってきたり、「大阪支社」みたいな不要なものが入ってきたりといったようなことがありまして。こういった、ここに書かれている間違った会社名、すべて1つのSansanに紐付くようにする必要があるんですね。

網羅性を考えても、やってもやっても、非常に難しい。例えばルールベースで「代表は消しましょう」「大阪支社は消しましょう」とやっても、ほぼ困難なタスクとなっております。

主なアプローチと制約

そこに対して私たちは自然言語処理を用いてアプローチをしてるんですけれども、1番簡単なのは「大量に辞書を作る」ことですね。

Sansan株式会社っていうのはこういうバリエーションがありますよ、名前のゆらぎがありますよと列挙しておけば、それが最も確実な方法で名寄せをする手段となります。

一方、これから話す内容としては、それ以外にも入力の文字に対してそれに近いものを探したり、その文字自体を変えてしまったりといった発想でやっております。ただこの時に必要になるのが、「制約」つまり、計算量、計算時間のことですね。

先ほど話したように、400万社の会社名があります。1つの名刺に書かれている会社名は1つです。その1つに対して400万社の中から「どれが一番近いかな」「どれがもっともらしいかな」っていうのを探すのは、非常に計算コストのかかる作業となっております。

編集距離を名寄せに利用する

それに対して、今回は3つの方法をお話しさせていただこうと思います。まず文字の編集距離。これはエンジニアの方もよく使われてるかと思います。

例えば「Sansan株式会社」と「Yonyon株式会社」というものがあった時に、「n」とか「株式会社」みたいなものは同じ文字ですよと。ただSがYになっていて、AがOになってると。

そうした時に、SからYに変えるコストを1とした時に、それが合計で4となる。それがSansan株式会社からYonyon株式会社の近さです。これを使うことによって、データ化ミスであったり、細かなノイズみたいなものを含んだ時にも、その文字の間の距離というのを測ることができます。

この編集距離というのは非常にメリットがあって、かなり高速に動きます。あとはインデックスを作成しておくことによって、その処理を大幅に削減することができます。

一方で、まとまった単位の文字の入れ替わりには非常に弱い。例えば「株式会社Sansan」と「Sansan株式会社」っていう文字列を比較する時には、けっこう離れてしまったりするわけですね。あとは文字の長さによって、長い文字でかつそれが重要でない時に、それに引っ張られるといったようなこともあります。

それで、先ほど話したように社名の検索っていうのは実際400万件ぐらいを検索すると10~20分かかるんですけど、インデックスを作成しておくとだいたい0.4秒ぐらいで可能となります。

これだけでは精度がなかなか出ないので、この文字単位から連続するn文字を取ってくる。例えばSansanですと、「Sa」とその次に「an」みたいなかたちで、横にずらしていって文字の集合を作成する「n-gram」という手法がありまして。それを用いて判別することによって、より系列を考慮した文字の編集距離というのを計算することができます。

単語埋め込みを用いた文章類似

次に「単語埋め込みを用いた文章類似」という話をしたいと思います。

先ほどは文字の種類を見て、それが同じか違うかみたいなことを見ていました。でも文字は、人間が読めばわかるように意味を持っていますね。

なので「Sansan」っていう文字列に対して、例えば「日本名刺」みたいなものがあった時には、それの距離はちょっと遠そうですよね。でも「活版印刷」だったらちょっと近そうですよね。

そういったようなかたちで、その文字の意味っていうのを捉えて、その意味の類似度をもって会社間、もしくは入力されたデータと会社間の類似度を図ろう、というのがこの単語埋め込みを用いた文章類似度です。

これには基本的な概念として「word2vec」と呼ばれる、最近わりと流行っているディープラーニングの手法があって、それを用います。それ以外にも、その単語から文章、もしくは短いセンテンスみたいなものに拡張する時にはいくつも手法があって。これはまだアカデミックの世界でも、確実なものは出てきていません。

例えば、先ほどの「日本印刷株式会社」があった時に、「日本」と「印刷」っていうのが、どれが近いかどれが遠いかそれぞれペアをとって測る「Word Mover’s Distance」というものがあったりします。それ以外にもさまざまな方法が考案されていて、いろんな種類のものがあります。

類似度を用いた事例

手法はちょっと省略させていただいて、結果を先に紹介したいと思います。成功した例ですと、「株式会社協和商工」という会社があります。

これは実は「総合商社株式会社協和商工」という名前に紐づいてほしい文字列なんですけれども、これに関して先ほどの文字列の類似度みたいなものを計算しても、「総合商社」というところがネックになって検知することができません。

一方で、この手法を用いると、「協和」といったものや「商工」といったものの意味を捉えて、その意味の近いものを持ってくるということができます。

また一方で、間違った例もありまして、例えば「株式会社ジョイライ」というのがあります。これは実際には「ジョイライフ」という会社の、末尾の一文字が欠損したものになっています。

こういった時には、この単語の類似度を用いた距離というのはなかなか機能しません。なぜかと言うと、今回の場合その文字列に対して形態素解析といったようなものを行っております。そうすると文字をある分割単位に分けてくれるんですけれども、その分割単位の1つが間違っていると、そこからなし崩し的に他のものも間違ってしまう。

例えば「有限会社ジョイライン」「ラーンジョイ」とか。なんかそれっぽいんだけどちょっと違う、みたいな文字列に、類似度として近いものとなってしまう、といったようなものがあります。

Encoder-Decoderを用いた文字のノイズ除去

最後は、ちょっとまだ実験的なもので外に出せる状態ではないんですけれども、文字列から文字列に変換してやろうと。間違った文字列があるんだったら、正しい文字列にディープラーニングを使って変換してやろう、というものがあります。

これがEncoder-Decoderを用いた文字のノイズ除去というもので、この構造自体はGoogle翻訳で使われていたり、あとはクックパッドさんがレシピの正規化の際に用いられていたりします。

これもなかなか癖のあるもので、例えば「経済産業省九州経済産業局地域経済部」というような会社名が入ってきた時に、これは経済産業省に紐づいてほしいんですけれども、上の例ですと正解をしている。

下の例ですと、足場川ダムうんたらかんたらってのがあった時に、これは国土交通省に紐づいてほしいんですけども、なぜかEncoder-Decoderを使うと防衛省っていうふうに間違ってしまってですね。ぜんぜん見当違いのものが出てくる。

非常に有望な技術であるのは確かなんですけれども、一方で間違いを犯してしまうってことも多分にあります。その間違いがなんで間違えたかということも、なかなか解明するのが難しい領域ですので、これはトライアンドエラーを繰り返しながらやっている状態となっております。

ニューラルネットを用いた姓名分割

次に事例の2つ目で、「ニューラルネットを用いた姓名分割」という話をしたいと思います。先ほどは名寄せを対象にしていました。ある名前が来た時に、それがどれに近いかといったものをやってましたけれども、これは与えられた文字列がどのような構造を持つかということを推定するタスクとなっています。

名前の分割なので、例えばカガ・ミサキさんっていう人がいたとします。これ実際にWikipediaに登録されていて……ごめんなさい(間違えました)。カガミ・サキ(加賀美早紀)さんですね(笑)。

これは2つバリエーションがあるよという事例なんですけれども。このような名前と苗字がくっついた文字列に対して、的確に苗字と名前がここですよ、といったような分割をしようというタスクになっています。

往々にしてOCRにより画像からテキストに起こした文字列っていうのは、スペースが削られていたり、なかなかその形を保ったまま構造化するのが非常に難しいタスクとなっておりまして。その後処理のところでいかに精度高く構造化をするかっていうのが、1つの課題となっております。

こういったことは、だいたいのものは人間ができますよね。機械にとっても辞書とかを作れば簡単にできるものではあるんですけれども、なかなか難しかったりもします。

そういった時に、これは学術的な用途でいろいろやってるんですけれども、先頭2文字で切ってみたりとか。あとは会社の辞書を使って、それがもっともらしいかどうかっていうのを判定するっていったことを使ったり。あとはディープラーニングの手法、Bidirectional LSTMという系列のモデルを使ったものを試したりしています。

3つの手法

軽く簡単に説明させていただくと、最初の頻度スコアですね。

「奥田」という苗字は非常にありふれた苗字で、一方で「奥」という苗字はちょっと少ないかもしれない。あとは「奥田裕樹」っていう時に、「奥田裕」まで含めると、そんな苗字の人はいないわけですね。

そうすると、そういった名前のもっともらしさ、頻度みたいなものを元にスコアを計算することによって、それをどれが1番分割として正しいかどうかっていうのを判別しようというのが、この頻度スコアになっています。

次に、ちょっと専門的な話になってしまって恐縮なんですけれども、Bidirectional LSTMというものがあります。これはニューラルネットの中の1つでして、系列のモデルを扱うものになっています。

例えば人の名前があった時に、人間は前から順にしか文字を見ないわけではないですよね。途中から見て「あ、これ名前っぽいな」みたいなことを考えたりですね。「ここらへんは区切りやすいな」みたいなことを考えるわけです。

そういった時に、今回このニューラルネットのモデルでは、全部の区切りのパターンを用意して、その中で正解は1つです、といったような学習をさせる。それによってその苗字と名前を区別しよう、といったようなことを試みています。

あとはもう1個、亜種みたいなものがあるんですけども。先ほどは全部の区切り位置を入力にした氏名っていうのを対象にしてましたけれども、実際、名前と苗字ってけっこう使われる文字とかの種類は異なりますよね。

「じゃあそれを別々に扱ってやろう」というのが、この複数系統を持つBidirectional LSTMといったものです。それぞれ苗字の入力、名前の入力があった時に、それをニューラルネットで変換していって、最後にそれが合ってますよ・間違ってますよといったような二値問題を解くニューラルネットを作成しています。

これ実際の結果なんですが、2つデータセットを用意してまして、左側のほうがよくある名前、右側のほうがあまりない珍しい名前。これは私がランダムに苗字と名前を取ってきて作成をしたデータセットになっています。

そうした時に、よくある名前は先ほどの頻度スコアを用いたものでも、Bidirectional LSTMというディープラーニングの手法を用いたものでも、両者とも99パーセント以上の精度を出しています。

一方で、珍しい名前は、頻度スコアを元にした計算ですと72パーセントぐらいしか精度が出ない。一方でディープラーニングの手法を使うと99パーセント以上の精度が出る、といったようなことがわかりました。

名前というのは、私たちは名刺を扱っているんですけれども、60代・70代・80代の人たちも名刺を持ってるかもしれない。一方で20代の人が名刺を作って持ってるかもしれない。そういったような幅広い年代の人に対して、正確な名前の分割をする必要があります。

そういった時にいちいち辞書を分けたりするよりも、こういった手法を用いてどのような年代に対しても正確に分割できる方法が求められています。

実応用への展開

これを実際に適用するといったお話を最後にしたいと思います。実際には、こんな簡単にうまくいくはずはありません。99パーセント出るかというと必ずしもそうではない。なぜかと言うと名前で入ってくる情報には非常に多種多様な、これもまた文字のゆらぎがあります。

例えば、名前しか書いていない、カタカナで書いてある、あとはミドルネームがある。または名前のあとにそれの英語表記が書いてあったり、所属が書いてあったり。これもいろんなバリエーションがあって、これは実問題を解く際には非常に障壁になります。

これに対しても私たちはいろいろ対応することによって、例えば分割前にこれらの中でノイズがあるかみたいなものを判別して、それを別の手法に回したりします。名前の言語判定、これもまた非常に問題なんですけれども、外国の方の名前が入ってくることもありますので。そういったような判定を通じて、精度を向上する施策をいろいろと試しています。

まとめとこれから

さて、ここまで2つ話をしてきましたけども、ちょっと最後にまとめを話したいと思います。

今回は、「私たちは科学をしているんだ」というような話を最初にさせていただきました。名刺のデータ化っていうのは、その名刺の裏にある個人や会社を正しく紐付けることです。これは生物学においては、名前をつけるということと同義かなと思っております。

そういった際に、サービスの価値を高めるために自然言語処理の活用をしていて、事例で紹介させていただきました。1つは名寄せの精度向上というところで、残り0.1パーセントの名寄せをいかに精度高く行うかといったことを目指しています。

2つ目はニューラルネットを用いた姓名分割ということで、文字列からいかにその構造を抽出するか、といったような話をさせていただきました。

最後にちょっとだけ話をさせてください。今うちの部署は、長期のインターンを募集しております。

こういったようなタスクを含めて、自然言語処理とかユーザーの属性推定とかに興味のある方がいらっしゃれば、ぜひとも声をかけていただければと思います。

もう1つ、こういったことは僕1人が全部行ってるものではありません。実際にはいろんなタスク、開発側で機能を開発するといったようなことや、精度を担保するための運用や、そういったものも含めていろんな人に支えていただきながら開発をしております。

こういったメンバーでやっておりますので、彼らに敬意を表しまして、この発表を終了したいと思います。どうもありがとうございました。