astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

データドリブンな企業とは何か~アスタミューゼ流宴会術~

こんにちは 今回、開発・デザイン以外の部署からゲスト寄稿させていただくことになりました亀久です。

自己紹介の前に、まだこのブログではアスタミューゼの組織体制がどうなっているのかを明らかにしたことがなかったと思うので、そのあたり簡単にご説明しますね(2017年9月現在)

アスタミューゼには、コーポレート本部を除くと大きく分けて3つの部署があります。

テクノロジーインテリジェンス(TI)部

『未来を創る2025年の成長領域』のコンセプト作りや、自社データベースを活用した技術情報の調査・分析業務などを行うアスタミューゼの頭脳集団

事業開発部

TI部が生み出すコンセプトやデータをもとにサービス/プロダクトを展開するビジネスサイドの部署。 新規事業開発支援/人材採用支援/知的情報Webプラットフォームの3事業に分かれています。 また、広報チームもこの部署です。

開発・デザイン部

上記を可能にするのが結局ここの人たち

私の所属は事業開発部ですが、特定の事業を専門に担当しているわけではありません。 TI部が生み出したコンセプトやデータをもとに、新サービスのプロトタイプとなるコンテンツを企画し、開発・デザイン部と連携して形にし、広報と連携して外部に発信していくという部署横断的な仕事をしています。

本記事では、日々の業務の中で、どのようなデータを活用してどういったコンテンツを開発しているのか、その一部をご紹介したいと思います。

アスタミューゼのイノベーションDBと『未来を創る2025年の成長領域』

まず、アスタミューゼがどのようなデータベースを持っているのか、下記の図をご覧ください。

f:id:astamuse:20170925115807p:plain

世界80ヵ国の新事業/新技術/新製品と投資情報をイノベーションDBとして保有しており、技術データが約8000万件、クラウドファンディングをはじめとするCtoCデータが約7200万件、企業データが約730万社、グラントデータが約300万テーマに上ります。

たしかに膨大なデータではあるのですが、アスタミューゼの「秘伝のたれ」は、むしろこちらの『未来を創る2025年の成長領域』のほうだったりします。

これらは、今後特に有望と思われる事業の指針となる市場群で、TI部が各種データおよび国内外の国際会議やシンポジウム・展示会等の情報、並びに独自のネットワークによる口コミ情報等を結集・分析し、策定しています。

アスタミューゼでは、膨大なデータと投資情報をこの『未来を創る2025年の成長領域』に沿って分類することで、企業や個人が未来を把握するお手伝いをしています。

それではこのイノベーションDBと『未来を創る2025年の成長領域』を活用したコンテンツ例をご紹介します。

(コンテンツ例1)AI分野の研究テーマ別日米比較

下の2つのグラフは、日米のAI分野における研究テーマを「どのような用途で研究しているか」という切り口で分析したものです。

日本の文部科学省による科学研究費助成事業(科研費)と、アメリカ国立科学財団 (National Science Foundation; NSF)から交付される競争的研究資金プログラムに採択された研究テーマから、独自の検索定義によりAI分野における研究テーマを抽出して用途別に分類しています。

f:id:astamuse:20170925115951p:plain

f:id:astamuse:20170925120038p:plain

ざっくり言うと、日本よりもアメリカのほうが用途明確で実践的な研究が多い、ということを示すデータです。
集計方法などの詳細についてはこちらの記事をご参照ください。

AI分野の研究テーマ日米比較 「医療・ヘルスケア」はアメリカがリード、日本は「生産技術」に注力

グラントの次は、人材採用に関するデータ活用の例です。

(コンテンツ例2)成長領域別の求人倍率推移

アスタミューゼでは『未来を創る2025年の成長領域』に沿って希少人材の採用支援サイト『転職ナビ』を約400種類運営しており、有望成長市場の変動に伴って新サイトの追加や入れ替えを行っています。

ちなみに最近リリースしたサイトには、このようなものがあります。

f:id:astamuse:20170925120246j:plain

