Motive
【Qiita x COTOHA APIプレゼント企画】関連の投稿です。
COTOHA API で照応解析してもギブミーチョコレート出来ていない問題とは別のAPIを使ってみました。
今回は
固有表現抽出(/nlp/v1/ne)
APIです。
MeCabだったら固有名詞を学習をして辞書に登録しないと人物名が抽出できなかった気がします。あと、KNPは精度は良さそうなのですがパッケージ自体重いです。
また、形態素解析すると機械学習された分配器が優秀なのか品詞までは正確に出力されるのですが、文章の中で多く出て来る名詞を分類できていたかと言うとそうでもない気がします。
COTOHAではAPIだけで名詞の細かい分類をしてくれます。
どこまで固有名詞を抽出できるかを簡易的にトライするために、スポーツ記事から人物名・技名を出力してみました。
Environment
- Python 3.6.8
- COTOHA API (https://api.ce-cotoha.com/)
Dataset
東京スポーツ
選定基準としては住んでいる地域ではこのスポーツ新聞が発売されていないという高尚な理由です。
Method
前述の通り、
COTOHA API 固有抽出
https://api.ce-cotoha.com/contents/reference/apireference.html#parsing_io_part
を使っています。
選手(人物)はx["class"] == "PSN" and x["extended_class"] == ""
、技名はx["class"] == "ART" and x["extended_class"] in [ "Doctrine_Method_Other"]
で抽出しています。Doctrine_Method_Other
は(主義方式名_その他)という意味です。
名称 | 説明 |
---|---|
ORG | 組織名 |
PSN | 人名 |
LOC | 場所 |
ART | 固有物名 |
DAT | 日付表現 |
TIM | 時刻表現 |
NUM | 数値表現 |
MNY | 金額表現 |
PCT | 割合表現 |
OTH | その他 |
Development
Script
**スクリプトコード** (クリックするとコードが表示されます。)
import argparse
import requests
from bs4 import BeautifulSoup
import json
#--- この4つパラメータはPortalで取得 ---
PUBLISH_URL = "--- get your parameter ---"
CLIENT_ID = "--- get your parameter ---"
CLIENT_SECRET = "--- get your parameter ---"
BASE_URL = "--- get your parameter ---"
class COTOHA:
def __init__(self):
self._token = self._getAccessToken()
def _getAccessToken(self):
header = {"Content-Type": "application/json"}
contents = {
"grantType": "client_credentials",
"clientId": CLIENT_ID,
"clientSecret": CLIENT_SECRET
}
raw_res = requests.post(PUBLISH_URL, headers=header, json=contents)
response = raw_res.json()
return response["access_token"]
def compose(self, sentence):
header = {
"Authorization": "Bearer {}".format(self._token),
"Content-Type": "application/json"
}
contents = {
"sentence": sentence
}
raw_res = requests.post(
BASE_URL +
"nlp/v1/parse",
headers=header,
json=contents)
response = raw_res.json()
return response
def properNoun(self, sentence):
header = {
"Authorization": "Bearer {}".format(self._token),
"Content-Type": "application/json"
}
contents = {
"sentence": sentence
}
raw_res = requests.post(
BASE_URL +
"nlp/v1/ne",
headers=header,
json=contents)
response = raw_res.json()
return response
def keyword(self, sentence):
header = {
"Authorization": "Bearer {}".format(self._token),
"Content-Type": "application/json"
}
contents = {
"document": sentence
}
raw_res = requests.post(
BASE_URL +
"nlp/v1/keyword",
headers=header,
json=contents)
response = raw_res.json()
return response
def coreference(self, sentence):
header = {
"Authorization": "Bearer {}".format(self._token),
"Content-Type": "application/json"
}
contents = {
"document": sentence
}
raw_res = requests.post(
BASE_URL +
"nlp/v1/coreference",
headers=header,
json=contents)
response = raw_res.json()
return response
def extract_norn_list(_apiobj, contents, condition):
dst = []
for p in contents:
items = _apiobj.properNoun(p.text)["result"]
_raw = list(filter(condition, items))
# print(_raw)
# 略称は除く
for _p in _raw:
name = _p["form"]
_exist = False
for pname in dst:
if name in pname:
_exist = True
if not _exist:
dst.append(name)
return dst
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--url")
args = parser.parse_args()
#APIオブジェクトを作成
cotoha = COTOHA()
#URLから記事を取得(東京スポーツ仕様)
res = requests.get(args.url)
soup = BeautifulSoup(res.text, 'html.parser')
title_text = soup.find('title').get_text()
contents = soup.find('div', {"class": "detail-content"}).find_all("p")
#抽出条件
def is_person(x): return x["class"] == "PSN" and x["extended_class"] == ""
def is_attack(x): return x["class"] == "ART" and x["extended_class"] in [
"Doctrine_Method_Other"]
#選手を出力
print(extract_norn_list(cotoha, contents, is_person))
#技名を出力
print(extract_norn_list(cotoha, contents, is_attack))
if __name__ == "__main__":
main()
Command
python main.py --url https://www.tokyo-sports.co.jp/prores/ddt/1754700/
Consequence
2つの記事を使って実行します。
【新日1・5東京ドーム】みのる US王座防衛のモクスリー襲撃「誰にケンカ売ってんだ!」
dataset
新日本プロレスの年間最大興行「レッスルキングダム14」(5日、東京ドーム)で行われたIWGP・USヘビー級王座戦は、王者ジョン・モクスリー(34)がIWGPタッグ王者のジュース・ロビンソン(30)の挑戦を退け、初防衛に成功した。
前夜(4日)の東京ドーム大会では、モクスリーがランス・アーチャー(32)から王座を奪回。ジュースはデビッド・フィンレー(26)とのコンビでタッグ王座を獲得した。その翌日に新王者同士の決戦となったが、モクスリーは昨年6月にジュースから同王座を奪っており、前夜のリング上で決着をつけることを宣言していた。
序盤はジュースが快調に先制したものの、モクスリーは場外でイスを持ち出して背中に一撃。さらにはジュースの額にかみついた。WWE時代に“狂犬”として暴れ回った荒くれ者が、強引にペースを奪い返した。
ジュースは豪快なハイアングルパワーボムで反撃したが、王者は足4の字固めから鉄柱を使った4の字と意表を突いた攻撃を連発した。挑戦者は雪崩式ブレーンバスターからジャックハマーにジャーマン。モクスリーのデスライダー(ダブルアーム式DDT)をかわして、ラリアートでぶち抜いた。
だが、王者は乱打戦から強烈なランニングニーを一閃。ジュースのパルプフリクションを切り返して、DDTから必殺のデスライダーを炸裂させて12分48秒、3カウントを奪った。
試合後には入場テーマ曲が流れ、いきなり鈴木みのる(51)が登場。昨年12月8日の広島大会でモスクリーからデスライダーを見舞われており、険しい表情で怒りを隠せない。花道でジャージーを脱いで戦闘態勢に入ると、リング上で王者とエルボーを打ち合った。ド迫力のみのるは裸絞めからゴッチ式パイルドライバーでモクスリーをKOした。
みのるはマイクを握ると「誰にケンカ売ってんだ、このヤロー! オレはプロレスラーの鈴木みのるだ。こいつのケンカ、オレが買ってやる!」と宣戦布告。US王座を巡る“狂犬”対“性悪男”の抗争勃発で、危険な香りが漂ってきた。
みのるの話「誰にケンカ売ってんだ、おい。俺は、お前が俺の前に来るのを待ってたんだよ。ジョン・モクスリー…いや、ジョン・ボーイ、心してかかってこい。ぶち殺す」
ジュースの話「すべてはここで終わりだ。ジョン・モクスリーは今日も俺より強かった。また超えられなかった。今日のことを考えたのは昨日の試合が終わってから。それまでまったく今日の試合のことなんて考えていなかった」
output
['ジョン・モクスリー', 'ランス・アーチャー', 'デビッド・フィンレー', '鈴木みのる', 'ジョン・ボーイ']
['足4の字固め', '雪崩式', 'ジャックハマー', 'ラリアート', '裸絞め']
【新日1・4東京ドーム】内藤 逆転でIC王座奪回も「目的はこのベルトじゃない」
dataset
新日本プロレスの年間最大興行「レッスルキングダム14」(4日、東京ドーム)で行われたIWGPインターコンチネンタル(IC)選手権は、内藤哲也(37)が王者のジェイ・ホワイト(27)を撃破。王座を奪回するとともに、5日東京ドーム大会でIWGPヘビー級王者(オカダ・カズチカVS飯伏幸太の勝者)とのダブルタイトルマッチに駒を進めた。
昨年9月の神戸大会でジェイに敗れ、昨年2度目となるIC王座からの陥落。東京スポーツ新聞社制定「プロレス大賞」ではノミネート「0」の屈辱も味わった。しかし、大観衆は“制御不能男”の復活を待ち望んでいる。序盤から大・内藤コールで背中を押すと、ジェイには容赦ないブーイングを浴びせた。
内藤は場外でエプロンを使ったネックブリーカーを放って先制。ところが、ジェイのセコンドの外道が場外から内藤の足を引っ張りペースを乱す。王者は内藤の左ヒザに狙いを絞って攻め込んだ。内藤はコーナーからの飛びつきフランケンシュタイナーで反撃。相手に顔につばを吐きかけてから、串刺しの低空ドロップキックだ。
これでペースを握るかとみられたが、ジェイのDDTを食らって悶絶し、再び左ヒザを攻められた。場外にはバックドロップで投げ捨てられ、劣勢は変わらない。さらに裏足4の字固めでヒザを締め上げられた。
大ピンチの内藤は顔をゆがませながらロープブレーク。何とか脱出すると、逆襲の浴びせ蹴りだ。さらにスパインバスター、回転式DDT、雪崩式フランケンシュタイナー、グロリアの猛攻。レフェリーがアクシデントでダウンする隙に外道が乱入したが、急所打ちで撃退した。
勝負をかけた内藤は、コリエンド式デスティーノを連発。ジェイの必殺ブレードランナー(変型顔面砕き)を完全に防ぎ切ると、最後は渾身のデスティーノで3カウントを奪った。
33分54秒の大激闘に逆転勝利。昨年1月からIWGPとIC、2冠奪取の野望を掲げてきた“制御不能男”は、完全復活へ一世一代の大舞台に挑む。
【内藤の話】「今回の2連戦の目的はこのベルトを取ることじゃないから。お客様は『内藤おめでとう』って声かけてくれてうれしいよ。でも、トランキーロ。今回の目的ではないから、そこは。さあて、明日の対戦相手はどっちかな。俺の予定はオカダ。理想も、オカダ。さあ、どうかな」
【ジェイ・ホワイトの話】「アイツ(内藤)はどこに行った…。俺は残念ながらみんなが作り上げたストーリーの脇役の一人だったということだったんだな。みんな、ジェイ・ホワイトが負けるのを望んでいたはずだ。お前らが好きな内藤が勝ったんだぞ。なぜ笑わないんだ。新しい俺のデスティーノ…運命が明日から始まる」
output
['内藤哲也', 'ジェイ・ホワイト', 'オカダ・カズチカ', '飯伏幸太', 'デスティーノ...運命']
['ネックブリーカー', 'バックドロップ', '足4の字固め', 'スパインバスター']
Consideration
- 選手の名称は「デスティーノ...運命」以外主要メンバーは抽出ができている。一般的な人物名は問題なく分類できてそうです。
- 技名ですが、残念ながらCOTOHA APIの分類には出てこないです。何回かAPIからの出力で一番抽出できてそうな組み合わせだったのが
class:ART, extended_class:Doctrine_Method_Other
だったので出力してみたのですが、「ハイアングルパワーボム」「コリエンド式デスティーノ」あたりが対象外になってしまいます。2番目の条件としてclass:ART, extended_class:Product
も追加すると技名以外も抽出されるので100%は厳しかったです - スポーツ記事ではなく専門書であれば効力を発揮できるかもしれません。APIに下記のtypeのパラメータを付与することができるからです。(for Enterpriseユーザのみ、、、なので有料であれば利用可能です。)
param | name |
---|---|
IT | コンピュータ・情報・通信 |
automobile | 自動車 |
chemistry | 化学・石油工業 |
company | 企業 |
construction | 土木建築 |
economy | 経済・法令 |
energy | 電力・エネルギー |
institution | 機関・団体 |
machinery | 機械 |
medical | 医学 |
metal | 非鉄・金属 |
PostScript
人物名抽出の精度はいいと言ったのですが、なぜか最近引退した「獣神サンダー・ライガー」が正しく抽出されなかったです。「ART:固有物名」の分類になっていました。
これはタレント名鑑のスタッフに出動応援した方が良さそうでしょうか。
としてです。