形態素解析

日本語形態素解析のWebAPIには「Yahoo! JAPANが提供するテキスト解析WebAPI」やgooラボの「形態素解析API」、docomo Developer supportの「言語解析」などがある。しかし、これらは汎用辞書を利用しているため、病名を形態素として抽出できない。そこで、Webサービス「形態素解析ウェブアプリUniDic-MeCab」をスクレイピングして、形態素解析関数を作成した。

なぜ、このサービスを利用したかというと、このサービスには「複合名詞判定」というオプションがあり、名詞、接頭辞、接尾辞の連続を複合名詞と判定して切り出してくれるため、合成単語の性格の強い医学用語の抽出に適しているからである。たとえば、「本態性高血圧症」を形態素解析すると「本態」「性」「高」「血圧」「症」と分解されるが、このサービスだとそのまま「本態性高血圧症」となる。

入出力インターフェース解析

まず、ブラウザ(Chrome)の開発者ツールを用いて入出力インターフェースの解析を行った。下図は「交感神経の興奮を心臓に伝えるβ1受容体を遮断し、心臓の過剰な働きを抑えることにより、降圧作用、抗狭心症作用、抗不整脈作用、抗心不全作用を示します。通常、本態性高血圧症(軽症?中等症)、狭心症、心室性期外収縮および慢性心不全(虚血性心疾患または拡張型心筋症に基づく)、頻脈性心房細動の治療に用いられます。」というテキストを入力して複合名詞判定を有効にして形態素解析した際の結果である。

図1.形態素解析の入出力インターフェース解析

開発者ツール(画面右側)でリクエストメッセージを確認したところ以下のようなフォームデータをPOSTメッセージで送信していた。

const formData = {
  'sentaku': '複合名詞判定',
  'btnCheck': 'Check',
  'input': '交感神経の興奮を心臓に伝えるβ1受容体を遮断し、心臓の過剰な働きを抑えることにより、降圧作用、抗狭心症作用、抗不整脈作用、抗心不全作用を示します。通常、本態性高血圧症(軽症?中等症)、狭心症、心室性期外収縮および慢性心不全(虚血性心疾患または拡張型心筋症に基づく)、頻脈性心房細動の治療に用いられます。'
};

形態素解析結果は下図に示すように表形式で出力される。

図2.形態素解析結果

開発者ツールで表形式の部分のHTMLを確認すると次のようになっていた。

<table class="table table-striped" border="1">
      <thead>
        <tr><th>書字形</th><th>発音形</th><th>語彙素読み</th><th>語彙素</th><th>品詞</th><th>活用型</th><th>活用形</th><th>語形</th><th>書字形基本形</th><th>語種</th></tr>
      </thead>
      <tbody>
		
          <tr>
			
    			<td>交感神経</td>
			
    			<td>コーカンシンケー</td>
			
    			<td>コウカンシンケイ</td>
			
    			<td>交感神経</td>
			
    			<td>名詞-複合名詞</td>
			
    			<td></td>
			
    			<td></td>
			
    			<td>コーカンシンケー</td>
			
    			<td>交感神経</td>
			
    			<td>漢漢</td>
			
          </tr>
		
          <tr>
			
    			<td>の</td>
			
    			<td>ノ</td>
			
    			<td>ノ</td>
			
    			<td>の</td>
			
    			<td>助詞-格助詞</td>
			
    			<td></td>
			
    			<td></td>
			
    			<td>ノ</td>
			
    			<td>の</td>
			
    			<td>和</td>
			
          </tr>
		

GASプログラムの作成

上述したWebサービスをスクレイピングしてプログラムで利用可能なようにするため、次のような関数を作成した。

function queryUniDicMeCab(text) {
  const BASE_URL = 'http://www4414uj.sakura.ne.jp';
  const URL = BASE_URL + '/Yasanichi1/unicheck/';
  const formData = {
    'sentaku': '複合名詞判定',
    'btnCheck': 'Check',
    'input': text
  };
  const options = {
    'method' : 'post',
    'payload' : formData
  };  
  const response = UrlFetchApp.fetch(URL, options);
  const html = response.getContentText('UTF-8');

  const re_thead = /<thead>\s*<tr>(.*?)<\/tr>\s*<\/thead>/s;
  const array_thead = html.match(re_thead);
  const array_th = array_thead[1].match(/<th>(.*?)<\/th>/g);

  const re_tbody = /<tbody>(.*?)<\/tbody>/s;
  const array_tbody = html.match(re_tbody);
  const html_tbody = array_tbody[1];

  const re_tr = /<tr>(.*?)<\/tr>/sg;
  const results = [];
  while(array_tr = re_tr.exec(html_tbody)) {
    const array_td = array_tr[1].match(/<td>(.*?)<\/td>/g);
    const morpheme = {};
    for(let i = 0; i < array_td.length; i++) {
      const th = array_th[i].replace(/<.*?>/g,'').trim();
      const td = array_td[i].replace(/<.*?>/g,'').trim();
      morpheme[th] = td;
    }
    results.push(morpheme);
  }
  return results;
}

この関数を用いて以下のような形態素解析結果を得ることができた。

[
 {
  "書字形": "交感神経",
  "発音形": "コーカンシンケー",
  "語彙素読み": "コウカンシンケイ",
  "語彙素": "交感神経",
  "品詞": "名詞-複合名詞",
  "活用型": "",
  "活用形": "",
  "語形": "コーカンシンケー",
  "書字形基本形": "交感神経",
  "語種": "漢漢"
 },
 {
  "書字形": "の",
  "発音形": "ノ",
  "語彙素読み": "ノ",
  "語彙素": "の",
  "品詞": "助詞-格助詞",
  "活用型": "",
  "活用形": "",
  "語形": "ノ",
  "書字形基本形": "の",
  "語種": "和"
 },
 ・・・
]

最終的には入力テキスト中から病名を検出してICDコード等の属性を付与する機能を作成したい。そして、薬剤情報の作用と効果の文書から病名を検出して薬剤とそれに関連する病名の情報を知識として抽出したい。

形態素解析に標準病名を辞書として登録したユーザ辞書を利用できればたやすく実現できるが、冒頭にあげたWebAPIはユーザ辞書を指定する機能などない。自作するには公開Webサーバが必要だが、無料で利用するとなると難しい。よってここで書いたような方法を用いるしかなかった。

0 件のコメント:

コメントを投稿