防衛技術転職ナビ

f:id:astamuse:20170925120347j:plain

金融システム・Fintech転職ナビ

こういったサイトが約400あるわけですが、これらの求人票データや登録者データを分析して成長領域別の求人倍率推移を出してみました。

f:id:astamuse:20170925120711j:plain

ざっくり言うと、成長領域における希少人材の求人倍率(17年5月時点)は最低の「農業・食品工業」領域で37.47倍、最高の「エレクトロニクス」で121.69倍(一般職業紹介の求人倍率は同時点で1.49倍)と、希少人材の希少ぶりを示すデータです。 集計方法などの詳細や、アスタミューゼの採用支援サービスについてはこちらの記事をご参照ください。

400の転職ナビで「希少人材」を採用|アスタミューゼが仕掛ける成長戦略とは?(HR NOTE)

それでは最後にもうひとつ、とあるデータを見ていただきたいと思います。

(コンテンツ例3)牽制マトリクス

こちらの表は、社内では「牽制マトリクス」と呼ばれているものです。

f:id:astamuse:20170925123427p:plain

これは特許の「牽制」情報から、自社技術を活かせる新たな領域を見つけるためのもので、縦軸に自社の技術、横軸に『未来を創る2025年の成長領域』の有望成長市場群が並べられています。 そのロジックについては当ブログの過去記事が詳しいのでよろしければご参照ください。

さて、この「牽制マトリクス」ですが、「企業」ではなく「個人」の目線で見たとき、もうひとつの側面が浮かび上がってきます。

技術やアイデアといったものは本質的に「個人」が生み出すもので、すべての技術やアイデアは「個人」に紐づいています。

つまり、この「牽制マトリクス」上にある特許/技術を持つ「個人」は、該当する有望成長市場で活躍できる可能性が高い、ということでもあるのです。

「企業」が成長領域のベンチャー企業に投資するように、「個人」もまた自分という資本を成長領域に投入するようになるのではないか、とか。

「企業」と「個人」が同じ成長領域に投資しようとするとき、両者のアイデンティティが限りなく近づく瞬間があるのではないか、とか。

そういったことを考えながら今日もこつこつSQLを叩いています。
現場からは以上です。それでは!

デザインの良し悪しを語るのに必要な「分解」について【書体編】

前置き(長い)

先日、というか結構まえの話になるのですが、とあるSNSを閲覧していたところ「明朝体で喋る人が好きなのだけれど大体の人がゴシック体で会話をしておr…(以下省略)」といった内容を発信している方をお見かけました。
こちらの投稿は「その感じ、とてもよくわかります」と言う分かる派と「明朝体やゴシック体といったものは文字として表されるものにも関わらず、それを用いて喋るとは一体どういうことなのか?」と言った分からない派が発生し、書体について様々な意見が投じられていたようです。
しかし「分かる派」の方々でも具体的な説明を求められると、「そいつはなかなか難しい」という様子で双方の理解は平行線を辿り、霧散、といった具合です。

筆者はいちおうデザイン的なそれを生業としており、先の投稿にあったような「明朝体」「ゴシック体」という類のものを意識する時間が非デザイナーの人よりは相対的に多いような気が何となく、しなくもないかな、と感じています。 そういった事情もあり「明朝体で話す感じ」については一定の理解が可能であるのと同時に、「意味がわからない」とおっしゃる方の言い分も確かによく分かります。 なぜならこういったやり取りは書体に限ったことではなく、主にデザイン界隈、すなわち「意匠」について語られる時によく見かける風景で、昨日今日に始まったことではないからです。

例えて言うなら、ある意匠(デザイン)を見て「うわぁ、これめっちゃイケてる、最先端、それでいてダウナー」的な感想を持ったとしても他の人が「全くそうは思わない、なぜそう感じるのか説明しろ」と言われて具体的な説明ができなければ先ほどの事例と同じことで、お互いの意見はいつまでたっても平行線、一生お互いの良いと思った素敵なデザインについて理解しあえないままで終わることになり、とても悲しい、的なことになりかねない。

