としおの読書生活

田舎に住む社会人の読書記録を綴ります。 主に小説や新書の内容紹介と感想を書きます。 読書の他にもワイン、紅茶、パソコン関係などの趣味を詰め込んだブログにしたいです。

カテゴリ: 自然言語処理

4267000_s

自然言語処理関連のソフトを作る機会があり、最近のメジャーな日本語自然言語処理ライブラリとしてGiNZAというものがあるという話を聞いたので試しに使ってみました。


GiNZAとは


GiNZAとはリクルートが国立国語研究所との共同研究成果をもとに開発した日本語自然言語処理ライブ来です。

形態素解析器であるSudachiPyと機械学習部分であるspaCyを合わせたライブラリのようです。

特徴は従来のspaCyは日本語に対してはMeCabをバックエンドに形態素解析ができる程度でした。

しかし。GiNZAの登場により最先端の機械学習技術を用いた日本語自然言語処理が簡単にできるようになったようです。



GiNZAのインストール


今回は2021年9月現在GiNZAの最新バージョンであるGiNZA v5.0をインストールしていきます。

GiNZA v5はインストール時に解析モデルのパッケージを指定する必要があるようで、解析度重視の場合は以下のコマンドでインストールしましょう。

pip install -U ginza ja-ginza-electra

速度重視の場合は以下のコマンドでインストールしてください。

pip install -U ginza ja-ginza

両方使い分けたい場合は、両コマンドとも実行してください。

インストールができたら動作を確認してみましょう。

ginza
すもももももももものうち。

# text = すもももももももものうち。
1       すもも  すもも  NOUN    名詞-普通名詞-一般      _       3       nsubj   _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=スモモ|NE=B-OTHERS|ENE=B-Flora
2       も      も      ADP     助詞-係助詞     _       1       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=モ
3       もも    もも    NOUN    名詞-普通名詞-一般      _       5       nsubj   _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=モモ|NE=B-OTHERS|ENE=B-Animal_Part
4       も      も      ADP     助詞-係助詞     _       3       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=モ
5       もも    もも    NOUN    名詞-普通名詞-一般      _       7       nmod    _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=モモ|NE=B-OTHERS|ENE=B-Color_Other
6       の      の      ADP     助詞-格助詞     _       5       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=ノ
7       うち    うち    NOUN    名詞-普通名詞-副詞可能  _       0       root    _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=ROOT|NP_B|Reading=ウチ
8       。      。      PUNCT   補助記号-句点   _       7       punct   _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=。




PythonでGiNZAを操作する


インストールができたろころでPythonでGiNZAを操作していきましょう。

1.文境界解析


文境界解析は文章から文の境界を検出する処理です。

import spacy

nlp = spacy.load('ja_ginza_electra')
doc = nlp('銀座でランチをご一緒しましょう今度の日曜日はどうですか。')

# 文境界解析
for sent in doc.sents:
    print(sent)

銀座でランチをご一緒しましょう
今度の日曜日はどうですか。

"。"がなくても文の境界が判断できていますね。


2.形態素解析


形態素解析は文章を単語に分割すると同時に単語の品詞などを推測する処理です。

import spacy

nlp = spacy.load('ja_ginza_electra')
doc = nlp('銀座でランチをご一緒しましょう。')
for sent in doc.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, token.tag_, token.dep_, token.head.i)
    print('EOS')

0 銀座 銀座 PROPN 名詞-固有名詞-地名-一般 obl 5
1 で で ADP 助詞-格助詞 case 0
2 ランチ ランチ NOUN 名詞-普通名詞-一般 obj 5
3 を を ADP 助詞-格助詞 case 2
4 ご ご NOUN 接頭辞 compound 5
5 一緒 一緒 VERB 名詞-普通名詞-サ変可能 ROOT 5
6 し する AUX 動詞-非自立可能 aux 5
7 ましょう ます AUX 助動詞 aux 5
8 。 。 PUNCT 補助記号-句点 punct 5
EOS






3.係り受け解析


係り受け解析は単語間の関係を解析する処理です。

以下のサンプルは係り受け木をSVG形式で保存しています。

