質問応答("Multilingual Natural Language Applications: From Theory to Practice"より)
(Schlaefer and Chu-Carroll, 2012) Nico Schlaefer, Jennifer Chu-Carroll: "Question Answering", Book chapter in "Multilingual Natural Language Applications: From Theory to Practice". Pearson, 2012.
を飛ばして読んだ。
質問応答
1.1 導入と歴史
質問応答(QA)システムは情報源からユーザの質問に答える回答を検索する。キーワード検索のパラダイム、たいていの伝統的な情報検索(IR)システムによって適用されるもの、と対照的にQAシステムは自然言語で質問を尋ねられる、ということはより直感的にそしてもっと表現的である、少ないキーワードと比較して。加えて、IRシステムがパッセージや文書をユーザのクエリに対する応答として返す一方で、QAシステムは的確でポンイントをついた回答を提供することを試みる。しばしば、ウェブは巨大で冗長で最新の情報源として重宝される。しかし、ローカルのテキストコーパスは頻繁に応用検索技術のために使われる、応用検索技術はソースを要求する、前処理をされ、狭いドメインに対して、そして比較・再現可能な結果を求める評価のためのソースを。
時間をとって最も研究されている質問タイプはfactoid質問とlist質問、factoid質問は固有表現のような簡潔な回答を尋ね(例えば、ターキーのキャピタルは何?)、list質問はfactoidのような回答のリストを見つける(例えば、どの国々がNATOにいるの?)。
書く速度が読む速度より遅くて面倒なので、要約しながら訳す。
factoidとlist型質問が最も研究されている。
最近はcomplex型質問として定義型質問、関係型質問、意見型質問などが研究されているよ。
RTE(Recognizing Textual Entailment)タスク
時間表現の妥当性が云々 today->1998
複数のサブ質問から回答が生成されるもの 「ワールドカップとヨーロッパチャンピオンシップで優勝した国のリストは?」
QAの研究について1960年代に戻ろう
限定されたドメインに対するエキスパートシステムは開発された[Simmons, 1970]
BASEBALLシステム[Green et al., 1961] US野球リーグのQA
LUNARシステム[Woods, 1973] アポロ計画で月から採取された岩のサンプルについてのQA
どちらも構造化された知識源と使ってる
早期の自然言語対話システム、基本的な質問応答の能力を備えたもの、例えばSHRDLUシステム(Winograd, 1972)はオモチャの世界
読解力を備えたシステムとしてQUALM[Lehnert, 1977]がある。
これらは人手の知識ベースに頼ってないがドメインは狭い
1990年代はクローズドドメインからオープンドメインへの移行期
非構造化テキストの大規模なコレクションをベースにしたトピックについての質問に答える
新世代のの質問応答の一つとしてNURAX [Kupiec, 1993]がある。これはfactoid質問に対して、onlineの辞書を使った一般知識を使って答える
英語のQA研究の主要なドライバは年次評価を運営しているTREC, 1999年から始まる[Dang et al., 2007]
2008年にQAトラックはTACに移動し[Dang et al., 2008]意見型質問にフォーカスがシフトした
CLEFは同様の評価プラットフォーム、ヨーロッパ言語に対する
NTCIRワークショップは年次(注、実際はannutalではなく1.5年に1度)評価、アジアの言語に対するQAの評価、[Mitamura, 2008]
TRECやTACは単一言語QAタスクに注目している、質問や情報源は両方とも英語、CLEFとNTCIRは言語横断タスク(NTCIRではACLIAでそういうのをやっていた)
今日はMITのSTARTシステム、Ask.com, Wolfram Alpha. MicrosoftとGoogleは基本的なQAをウェブ検索エンジンに統合した。
TRECのシステムとして、CMUのOpenEphyraやMITのAraneaはオープンソース。
1.2 構成 (Architecture)
主要なパイプラインは次
質問解析
クエリ生成
検索
候補となる回答生成
回答ソコア付け
1.3 知識獲得と前処理
テキストを正規化する
広告のようなノイズを削除する
スペルを直す
文に分解する
日本語のQAは形態素に分解する
分かち書きされていないので大変
複数の字種が文内に現れる、カタカナ、ひらがな、漢字、がこれが分かち書きの鍵となる
幾つかの日本語のインデックスは文字1gramか2gramでリコール重視で作られる、ノイズも増えるが
中国語は単語分割が部分的に難しい、
字種は大抵一つ(漢字)だから(日本語のように複数の字種がないから)分割が難しい
辞書にない未知語を認識して分割するのは難しい
主要なインデクシングは文字レベルで行う
大抵のソースはいろんな型の統語的意味的なアノテーションで増大している、瀕し、固有表現の型、エンティティの関係。
IndriとLuceneの紹介。
1.4 質問解析
辞書やWord NetやFrame Net由来のcompound terms
オントロジー(木構造)のanswer type
1.5 検索と候補抽出
1.5.1 非構造化ソースに対する検索
anaphoraは日本語や中国語で頻出する。
IDFやOkapi BM25
PRF (pseudo-relevance feedback)によるクエリ拡張
1.5.2 非構造化ソースからの候補抽出
「型ベースの候補抽出」
質問解析で抽出した回答型を使う方法
数値型や日付型は正規表現(regex)に使うといい
「構造的なマッチングを用いた候補抽出」
統語的、意味的な構造を用いて取り出す
MINIPARは英語係り受け解析器
PropBank corpus は人手で述語項構造のアノテーションが付いている
SRL (semantic role labeling)
SRLシステムにASSERTがある
Semantic role labelingとマッチングの例がある
1.5.3 構造化ソースからの候補抽出
RDF
DBpediaやFreebase
1.6 回答スコア付け
1.6.1 アプローチの概要
TF-IDF
similarity
COGEX
質問と回答に関係するパッセージを
統語的なパーサと論理proverで論理表現に変換
wh-slot
テキストの含意関係技術
PASCAL RTE チャレンジ
地名辞典は地理的な質問に答える
CIA World Factbook
eXtended WordNet (XWN)
1.6.2 根拠を結合する
根拠は数値的、カテゴリ特徴量として表現され、
統計モデルは候補が正解か確率を求める
logistic regression [Agresti, 2002]や最大エントロピーモデル[Berger et al., 1996]
ルールベース
1.6.3 リスト質問に対する拡張
factoid型質問はトップランクされた回答か無回答
list型質問はトップnの回答を返す
nは質問文から抽出できるか、信頼度の閾値で決める、など
!あんまり、いいことが書かれていない
問題文からリスト数が決まる場合もあるけど回答すべきことからリスト数が決まる場合もあるでしょ?
NATO加盟国は?に対してはNATO加盟国全部リストするわけで。。。
1.7 言語横断質問応答
機械翻訳を通してソースを拡張することができる
Google TranslateとBabel Fish
1.8 事例分析
もう少し具体的な処理の流れが書いてあるだけ
1.9 評価
1.9.1 評価タスク
1999-2007 TREC 8-16
2008- TAC
factoid, list, definition, relationship, opinion
NTCIR workshop
言語横断QAについて、アジアの言語
CLEF
ドイツ語、英語、フランス語、ドイツ語、イタリア語、ノルウェー語、ポルトガル語、ルーマニア語、スペイン語
CLEFの特徴はNTCIRよりもっと質問とコーパスのペアが複雑
(確かにペアの組み合わせ数は増すかもしれないけど、日本語や中国語と英語の言語的なペアの複雑性は書かれていないのね。。。)
1.9.2 回答の正しさの判定
complex answerはnuggetを使ったものがある
あんまり書かれていない
1.9.3 パフォーマンスのメトリクス
Accuracy
MRR
MRR@5
CWS (confidence weighted score)
Recall and Precision
F
1.10 現在と将来の挑戦
semantic matching, テキスト含意関係
理由付け
new domainやreal worldアプリケーション
1.11 まとめとさらなる読み物
省略
sbtからのREPLメモ
sbtのバージョンは、0.12.1。
REPLは、consoleで起動。
他は:helpの内容をコピペしておく。
All commands can be abbreviated, e.g. :he instead of :help.
Those marked with a * have more detailed help, e.g. :help imports.
:cp
:help [command] print this summary or command-specific help
:history [num] show the history (optional num is commands to show)
:h?
:imports [name name ...] show import history, identifying sources of names
:implicits [-v] show the implicits in scope
:javap
:load
- paste enter paste mode
- all input up to ctrl-D compiled together
:power enable power user mode
:quit exit the interpreter
:replay reset execution and replay all previous commands
:reset reset the repl to its initial state, forgetting all session entries
:sh
:silent disable/enable automatic printing of results
:type [-v]
:warnings show the suppressed warnings from the most recent line which had any
尺度水準
同一性 | 順序性 | 加法性 | 等比性 | |
(頻度) | (大小) | (加減) | (乗除) | |
名義尺度 | ○ | × | × | × |
順序尺度 | ○ | ○ | × | × |
間隔尺度 | ○ | ○ | ○ | × |
比例尺度(絶対零点) | ○ | ○ | ○ | ○ |
詳しくは、
http://www.motorwarp.com/koizumi/scale.html
リッカート尺度(順序尺度)
提示された文に回答者がどの程度合意できるかを回答する。
1.全く同意できない
2.同意できない
3.どちらともいえない
4.同意できる
5.非常に同意できる
のような5段階がよく使われる。
私としては、段階数はどっちつかずの部分をCantor functionやMinkowski's question mark functionのごとく用意するためににしたらいいんじゃない?と思うけどどうなんだろう?
サーストン尺度
ガットマン尺度
MappedOneToMany
MappedOneToManyは、同じ2テーブル間で同じ方向に一対多関係を複数設置しても実体はMappedForeignKeyなのでどれも同じものとして扱われる。例えば、次のような設計はアンチパターン。
class Counter extends LongKeyedMapper[Counter] with IdPK with OneToMany[Long, Counter] { def getSingleton = Counter object waiting extends MappedOneToMany(Invitation, Invitation.counter, OrderBy(Invitation.id, Ascending)) object invited extends MappedOneToMany(Invitation, Invitation.counter, OrderBy(Invitation.id, Ascending)) //waitingとinvited以外のカラムがあればという意味 object something_else extends MappedSomethingElse(this) } class Invitation extends LongKeyedMapper[Invitation] with IdPK { def getSingleton = Invitation object counter extends MappedLongForeignKey(this, Counter) } //以下のコードは読まなくても大丈夫 object Counter extends Counter with LongKeyedMetaMapper[Counter] {override def fieldOrder = List(id)} object Invitation extends Invitation with LongKeyedMetaMapper[Invitation] {override def fieldOrder = List(id)}
対策としては、テーブルをわけてしまえばいい。
class WCounter extends LongKeyedMapper[WCounter] with IdPK with OneToMany[Long, WCounter] { def getSingleton = WCounter object waiting extends MappedOneToMany(Invitation, Invitation.wcounter, OrderBy(Invitation.id, Ascending)) //必要であれば object counter extends MappedLongForeignKey(this, Counter) } class ICounter extends LongKeyedMapper[ICounter] with IdPK with OneToMany[Long, ICounter] { def getSingleton = ICounter object invited extends MappedOneToMany(Invitation, Invitation.icounter, OrderBy(Invitation.id, Ascending)) //必要であれば object counter extends MappedLongForeignKey(this, Counter) } class Counter extends LongKeyedMapper[Counter] with IdPK with OneToMany[Long, Counter] { def getSingleton = Counter //上のコード同様、waitingとinvited以外のカラムがなければCounterごと消す。 object something_else extends MappedSomethingElse(this) } class Invitation extends LongKeyedMapper[Invitation] with IdPK { def getSingleton = Invitation object wcounter extends MappedLongForeignKey(this, WCounter) object icounter extends MappedLongForeignKey(this, ICounter) object counter extends MappedLongForeignKey(this, Counter) } //以下のコードは読まなくても大丈夫 object WCounter extends WCounter with LongKeyedMetaMapper[WCounter] {override def fieldOrder = List(id)} object ICounter extends ICounter with LongKeyedMetaMapper[ICounter] {override def fieldOrder = List(id)} object Counter extends Counter with LongKeyedMetaMapper[Counter] {override def fieldOrder = List(id)} object Invitation extends Invitation with LongKeyedMetaMapper[Invitation] {override def fieldOrder = List(id)}
TableSorter
I tried to use the TableSorter Lift Widget (lift 2.4M5).
According to the tutorial (http://oss.infoscience.co.jp/scala/www.assembla.com/wiki/show/liftweb/TableSorter.html), I could have activated it by this code.
TableSorter("#table_id")
So then, I tried to do it by the following code. It was successful.
TableSorter.init
TableSorter("#table_id")
MappedDateTime, MappedDate and MappedTime's format methods
MappedDateTime, MappedDate and MappedTime's format methods use LiftRules.dateTimeConverter's format methods (formatDateTime(d : Date), formatDate(d) and formatTime(d)) which use the following formatters respectively.
def formatDateTime ->
def internetDateFormatter = { val ret = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.US) ret.setTimeZone(utc) ret }
def formatDate(d) ->
def dateFormatter = new SimpleDateFormat("yyyy/MM/dd")
def formatTime(d) ->
def hourFormat = new SimpleDateFormat("HH:mm:ss")
Then, I overrided thier methods to localize them.
MappedDateTime case
import _root_.java.text.DateFormat import _root_.java.util.Date import _root_.net.liftweb.http.S override def format(d : Date) : String = DateFormat.getDateTimeInstance( DateFormat.FULL, DateFormat.FULL, S.locale ).format(d)
MappedDate case
import _root_.java.text.DateFormat import _root_.java.util.Date import _root_.net.liftweb.http.S override def format(d : Date) : String = DateFormat.getDateInstance( DateFormat.FULL, S.locale ).format(d)
MappedTime case
import _root_.java.text.DateFormat import _root_.java.util.Date import _root_.net.liftweb.http.S override def format(d : Date) : String = DateFormat.getTimeInstance( DateFormat.FULL, S.locale ).format(d)