とまあ極端な例ですけど、でもデザインが醸し出すイメージ・印象を具体的な言葉に変換して伝えることはそんなに難解なことなのか?といったら案外そうでもないハズです。 それはデザインされたものを「分解する」ことで誰でも簡単にできることだと思います。

ひっじょーに長くなりましたが、取りあえずそういうことで今回はデザインを「分解する」的なものが何なのかについて、「書体」を例に考えていきたいと思います。

基礎を知る

まず、はじめに分解しようと思う要素の基礎を確認する必要があります。 筆者自身がよく行う事ですが、既に知っている事であっても分解していこうと要素については調べ直すようにしています。 知っていると思っていた事柄も過大解釈していたり、思い違いをしていたり、偏った見方をしていたり、という場合も決してゼロではありません。 基本的には自分の知識や記憶をあてにしない、というスタンスでいることが大事なことかもしれません。

ということで、まずは書体の基本をざっと確認していきます。

書体の基本

書体とフォント

書体の英訳がフォントと考えている人もいるため混同されがちですが、厳密には違います。

書体:統一されたデザインを持つ文字の集まり
フォント:書体をディスプレイ表示や印刷などで使えるようにデータ化したもの

このような違いがあるものの実際には「書体」のことを指すときにも「フォント」と言いがちですし、仕事以外の場ではその違いを意識して使うことはあまりないかもしれません。 ちなみに書体の英訳として相当するのはtypefaceらしいです。

和文書体と欧文書体

そして「書体」と一口に言っても世界には数え切れないほどの、ありとあらゆる種類が存在しています。 すべてを確認するのはこの場ではムリな気がする。 なので理解しやすいように大きく2つに分けてみるとまずは「和文書体」と「欧文書体」に大別することができます。 読んで字のごとくですが、

  • 和文書体:日本語(ひらがな/カタカナ/漢字/その他)をデザインした書体

  • 欧文書体:アルファベット表記の文字をデザインした書体

簡単に説明するとこのようになります。

明朝体とゴシック体

さらに和文書体も大きく2つの種類に分けることができるのですが、それが先述した「明朝体」と「ゴシック体」です。 これらは馴染みがある書体ですよね。 それぞれの特徴は

  • 明朝体:縦の線は太く、横の線は細くデザインされており、筆で書いたような「うろこ(※)」「はね」「はらい」などもデザインされた書体

  • ゴシック体:線の太さがほぼ均等で直線的にデザインされた書体

(※)うろこ:線の右端、曲がり角の右肩につけられる三角形のこと。毛筆で書いた文字にある「押さえ」。

f:id:astamuse:20170920112706p:plain

セリフ体とサンセリフ体

また、欧文書体も「セリフ体」と「サンセリフ体」の2つに大別できます。

  • セリフ体:縦線が細く、セリフ(※)をもつ書体。欧文書体の中でもっともスタンダード。

  • サンセリフ体:すべての線の太さがほぼ均等で、セリフをもたない書体

(※)セリフ:明朝体でいう「うろこ」と同じ(ような)もの

f:id:astamuse:20170920113005p:plain

こうやって比べてみると、和文書体も欧文書体も同じような大別の仕方で、「あしらい」なども非常に似ていることがわかります。

と、ここまでの解説は書籍やwebなどにももっと詳しく解説されていますのでもっと知りたい方は自力で調べて下さい。

「書体」とはいったい何なのか(「分解」的なことの実践)

それでは「書体」がどういったものか大まかにわかったところで、実践です。

書体」とは上記の『書体の基本』にも書いたように【統一されたデザインを持つ文字の集まり】です。 ではその「文字」とは何か? 端的に言ってしまえば「言葉/言語」を表す「図形」と言い換えられます。

ではその「図形」は何なのか? それは「点と線」で構成された形です。

つまり、人はある特定の「点と線」の重なりを「文字」と認識しているわけです。

ではここで、2つの線を見比べてください。

f:id:astamuse:20170920113028p:plain

