Yahoo! Japan Developer Network : 日本語形態素解析サービスの利用

/*
 * Yahoo! Japan ディベロッパーネットワーク: テキスト解析:形態素解析サービスの利用
 * http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html
 * 2015.11.18
 */
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.xpath.*;

import java.util.ArrayList;

public class YahooMorph {
  private String appid;
  private final String path = "http://jlp.yahooapis.jp/MAService/V1/parse?";

  // 形態素 (morpheme)クラス
  public class Morpheme {
    private String surface;
    private String reading;
    private String pos;
    private String baseform;
    
    public Morpheme(String surface, String reading, String pos, String baseform){
      this.surface = surface;
      this.reading = reading;
      this.pos = pos;
      this.baseform = baseform;
    }
    
    // getter
    public String getSurface(){ return surface; }
    public String getReading(){ return reading; }
    public String getPos(){ return pos; }
    public String getBaseform(){ return baseform; }
  }
  
  public YahooMorph(String appid){
    this.appid = appid;
  }
  
  public ArrayList<Morpheme> analyse(String text){
    // 形態素を格納するリスト
    ArrayList<Morpheme> morph_list = new ArrayList<Morpheme>();
    
    try{
      // リクエスト URL およびその引数については下記を参照
      // http://developer.yahoo.co.jp/webapi/jlp/ma/v1/parse.html
      // (注)日本語文字列は予め URL encoding しなければならない。
      URL url = new URL(path + "appid=" + appid + "&results=ma&response=surface,reading,pos,baseform&sentence=" + URLEncoder.encode(text, "utf-8"));
      
      // Yahoo! Developer Web service とのコネクションを張る
      HttpURLConnection http = (HttpURLConnection)url.openConnection();
      http.setRequestMethod("GET"); // GET メソッドによるアクセス
      http.connect();
      
      // サーバから返される XML を処理するための document builder の設定
      InputStream input = url.openStream();
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(input);

      // XML の解析(parsing)に XPath を用いる。
      // XPath の解説は下記サイトが詳しい。
      // http://www.techscore.com/tech/XML/XPath/index.html
      XPathFactory factory = XPathFactory.newInstance();
      XPath xpath = factory.newXPath();
      
      // 表層形 (surface), 読み (reading), 品詞 (pos),基本形 (baseform)の取り出し
      NodeList surfaces = (NodeList)xpath.evaluate("//ma_result/word_list/word/surface/text()", doc, XPathConstants.NODESET);
      NodeList readings = (NodeList)xpath.evaluate("//ma_result/word_list/word/reading/text()", doc, XPathConstants.NODESET);
      NodeList poses = (NodeList)xpath.evaluate("//ma_result/word_list/word/pos/text()", doc, XPathConstants.NODESET);
      NodeList baseforms = (NodeList)xpath.evaluate("//ma_result/word_list/word/baseform/text()", doc, XPathConstants.NODESET);

      // デバッグ用の出力
      /*
      for(int i=0; i < surfaces.getLength(); i++){
        System.out.println(surfaces.item(i).getNodeValue());
      }
      
      for(int i=0; i < readings.getLength(); i++){
        System.out.println(readings.item(i).getNodeValue());
      }

      for(int i=0; i < poses.getLength(); i++){
        System.out.println(poses.item(i).getNodeValue());
      }

      for(int i=0; i < baseforms.getLength(); i++){
        System.out.println(baseforms.item(i).getNodeValue());
      }
      */

      // 各形態素の表層形 (surface), 読み (reading), 品詞 (pos),基本形 (baseform)を
      // 形態素解析リストへ格納
      for(int i=0; i < surfaces.getLength(); i++){
        morph_list.add(new Morpheme(surfaces.item(i).getNodeValue(),
            readings.item(i).getNodeValue(),
            poses.item(i).getNodeValue(),
            baseforms.item(i).getNodeValue()));
      }
      
      http.disconnect(); // コネクションの切断
      
    } catch(Exception e){
      System.out.println(e);
      System.exit(1);
    }
    
    return morph_list;
  }
  
  public static void main(String[] args) {
    // Application ID の取得方法は下記を参照:
    // http://developer.yahoo.co.jp/start/
    String appid = "xxxx";

    YahooMorph yahooMorph = new YahooMorph(appid);

    // 形態素解析(その1)
    String text = "明日,晴れることを願っている。";
    ArrayList<Morpheme> result = yahooMorph.analyse(text);
    System.out.println("=== Example 1 ===");
    for(int i=0; i < result.size(); i++){
      Morpheme m = result.get(i);
      System.out.println(m.getSurface()
          + "\t" + m.getReading()
          + "\t" + m.getPos()
          + "\t" + m.getBaseform());
    }

    // 形態素解析(その2)
    text = "JavaもC言語もどちらも大切でしょう。";
    result = yahooMorph.analyse(text);
    System.out.println("=== Example 2===");
    for(int i=0; i < result.size(); i++){
      Morpheme m = result.get(i);
      System.out.println(m.getSurface()
          + "\t" + m.getReading()
          + "\t" + m.getPos()
          + "\t" + m.getBaseform());
    }
  }
}