Slide 1

Slide 1 text

⾼精度名寄せシステムを⽀える テキスト処理 (の、ほんのさわり) ⽥野⼝⼤樹(@dproject21) 2017.11.14 golang.tokyo #10

Slide 2

Slide 2 text

あんただれよ? • ⽥野⼝ ⼤樹 (たのっち @dproject21) • ミーカンパニー株式会社所属 • Java + Agileな新宿⻄⼝のSIer → 某Webサービス企業 → 現職 • ⽣息域 • Akiba.go • アジャイル界隈 (Agile Japan 2015 公認レポーター) • ソフトウェアテスト界隈(WACATE、アジャイルテスト読書会) • 同⼈技術書界隈(DevLOVE Pub) • クリティカル・シンキング界隈(TOCfE Bootcamp) • Go⾔語歴 5ヶ⽉ • .NET → Java → Go

Slide 3

Slide 3 text

お仕事の内容 • ミーカンパニー株式会社 http://mecompany.me/ • オープンデータの医療機関データを加⼯して作り上げた医療・ 薬局・介護マスタデータ「SCUEL」を販売しています。 • 名寄せのためのデータクレンジングにGoを全⾯採⽤しています。 • Goを採⽤したことで、⾼精度の名寄せシステムを、⾼速で動作 させることができています。 • 名寄せシステムで使っている「テキスト処理の考え⽅」の⼀部 を LT という形で紹介します。

Slide 4

Slide 4 text

先ほどのセッションほとんど聞けてな かったけど… • reflectパッケージは遅いので、できる限り使わないのが吉 • JSONもキャッシュ(redis / memcached)するための シリアライズ/デシリアライズで使うには遅い。 ProtocolBufferやMessagePackが早いので、こちらを使おう。 • Goは正規表現が遅い。 簡単な正規表現は等価になるfunctionを作ったほうがいい。

Slide 5

Slide 5 text

今⽇のまとめ • stringsパッケージでの⽇本語テキスト処理には罠が多い。仕様 をきちんと確認しよう。 • いくつかの機能はutf8パッケージで代⽤できる。 • Githubからライブラリを拾ってくる場合、rune対応であるか確 認しよう。 • rune対応のfunctionが⾜りなければ作ろう • unicodeパッケージを活⽤しよう

Slide 6

Slide 6 text

rune⾮対応の標準ライブラリの罠 • stringsパッケージの strings.Index

Slide 7

Slide 7 text

rune⾮対応の標準ライブラリの罠 • stringsパッケージの strings.Index

Slide 8

Slide 8 text

rune⾮対応の標準ライブラリの罠 • stringsパッケージの strings.Index 3⽂字⽬(2番⽬)じゃないの?

Slide 9

Slide 9 text

rune⾮対応の標準ライブラリの罠 • stringsパッケージの strings.Index

Slide 10

Slide 10 text

rune⾮対応の標準ライブラリの罠 • stringsパッケージの strings.Index 欲しいのは バイト数じゃない ⽂字数なんだ

Slide 11

Slide 11 text

utf8パッケージで⼀部賄えるけど… • utf8パッケージを使う RuneCountInString、良く使います

Slide 12

Slide 12 text

utf8パッケージで⼀部賄えるけど… • utf8パッケージを使う

Slide 13

Slide 13 text

Githubでライブラリ拾う場合も注意 • とある処理をするためにGithubからライブラリを取得 • 実⾏してみたら想定していた結果と違う! • ソースコードを読んだらrune⾮対応 • rune対応の別ライブラリに変えました。

Slide 14

Slide 14 text

無ければ作ろう • stringsパッケージでruneに対応していない • utf8パッケージに対応する機能がない • Githubで出回っているライブラリでも⾒つからない • stringsパッケージのいくつかのfunctionは rune対応版を内製しています。

Slide 15

Slide 15 text

より便利なfunctionを作ろう • Goの正規表現は遅い。正規表現をfunctionに置き換えたい。 • unicodeパッケージが活躍する。 • [0-9] これ、unicode.IsDigitで代⽤できる。

Slide 16

Slide 16 text

より便利なfunctionを作ろう • Unicode.IsDigit

Slide 17

Slide 17 text

台⾵の前に作っていたのはココマデ

Slide 18

Slide 18 text

Unicodeとの格闘 • Unicode.IsDigitの仕様をもう⼀度確認

Slide 19

Slide 19 text

Unicodeとの格闘 • Unicode.IsDigit isExcludingLatinって何だ?

Slide 20

Slide 20 text

Unicodeとの格闘 • src/unicode/letter.go これ、[0-9]と等値ではない?

Slide 21

Slide 21 text

Unicodeとの格闘 • Playgroundで検証(LT開始の30分ほど前に検証しました) 全⾓の 1 もIsDigitでtrue判定される

Slide 22

Slide 22 text

よし! function作ろう!

Slide 23

Slide 23 text

内製functionのテストはどうしてる? • testify / assert でテスト書いています。 • 最初は愚直に testingパッケージの t.Error を使っていました。 • エラー時のメッセージを⾃分でつくるのは⼤変 • xUnitに慣れた⾝として、assertは欲しかった。 • テストコードの構成は、永和システムマネジメントさんの「時 を越えたプログラミングの道」を参考にしています。 • https://twop.agile.esm.co.jp/learning-go-lang-by-tdd- 8326723d9362

Slide 24

Slide 24 text

functionを作ろう • 半⾓英数字の仕様ってどうだっけ? https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

Slide 25

Slide 25 text

functionを作ろう • 半⾓の英数字だけtrueになるfunctionを作ろう

Slide 26

Slide 26 text

functionを作ろう • 半⾓の英数字だけtrueになるfunctionを作ろう

Slide 27

Slide 27 text

functionを作ろう • 実際は「前処理」で全⾓数字を変換しているから問題起きな かったんですけどね。

Slide 28

Slide 28 text

今⽇のまとめ • stringsパッケージでの⽇本語テキスト処理には 罠が多い。仕様をきちんと確認しよう。 • いくつかの機能はutf8パッケージで代⽤できる。 • Githubからライブラリを拾ってくる場合、 rune対応であるか確認しよう。 • rune対応のfunctionが⾜りなければ作ろう • unicodeパッケージを活⽤しようにも罠がある! 仕様をきちんと確認しよう! ←NEW!!!