「力強い線」はどちらで「繊細な線」はどちらでしょう?
通常、左の線を力強く、右の線を繊細と感じるのではないでしょうか。
このように、人は「線」の太さ・強弱に対して共通する印象・イメージを持っていると言えます。

では

  • 「線(と点)」の重なりを「文字」を認識していて

  • その「線」の強弱に特定の共通するイメージを持っている

ということは 持ってもらいたい印象・イメージを、線に強弱をつけることによってコントロールされた「文字」が「書体」ということになります。

便宜的に線の強弱と書きましたが、もちろんそれだけではありません。 「文字」を織り成す線には直線もあれば曲線もあり、また途中で曲げて角をつけることもあれば、その角度の付け方にもイメージが宿ります。
つまりは人が共通で持ち得る「あしらい」に対するイメージを積み重ねることよって、「書体」に「雰囲気」を持たせているのです。

例:ゴシック体

上記のことを前提として、「ゴシック体」の持っている雰囲気的なそれを例として書き出しておきたいと思います。

ゴシック体のイメージ :強い、重さ、頑健 f:id:astamuse:20170920115656p:plain なぜそういうイメージを持つか?:濃さは密度を連想させ、塗りの部分が多いため字が重く見える。また、角張っていてゴツゴツとしている所に男性的な印象を持つ。輪郭もはっきりとしているので、擬人化するとハキハキと大きな声でしゃべる男性が想像される。

(もう少し例を出しておきたいところですが、体力の限界なので終わります)

このように細かく分けて考えていくことで、「これめっちゃイケてる」と思った時に説明の手がかりになるはずです(多分)。

参考書籍:タイポグラフィの基本ルール-プロに学ぶ、一生枯れない永久不滅テクニック-[デザインラボ]

タイポグラフィの基本ルール -プロに学ぶ、一生枯れない永久不滅テクニック-[デザインラボ]

タイポグラフィの基本ルール -プロに学ぶ、一生枯れない永久不滅テクニック-[デザインラボ]

あと【書体編】と明記してありますが続きものというワケではないのでこれで終わるかもわからないなぁ…と 自分のプレッシャーにならない程度にゆるいペースでまとめて逝きたいです。

書体について教えてくれる人が居たら弊社にお越し下さいませ。

CoreNLP を使ってみる(1)

山縣です。

 

今回は 自然言語処理ツールである Stanford CoreNLPについて書きたいと思います。

Stanford CoreNLPとは

Stanford CoreNLP は自然言語処理ツールのひとつです。スタンフォード大学がオープンソース(GPL3) で公開しています。 英語、中国語など主要な言語をサポートしています。が残念ながら日本語は対応していません。

日本語以外の自然言語処理ツールについては先日、白木が Polyglot について記事を書いていましたが、こちらは Python 用です。私は Scala で書くことが多いので、Java/Scala で使えるものとして CoreNLP を使っています。

CoreNLP を使うには CLI として呼び出す方法、サーバとして起動して呼び出す方法、プログラムからライブラリとして使用する方法があります。

今回は CLI とサーバとして使う方法について解説したいと思います。

CLI として使ってみる

インストール

Windows10 の bash on windows 上にインストールしてみました。

CoreNLP は Java で作られていますのでJavaの実行環境が必要です。Java のバージョンは Java8 になります。

CoreNLPのインストールは、まずDownload | Stanford CoreNLP よりファイルをダウンロードします。

この記事を書いた時点でCoreNLPのバージョンは 3.8.0 です。

"Download CoreNLP 3.8.0" ボタンを押して、本体をダウンロードします。 ダウンロードした、stanford-corenlp-full-YYYY-MM-DD.zip を展開します。

$ unzip stanford-corenlp-full-2017-06-09.zip
$ cd stanford-corenlp-full-2017-06-09

次に各言語固有の モデルデータ(JARファイル) をダウンロードします。今回は英語を使います。本体と同じページに各言語用のモデルデータがあるので、そちらから"English" を選び英語用のモデルデータ(stanford-english-corenlp-2017-06-09-models.jar) をダウンロードして本体のディレクトリに置きます。