# -*- coding: utf-8 -*-
# 文境界解析

import spacy
from spacy import displacy
from pathlib import Path

nlp = spacy.load('ja_ginza_electra')
doc = nlp("銀座でランチをご一緒しましょう。")
for sent in doc.sents:
    svg = displacy.render(sentstyle="dep")
    file_name = "kakari.svg"
    output_path = Path("./" + file_name)
    output_path.open("w"encoding="utf-8").write(svg)

キャプチャ


4.固有表現抽出


固有表現抽出は国名、人名などの固有表現を抽出する処理です。

import spacy
from spacy import displacy

nlp = spacy.load('ja_ginza_electra')
doc = nlp("山田さんと銀座でランチをご一緒しましょう。")
for ent in doc.ents:
   print(
       ent.text+','# テキスト
       ent.label_+','# ラベル
       str(ent.start_char)+','# 開始位置
       str(ent.end_char)) # 終了位置

山田,Person,0,2
さん,Title_Other,2,4
銀座,City,5,7



5.単語の分散表現


GiNZAでは学習済みの単語分散表現(word2vec)も使用できるみたいです。

分散表現は300次元ですが今回は最初の2次元だけ表示します。分散表現が学習されていない単語はALL 0になるみたいですね。

また、L2ノルムも取得することができます。

分散表現はja_ginza_electraでは学習済みモデルがないみたいなので、ja_ginzaを使用しています。

import spacy

nlp = spacy.load('ja_ginza')  
doc = nlp("銀座でランチをご一緒しましょう。")
for token in doc:
    print(token.text, token.vector[:2], token.has_vector, token.vector_norm)