なお英語で使用する場合は、実際には追加のモデルデータを取得しなくても大方の機能が動くようです。本体に含まれる stanford-corenlp-3.8.0-models.jar に基本的なモデルデータが含まれているようです。

インタラクティブに使う

とりあえずこれでセットアップが完了したので、試しに実行してみます。 付属している corenlp.sh を使ってCoreNLP を起動します。

$ ./corenlp.sh -annotators tokenize,ssplit,pos,lemma,ner
java -mx5g -cp "./*" edu.stanford.nlp.pipeline.StanfordCoreNLP -annotators tokenize,ssplit,pos,lemma,ner
[main] INFO edu.stanford.nlp.pipeline.StanfordCoreNLP - Adding annotator tokenize
...

Entering interactive shell. Type q RETURN or EOF to quit.
NLP>

入力ファイルを指定しなかった場合、インタラクティブシェルが立ち上がるので、ここに処理したい文章を入れると結果が返ります。

NLP> How can I get to Tokyo station? I need to get on the bullet train at that station.

Sentence #1 (8 tokens):
How can I get to Tokyo station?
[Text=How CharacterOffsetBegin=0 CharacterOffsetEnd=3 PartOfSpeech=WRB Lemma=how NamedEntityTag=O]
[Text=can CharacterOffsetBegin=4 CharacterOffsetEnd=7 PartOfSpeech=MD Lemma=can NamedEntityTag=O]
[Text=I CharacterOffsetBegin=8 CharacterOffsetEnd=9 PartOfSpeech=PRP Lemma=I NamedEntityTag=O]
[Text=get CharacterOffsetBegin=10 CharacterOffsetEnd=13 PartOfSpeech=VB Lemma=get NamedEntityTag=O]
[Text=to CharacterOffsetBegin=14 CharacterOffsetEnd=16 PartOfSpeech=TO Lemma=to NamedEntityTag=O]
[Text=Tokyo CharacterOffsetBegin=17 CharacterOffsetEnd=22 PartOfSpeech=NNP Lemma=Tokyo NamedEntityTag=LOCATION]
[Text=station CharacterOffsetBegin=23 CharacterOffsetEnd=30 PartOfSpeech=NN Lemma=station NamedEntityTag=O]
[Text=? CharacterOffsetBegin=30 CharacterOffsetEnd=31 PartOfSpeech=. Lemma=? NamedEntityTag=O]
Sentence #2 (12 tokens):
I need to get on the bullet train at that station.
[Text=I CharacterOffsetBegin=32 CharacterOffsetEnd=33 PartOfSpeech=PRP Lemma=I NamedEntityTag=O]
[Text=need CharacterOffsetBegin=34 CharacterOffsetEnd=38 PartOfSpeech=VBP Lemma=need NamedEntityTag=O]
[Text=to CharacterOffsetBegin=39 CharacterOffsetEnd=41 PartOfSpeech=TO Lemma=to NamedEntityTag=O]
[Text=get CharacterOffsetBegin=42 CharacterOffsetEnd=45 PartOfSpeech=VB Lemma=get NamedEntityTag=O]
[Text=on CharacterOffsetBegin=46 CharacterOffsetEnd=48 PartOfSpeech=IN Lemma=on NamedEntityTag=O]
[Text=the CharacterOffsetBegin=49 CharacterOffsetEnd=52 PartOfSpeech=DT Lemma=the NamedEntityTag=O]
[Text=bullet CharacterOffsetBegin=53 CharacterOffsetEnd=59 PartOfSpeech=NN Lemma=bullet NamedEntityTag=O]
[Text=train CharacterOffsetBegin=60 CharacterOffsetEnd=65 PartOfSpeech=NN Lemma=train NamedEntityTag=O]
[Text=at CharacterOffsetBegin=66 CharacterOffsetEnd=68 PartOfSpeech=IN Lemma=at NamedEntityTag=O]
[Text=that CharacterOffsetBegin=69 CharacterOffsetEnd=73 PartOfSpeech=DT Lemma=that NamedEntityTag=O]
[Text=station CharacterOffsetBegin=74 CharacterOffsetEnd=81 PartOfSpeech=NN Lemma=station NamedEntityTag=O]
[Text=. CharacterOffsetBegin=81 CharacterOffsetEnd=82 PartOfSpeech=. Lemma=. NamedEntityTag=O]
NLP>

入力したテキストを二つのSentenceに分割したうえで、各トークンについての解析結果を表示しています。

上記の出力形式はデフォルトの 'text' というhuman readable なフォーマットになっています。

表示の意味はText がそのトークン、CharacterOffsetBegin/End がテキストの中での位置を、 PartOfSpeech が品詞を、Lemmaがレンマを NamedEntityTag が固有表現を表しています。

アノテータ

CoreNLPに処理させる機能(アノテータ)は立ち上げ時に -annotators オプションでカンマ区切りで指定しています。今回は "tokenize,ssplit,pos,lemma,ner" を指定しています。

tokenize はテキストをトークン(単語)に分ける処理を, ssplit はトークン群を文に分割する処理を、pos(part of speech) は品詞の判別、lemmaはレンマ化, ner(named entity recognition) は固有表現抽出を行います。

使用できるアノテータの一覧は Annotators | Stanford CoreNLP にあります。

またアノテータには依存関係があり、依存しているものを先に指定する必要があります。たとえば ssplit は tokenize に依存しているので tokenizeを先に(左に)指定する必要があります。また lemma は tokenize,ssplit,pos に依存しています。各アノテータの依存関係は Annotator dependencies | Stanford CoreNLP に記載されています。

posで出力されるタグ記号の一覧はこちらのタグ一覧が参考になるようです。

ner では、名称(PERSON, LOCATION, ORGANIZATION, MISC)、数字(MONEY, NUMBER, ORDINAL, PERCENT)、時間(DATE, TIME, DURATION, SET)を認識することができます。

Ieyasu Tokugawa was the founder of Edo shogunate. He lived to be 73 years old. He died on January 31,1543.

上記のテキストのNERを見ると以下のような結果になりました。 (見やすいように必要な情報だけに加工してあります)

Ieyasu PERSON
Tokugawa  PERSON
...
Edo O
shogunate O
...
73 DURATION
years DURATION
old DURATION
...
January DATE
31,1543 DATE

上記のように "Ieyasu Tokugawa" をPERSON, "73 years old" をDURATION, "January 31,1543" を DATE と認識できています。一方 "Edo shogunate" は認識できませんでした。

入力ファイルを指定する

先ほどまではインタラクティブにテキストを入力していましたが、 入力ファイルを指定することでバッチ的に処理をすることが可能です。

$ cat input.txt
Stanford University is located in California. It is a great university, founded in 1891.

$ ./corenlp.sh -annotators tokenize,ssplit,pos,lemma,ner -file ./input.txt

-file で入力ファイルを指定します。出力形式を指定しない場合 xml がデフォルトになります。

$ cat input.txt.xml
...
<root>
  <document>
    <sentences>
      <sentence id="1">
        <tokens>
          <token id="1">
            <word>Stanford</word>
            <lemma>Stanford</lemma>
            <CharacterOffsetBegin>0</CharacterOffsetBegin>
            <CharacterOffsetEnd>8</CharacterOffsetEnd>
            <POS>NNP</POS>
            <NER>ORGANIZATION</NER>
          </token>
          <token id="2">

出力ファイル名は <入力ファイル名>.xml になります。

-filelist オプションでファイルリストを指定することで複数のファイルを一括して処理することもできます。 CoreNLP CLI の起動は Java であることやモデルデータのロードに時間がかかるので多数のフィルを処理するときは -filelist で一括して処理したほうが効率的だと思います。

出力フォーマットを指定する