銀座 [ 0.55935055 -0.02516028True 3.8992517
で [-0.09195102 -0.10327693True 1.8796002
ランチ [ 0.23565347 -0.08456942True 3.8218849
を [-0.19509408 -0.13202968True 2.0958433
ご [0.33537257 0.21526141True 2.8017106
一緒 [-0.1381576  -0.10699644True 2.5291438
し [ 0.00739705 -0.32393304True 2.2611105
ましょう [0. 0.] False 0.0
。 [ 0.12551211 -0.1708449 ] True 2.4466825

また、以下のように書くことで文のベクトル表現なども簡単に表現できます(各単語のベクトルを足して平均を求めている)。

import spacy

nlp = spacy.load('ja_ginza')  
doc = nlp("銀座でランチをご一緒しましょう。")
print(doc.vector[:2]) 

0.09312034 -0.08128325]





まとめ


GiNZAの基本的な処理について一通り触れてみましたが正直むちゃくちゃ便利です。

spaCyに関する知識が少ないのでGiNZAを有効活用できるようにそのあたりも勉強していこうと思います。





gensimのWord2Vecを使ってみたので、使用方法をまとめました。

今回コーパスは『極性分析できのこたけのこ戦争に決着をつける』の記事で集めたツイートのデータを使用します。小規模なコーパスなので上手くいかない可能性もありますが練習ということであまり気にしません。


Word2Vecとは


Word2Vecは大量のテキストデータを解析し、単語をベクトル化する方法です。

単語をベクトル化することで単語同士の類似度を計算したりすることができます。

今回の場合きのこの山とたけのこの里のツイートをWord2Vecを用いて分析するということできのこの山とたけのこの里はお菓子の名前という同じカテゴリなので二つの単語のベクトルは近いものになるはずです。


実行環境


  • Windows10
  • Python3.6
  • gensim3.4.0
  • MeCab(辞書はmecab-ipadic-Neologdを使用)
MeCabのインストール方法や辞書の変更方法は以下の記事にまとめています。

Python3でMeCabを動かしてみる(Windows10 64bit)

MeCabのNEologd辞書をWindows10で使う方法


gensimのインストール


gensimは以下のコマンドだけでインストールすることができます。
pip install gensim
anacondaを使っていてpipではインストールができない場合は次のコマンドを使ってください
conda install -c anaconda gensim



学習データの準備


コーパスは最初に述べた通りツイートのデータを使うのですがWord2Vecの学習を始める前に学習データを分かち書きにして単語と単語の間をスペースで区切った状態に変更する必要があります。

またWord2Vecでモデルを作成するさいは助詞、助動詞などの非自立語は除外したほうが精度の良いモデルを作成することができるため今回は名詞、形容詞、動詞以外の単語は除外します。

"たけのこの里が好きだ。" という文があった場合は "たけのこの里 好き" といった状態に変更します。

学習データの準備は以下のコードで実行しました。
# -*- coding: utf-8 -*-
# 学習データをgensimで使える型に変換

import MeCab

# テキストを名詞、形容詞、動詞を残した分かち書きに変換
def wakachi(text, file):
  tagger = MeCab.Tagger("-Ochasen -d C:\mecab-ipadic-neologd")
  node = tagger.parseToNode(text)
  while node:
    # 名詞、形容詞、動詞だけリストに追加
    if (node.feature.split(',')[0] == '名詞' or node.feature.split(',')[0] == '形容詞' or node.feature.split(',')[0] == '動詞') and node.feature.split(',')[6] != '*':
      try:
        file.write('{} '.format(node.feature.split(',')[6]))
      except:
        pass
    node = node.next
  
# tweetを読み込み
def loadtweet(filename):
  tweet = []
  with open(filename) as f:
    for i in f:
      try:
        tweet.append(i.rstrip())
      except:
        pass
    return tweet
  
def main():
  tweet = loadtweet("tweet/kinoko_tweet.txt")
  wakachi_file = "kinoko_wakachi.txt" # 書き込み先のファイル名
  
  with open(wakachi_file, 'w') as f:
    for i in tweet:
      wakachi(i, f)
      f.write('\n')

if __name__ == '__main__':
  main()
今回私はtweetを対象に行っていますがどんなコーパスを使用してもこのコードで対応できるはずです。

コード中に例外処理をいれていますがこれは文字コード関係でエラーを起こしてしまい今回はあまり厳密にデータをしなくてもいいかということで簡単に片づけています。




Word2Vecのモデル作成


Word2Vecのモデルの作成は自分で一からコードをかこうとすると結構大変ですが、gensimを使えば10行もかかりませんでした。

モデルの作成は以下のコードで行いました。
# -*- coding: utf-8 -*-
# Word2Vecのモデルを作成
from gensim.models import word2vec

data = word2vec.LineSentence("kinoko_wakachi.txt")
# モデルを作成
model = word2vec.Word2Vec(data, size=200, window=10, hs=1, min_count=2, sg=1)
# モデルを保存
model.save('kinoko.model')
モデルを作成するWord2Vecメソッドのオプションでは、生成するベクトルの次元数や、単語の最大距離を設定することができます。

sizeは生成するベクトルの次元数です。今回は200次元にしています。
windowは単語の最大距離です。今回は10にしています。
hsは学習にsoftmax関数を使うかどうかです。(0の場合は使わない、0以外の値では使う)
min_countはこの値より出現回数の少ない単語を無視します。
sgは学習アルゴリズムの設定です(0の場合はCBOW、1の場合はskip-gram)。今回は何かの論文でskip-gramの方が良い結果になりやすいと見た記憶があるのでskip-gramを使いました。


生成したWord2Vecのモデルを使ってみる


modelの読み込み

model = word2vec.Word2vec.load('kinoko.model')

単語のベクトルの確認

# きのこの山のベクトルを確認
word_vector = model.wv["きのこの山"]

似た単語を列挙

# きのこの山と類似している単語の確認
similar_words = model.wv.most_similar(positive=["きのこの山"], topn=9)
print(similar_words)
[('満足', 0.6623457670211792), ('NI', 0.6556951999664307), ('きのこ派', 0.6542500257492065), ('最高かよ', 0.6375962495803833), ('アイス', 0.6262195110321045), ('4m', 0.6219021081924438), ('ファン', 0.6202322244644165), ('永遠', 0.6201416850090027), ('ムース', 0.619083821773529)]
きのこの山に類似している単語にたけのこの里がないのは意外でした。アイスやムースなどの他の食べ物があるため学習データを増やせばたけのこの里も類似している単語として出現するのかもしれません。

語句の線形計算

# 線形計算(きのこの山-きのこ=???)
print(model.most_similar(positive=['きのこの山'], negative=['きのこ'])[0])
('木村', 0.4005602300167084)
"きのこの山-きのこ" をしてみると "木村" という謎の結果になりました。(なにがでたら正解かは分からないが...)

positiveに加算する単語、negativeに減算する単語を入れます。"父-男+女" のように複数の単語を用いた計算を行うことができます。

色々な語句の線形計算を行ってみると楽しそうな気がします。


最後に


この記事ではgensimを使ってWord2Vecのモデルを作成しました。

今回は小規模なコーパスを使ってモデルを作成しましたが、次することがあればもう少し大きなコーパスを使ってモデルを作成して文の類似度を測るなど応用した方法を実行してみようと思います。




Python3でtweetの形態素解析を行うためにWindows10でMeCabの辞書をNEologd辞書に変更しようとしたら思いのほかてこずったので変更手順をまとめました。

MeCabをインストールしていることを前提として進めるのでまだインストールしていない方は下の記事を参考にしてください。




NEologd辞書とは


Neologd辞書とは佐藤敏紀(@overlast)が開発しているオープンソースのMeCabと共に使う単語分かち書き辞書です。

特徴として週二回以上という頻繁なペースで更新されているため新語や固有表現に強く、語彙数が多くなっています。

そのためSNSなどの新語が多い環境で自然言語処理を行う際一般的にNeologd辞書が使われています。



NEologd辞書のインストール

動作環境

本記事における動作環境は下記の通りになります。
  • Windows10 Home
  • Python 3.6.7


コマンドプロンプトでLinuxコマンドをたたけるようにする


Linuxコマンドを使ってneologd辞書をインストールしていくので最初にコマンドプロンプトでLinuxコマンドを入力できるようにしていきます。

1. Windows Subsystem for Linuxを有効にする


コントロールパネル > プログラム
neologd1

Windowsの機能の有効化または無効化

neologd2

Windows Subsystem for Linuxにチェックして再起動

neologd3

2. Ubuntuをインストール


Windows Subsystem for Linuxを有効にしたら次はMicrosoft StoreからUbuntuをインストールします。

Microsoft Storeを起動してUbuntuと検索したら下記の画面がでるので入手をクリックしてください。
neologd4

3. ユーザ登録


インストールが完了したらUbuntuを起動してください。そうするとユーザ名とパスワードを入力するように指示がでますのでにゅうりょくしてください。

4. パッケージを最新化する


ユーザ登録ができたらパッケージを最新化するために下記のコマンドを入力してください。

sudo apt update
sudo apt upgrade





NEologdをインストール

1. ビルドに必要なものをインストール


下記のコマンドを入力してビルドに必要なものをインストールします。

sudo apt install mecab
sudo apt install libmecab-dev
sudo apt install make

2. UbuntuでNeologdをインストール

git clone https://github.com/neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd
sudo bin/install-mecab-ipadic-neologd

3. NEologdをWindowsにコピーする

cd ..
sudo cp -R /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd/  /mnt/c/

コピー先は各自好みで指定してください。


NEologdがWindows10で使えるか確認


上記の作業が全て完了したらWindowsで使えるか確認します。

下記のコードが動いたら正しくインストールできています。

import MeCab

mecab = MeCab.Tagger("-Ochasen -d C:\mecab-ipadic-neologd")
print(mecab.parse("進撃の巨人の発売日だ"))

実行結果は以下の通りになります。

neologd5

ちなみに最初からMeCabに入っている辞書を使った場合の結果は以下の通りになります。

neologd6






以前Windowsの環境でPythonでMeCabを使おうと思ったら上手くいかず諦めてUbuntuを使っていたのですが、今回久しぶりに挑戦してみるとあっさりと使うことができたので環境構築方法をまとめました。


動作環境


本記事における動作環境は下記の通りになります。
  • Windows10 Home
  • anaconda
  • Python 3.6.7
今回はanacondaを使っていますがanacondaを使ってなくても手順通り進めればインストールすることができます。



MeCab(64bit版)のインストール

1. MeCab(64bit版)のインストーラのダウンロード


MeCabのインストーラは下記のページからダウンロードできます。




2. mecab-0.996.exeを実行する


インストーラをダウンロードできたらmecab-0.996.exeを実行してインストールしていきましょう。



環境変数の設定


MeCabを無事インストールすることができたら次は環境変数の設定を行います。

1. 環境変数に「MeCabのインストール先\bin」を設定する


インストール先を特に指定せずデフォルトの設定でインストールしたのなら下記の例と同じもので問題ありません。

環境変数の例:C:\Program Files\MeCab\bin


2. 環境変数が正しく通せているか確認する


環境変数を設定できたら設定を正しく行えているか確認します。

コマンドプロンプトを起動してMeCabと入力した後に好きな文章を入力して形態素解析が実行されたら正しく環境変数を設定できています。

この際文字化けがおきますがそれはコマンドプロンプトがUTF-8に対応していないのが原因で起きるので気にしなくて大丈夫です。

MeCab1




mecab-python-0.996のセットアップ

1. mecab-python-0.996.tarのダウンロード


mecab-python-0996.tarは下記のページのperl/ruby/python/java バインディングの下にあるダウンロードリンクからダウンロードができます。

ダウンロードの際様々なバージョンのものがありますが0.996のものをダウンロードしてください。


2. mecab-python-0.996.tarを解凍する


mecab-python-0.996.tarをダウンロードすることができたら好きな場所に解凍してください。


3. setup.pyの編集


mecab-python-0.996のフォルダ内にあるsetup.pyはpython2.xxに合わせて書かれているものなのでpython3で利用できるように中身を少し書き換える必要があります。

下記に編集後のコードを乗せておくのでこれをそのままコピーしたらほぼほぼ大丈夫です。

ただMeCabのインストール先をデフォルトとは別の場所にした場合その部分だけインストール先に合わせて修正してください。

#!/usr/bin/env python

from distutils.core import setup,Extension,os

setup(name = "mecab-python",
    version = '0.996',
    py_modules=["MeCab"],
    ext_modules = [
        Extension("_MeCab",
            ["MeCab_wrap.cxx",],
            include_dirs=[r'C:\Program Files\MeCab\sdk'],
            library_dirs=[r'C:\Program Files\MeCab\sdk'],
            libraries=['libmecab'])
    ]
)


4. ビルドとインストール


Anaconda Promptを起動してmecab-python-0.996のフォルダに移動してください。

移動できたら下記のコマンドを入力してビルドしてください。

python setup.py build

ビルドができたら下記のコマンドを入力してインストールしてください。

python setup.py install


5. 実行確認


インストールができたら最後に実行できるか確認を行います。

下記のコードを実行して形態素解析の結果がかえってきたら作業は終了です。

import MeCab
mecab = MeCab.Tagger("-Ochasen")
print(mecab.parse("すもももももももものうち"))

実行結果は下記の通りになります。

MeCab2



最後に


環境を構築中にVisual Studioをインストールしていない場合はそれ関連のエラーが出るかもしれませんが適宜対応してください。

もし何か分からないことがあればコメントをもらえれば返しますのでコメントしてください。


1979年から現在にかけて、きのこの山派とたけのこの里派との間で繰り広げられているきのこたけのこ戦争に終止符を打つためにきのこの山、たけのこの里に関するツイートを集めて極性分析してみました。

今回の記事ではきのこの山、たけのこの里に関するツイートを同数集めて、ポジティブなツイートが多い方をきのこたけのこ戦争の勝者とします。




極性分析とは


自然言語処理の感情分析技術の一つで、分析したい文章がポジティブ(正)な文章なのかネガティブ(負)の文章なのか判定する技術である。

「カントリーマァムはお美味しい。」

上記のような例文がある場合美味しいはポジティブな単語なので例文はポジティブな文だと分析される。

極性分析は、東北大学の乾・鈴木研究室の日本語評価極性辞書(用言編)[1] と日本語極性辞書(名詞編)[2] を用いて行います。

用言編では用言を中心に約5000件に人手でポジ(経験)、ポジ(評価)、ネガ(経験)、ネガ(評価)のタグが割り振られています。

名詞編では評価極性を持つ名詞、約8500表現に対してp(ポジティブ)、e(ネガティブ)、n(ニュートラル)のタグが割り当てられています。



実行手順


きのこの山とたけのこの里に極性分析を行う実行手順は以下の通りになります。

1. Twitterから「きのこの山」 or 「たけのこの里」が入るツイートを集める
2. ツイートを分かち書きにする
3. 極性を求める


1. Twitterから「きのこの山」 or 「たけのこの里」が入るツイートを集める
今回ツイートはpythonでTwitterAPIを使うことができるtweepyを使用しました。

TwitterAPIでは過去一週間までのツイートを収集できるので一週間分収集しました。

またツイートの中にはきのこの山とたけのこの里の両方の言葉が入っているものもありましたが、今回はそういったものは除外しました。


2. ツイートを分かち書きにする
ツイートを分かち書きに変換するのにはMeCabを使用しました。また辞書はNEologd辞書を使用しました。

MeCabのインストール方法については下記の記事に書いているのでそちらを参考にしてください。

Python3でMeCabを動かしてみる(Windows10 64bit)

MeCabを使用すると文章を単語単位に分割できるので、これで日本語極性辞書が利用できます。


3. 極性を求める
今回極性は全てのポジティブな単語の重みを、全てのネガティブな単語の重みを-1として計算していきます。

最終的に文に対する重みの合計が1以上の場合はポジティブな文、-1以下の場合はネガティブな文、0の場合とネガティブまたはポジティブの単語が文中に一つもない場合はニュートラルな文として判定していきます。



きのこたけのこ戦争の結果


実験データとしてきのこの山が入っているツイートを3641件、たけのこの里が入っているツイートを4231件用意しました。

きのこの山とたけのこの里のツイート数をそろえないのはそれぞれに対しての過去一週間のツイート数も人気度に反映すると判断したからです。

以下がきのこの山とたけのこの里に関する極性分析の結果です。

kinokotakenoko1

結果は、ツイート数が多いたけのこの里の方がきのこの山よりもポジティブなツイート数が多いという結果になりました。当然と言えば当然な結果なのですがきのこの山派の私としては残念な結果となりました。

たけのこの里ときのこの山のネガティブ、ポジティブ、ニュートラルの割合をそれぞれいかに示します。
kinokotakenoko3
kinokotakenoko2

割合をみてもたけのこの里の方がポジティブなツイートが多いみたいなのできのこの山の完全敗北となりました。

どちらともポジティブなツイートよりもネガティブなツイートの方が多いのが面白いですね。



最後に


極性分析できのこたけのこ戦争に決着をつけてみた結果たけのこの里の大勝利という結果で終わりました。みなさん納得のいく結果だったでしょうか?

きのこの山派の私としてはとても悔しいのできのこの山のポジティブなツイート数を増やすために今度きのこの山botでも作ろうと思います。

収集したツイートの中には「きのこの山よりたけのこの里の方が好きだ」といった両方のワードが出てきたツイートもありましたので、もしまた次やることがあればそういったツイートも分析の対象としていれていけるようにしたいです。

こんなネタ記事をここまで読んでくださってありがとうございました。


参考
[1] 小林のぞみ,乾健太郎,松本裕治,立石健二,福島俊一. 意見抽出のための評価表現の収集. 自然言語処理,Vol.12, No.3, pp.203-222, 2005. / Nozomi Kobayashi, Kentaro Inui, Yuji Matsumoto, Kenji Tateishi. Collecting Evaluative Expressions for Opinion Extraction, Journal of Natural Language Processing 12(3), 203-222, 2005.

[2] 東山昌彦, 乾健太郎, 松本裕治, 述語の選択選好性に着目した名詞評価極性の獲得, 言語処理学会第14回年次大会論文集, pp.584-587, 2008. / Masahiko Higashiyama, Kentaro Inui, Yuji Matsumoto. Learning Sentiment of Nouns from Selectional Preferences of Verbs and Adjectives, Proceedings of the 14th Annual Meeting of the Association for Natural Language Processing, pp.584-587, 2008.









↑このページのトップヘ