デフォルトの出力フォーマットを変更するには -outputFormat を指定します。 指定できるフォーマットは text, json, xml, conll, conllu, serialized です。指定するフォーマットによって出力ファイルの拡張子が変わります。 詳細は Output options で確認してください。

プロパティファイル

今まで corenlp.sh 実行時に引数でパラメータを指定していましたが、プロパティファイルを用意することでパラメータを指定することが出来ます。

$ cat my.properties
annotators = tokenize,ssplit,pos,lemma,ner,parse,mention,coref
outputExtension = .output
outputFormat = text
file = test.txt

$ cat test.txt
I bought an apple at the supermaket.
I am going to eat it later.

上記のようなプロパティファイルと入力ファイルを用意して実行します。

$ ./corenlp.sh -props ./my.properties
java -mx5g -cp "./*" edu.stanford.nlp.pipeline.StanfordCoreNLP -props ./my.properties
[main] INFO edu.stanford.nlp.pipeline.StanfordCoreNLP - Adding annotator tokenize
...

$ cat test.txt.output
Sentence #1 (8 tokens):
I bought an apple at the supermaket.
[Text=I CharacterOffsetBegin=0 CharacterOffsetEnd=1 PartOfSpeech=PRP Lemma=I NamedEntityTag=O]
...
Coreference set:
        (2,6,[6,7]) -> (1,4,[3,5]), that is: "it" -> "an apple"
Coreference set:
        (2,1,[1,2]) -> (1,1,[1,2]), that is: "I" -> "I"

test.txt.output に解析結果が出力されました。coref アノテータを指定したので共参照の解析結果が表示され、 2つ目の文の 'it' が 1つ目の文の 'an apple' を指していることなどが解析できています。

なお、プロパティファイルを指定しなかった場合、CoreNLP はclasspath 上の StanfordCoreNLP.properties を、それが無ければ .jar に含まれるedu/stanford/nlp/pipeline/StanfordCoreNLP.properties を読み込んでいます。

逆に言えば -props で指定してしまうとデフォルトの StanfordCoreNLP.properties が読み込まれなくなります。 このjar に組み込まれている edu/stanford/nlp/pipeline/StanfordCoreNLP.properties の中を確認してみると

$ less edu/stanford/nlp/pipeline/StanfordCoreNLP.properties
annotators = tokenize, ssplit, pos, lemma, ner, depparse, mention, coref

tokenize.language = en
...
#pos.model = /u/nlp/data/pos-tagger/wsj3t0-18-left3words/left3words-distsim-wsj-0-18.tagger
...
#ner.model = ...
#ner.model.3class = /u/nlp/data/ner/goodClassifiers/all.3class.distsim.crf.ser.gz

上記のように annotators と tokenize.language 以外のモデルデータの指定などはすべてコメントになっており、デフォルト値が呼ばれているだけだとわかります。 したがって -props で自前のプロパティファイルでモデルデータの指定をしなくても挙動は変わりません。

一方他の言語の場合は違ってきます。例えばドイツ語の言語モデルに含まれている StanfordCoreNLP-german.properties にはドイツ語の解析に必要なモデルデータの指定等が記載されています。

$ cat StanfordCoreNLP-german.properties
annotators = tokenize, ssplit, pos, ner, parse

tokenize.language = de

pos.model = edu/stanford/nlp/models/pos-tagger/german/german-hgc.tagger

ner.model = edu/stanford/nlp/models/ner/german.conll.hgc_175m_600.crf.ser.gz
ner.applyNumericClassifiers = false
ner.useSUTime = false

parse.model = edu/stanford/nlp/models/lexparser/germanFactored.ser.gz
...

したがって英語以外の言語で自前のプロパティファイルを使いたい場合はモデルデータに含まれるデフォルトのプロパティファイルを抽出して、そこに記載していく必要があります。

サーバーとして使用

CoreNLP はサーバとして起動して Web API 経由で使用することもできます。

java -mx5g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer
[main] INFO CoreNLP - --- StanfordCoreNLPServer#main() called ---
...
[main] INFO CoreNLP -     Threads: 8
[main] INFO CoreNLP - Starting server...
[main] INFO CoreNLP - StanfordCoreNLPServer listening at /0:0:0:0:0:0:0:0:9000

上記のように tcp 9000 でサーバが立ち上がります。

以下のようなクエリを投げることで、CLI と同じようにテキストの解析が可能です。

$ wget --post-data 'I bought an apple at the supermaket. I am going to eat it later.' 'localhost:9000/?properties={"annotators":"tokenize,ssp
lit,pos,lemma,ner,parse,mention,coref","outputFormat":"text"}' -O -
...
             Sentence #1 (8 tokens):
I bought an apple at the supermaket.
[Text=I CharacterOffsetBegin=0 CharacterOffsetEnd=1 PartOfSpeech=PRP Lemma=I NamedEntityTag=O]
...
Coreference set:
        (2,6,[6,7]) -> (1,4,[3,5]), that is: "it" -> "an apple"
Coreference set:
        (2,1,[1,2]) -> (1,1,[1,2]), that is: "I" -> "I"

Java以外の言語からの利用

CoreNLPをサーバとして起動すると http 経由で呼び出せるので、Java系以外の言語からも容易に呼び出すことができます。CoreNLP では Web API の Java 用クライアントが提供されていますが、それ以外に様々な言語のバインディングが公開されています。 CoreNLP のこのサイトではそのような言語やパッケージの一覧をリストアップしています。 Python, Ruby, JavaScriptなど多くのメジャー言語用のライブラリが公開されているので、用途に合うものを利用することが出来そうです。

試しに Python 用のライブラリである py-corenlp を使ってみました。

$ sudo pip install pycorenlp
...
  Downloading pycorenlp-0.3.0.tar.gz
...
Installing collected packages: pycorenlp
  Running setup.py install for pycorenlp ... done
Successfully installed pycorenlp-0.3.0

pip でインストールして以下のようなスクリプトを試してみました。

$ cat test_pycorenlp.py
#!/usr/bin/env python

from pycorenlp import StanfordCoreNLP

nlp = StanfordCoreNLP('http://localhost:9000')

text = 'I bought an apple at the supermaket. I am going to eat it later.'

output = nlp.annotate(text, properties={
    'annotators': 'tokenize,ssplit,pos,lemma,ner,parse,mention,coref',
    'outputFormat': 'text'
})

print(output)

実行してみます。

$ ./test_pycorenlp.py
Sentence #1 (8 tokens):
I bought an apple at the supermaket.
[Text=I CharacterOffsetBegin=0 CharacterOffsetEnd=1 PartOfSpeech=PRP Lemma=I NamedEntityTag=O]
[Text=bought CharacterOffsetBegin=2 CharacterOffsetEnd=8 PartOfSpeech=VBD Lemma=buy NamedEntityTag=O]
...
(ROOT
  (S
    (NP (PRP I))
    (VP (VBD bought)
      (NP (DT an) (NN apple))
      (PP (IN at)
        (NP (DT the) (NN supermaket))))
    (. .)))
...
Sentence #2 (8 tokens):
I am going to eat it later.
[Text=I CharacterOffsetBegin=37 CharacterOffsetEnd=38 PartOfSpeech=PRP Lemma=I NamedEntityTag=O]
[Text=am CharacterOffsetBegin=39 CharacterOffsetEnd=41 PartOfSpeech=VBP Lemma=be NamedEntityTag=O]
...
advmod(eat-5, later-7)
punct(going-3, .-8)

Coreference set:
        (2,6,[6,7]) -> (1,4,[3,5]), that is: "it" -> "an apple"
Coreference set:
        (2,1,[1,2]) -> (1,1,[1,2]), that is: "I" -> "I"

問題なく結果を返しています。

以上、CLI および WebAPI として使う方法を紹介してみました。 次回、本命の Java ライブラリを Scala/Spark で使う方法などについて書きたいと思います。

Copyright © astamuse company, ltd. all rights reserved.