論文:ウェブページからデータを抽出するプログラムの合成
プログラムを自動生成する研究、とくに入出力例を用いたプログラム合成 (Programming by Example) に興味があるので、論文を読んでメモとして残してゆく。以下、水色のテキストは私の主観的なコメント。
タイトル
Web Data Extraction using Hybrid Program Synthesis: A Combination of Top-down and Bottom-up Inference
SIGMOD2020
概要
ウェブページからデータを抽出するプログラムを、抽出すべきデータの (不完全な) 例から合成する手法。合成のアルゴリズムとして、入出力例を考慮したトップダウンなアプローチと、ドキュメントの構造のみを考慮したボトムアップなアプローチを組み合わせるのが特徴。本手法は Microsoft Power BI に搭載されている。
手法の入出力
手法の入力
- Web ドキュメント
- 抽出するデータの例 ]
- は文字列、 はノードの例。文字列は必須で、ノードはオプション。
- たとえば [(“Snow White and the Seven Dwarfs”, ), (“Fantasia”, )]
- ここで や は null でもよい。
手法の出力
- DSL 上のプログラム
- ただし、 の実行結果が ] であるもの。ここで、すべての () に対して以下が成立する
- ( null の場合)
- ここでのポイントは、抽出するデータの例が 個与えられるもとで、 () 個のデータを抽出する、もっともらしいプログラム を求めるということ。仕様が不完全であるため、semi-supervised で hybrid なアプローチが有効である。
- ただし、 の実行結果が ] であるもの。ここで、すべての () に対して以下が成立する
DSL の定義
プログラム合成手法では、DSL (Domain-Specific Language、ドメイン固有言語) をドメインごとに定義し、その上でプログラムを構築するアプローチが一般的である。本手法では、入力となる DOM ツリー inp からノードの集合を抽出するための DSL を以下のように定義する。
各命令のセマンティクスは論文を参照。ただし、文法 から点線下線と実線下線を除いた文法を、それぞれ と とする。文法 , はそれぞれ top-down, bottom-up な合成で構築される。
たとえば、"mydata" という ID を持つノードの配下にある DIV 要素の2番目の子でありクラス "c1" のノード集合を抽出したいとき、対応するプログラムは以下の通りである。
Filter( Conjunction( Class(“c1”), NthChild(2) ), ChildrenOf( Filter( Tag(“DIV”), DescendantsOf( Filter( AllNodes(), Id(“mydata”) )))))
Combination of top-down and bottom-up synthesis
一般に、DSL 上のプログラムを合成するアルゴリズムとして top-down なものと bottom-up なものが存在する。
top-down なアプローチでは、ユーザによって入出力例が与えられるケース (supervised program synthesis) で有効である。 具体的には、構文木の根から葉の方向へプログラムを構築してゆく。その過程において、満たすべき入出力例の制約を、各命令からその引数 (構文木の) へと伝播させることで、探索空間を入出力例を満たしうる部分のみに限定する。これは deductive なアプローチといえる。
bottom-up なアプローチは、ユーザによって入出力例を与えられないケース (unsupervised program synthesis) で有効である。(入出力例の制約は関係なく) DSL 上のプログラムを列挙する。
本手法は、top-down と buttom-up なアプローチのどちらも使用するハイブリッドなアルゴリズムになっているのが特徴である。
Bottom-up synthesis
まずは Figure 5 にある bottom-up な合成から見てゆく。
- EnumerateBottomUp(d)
与えられた入出力例とは関係なく、 で表現されるプログラムをボトムアップに列挙してゆく 。その結果は、得られたプログラム と、それをウェブドキュメント に適用した結果得られるノード集合 の2つ組 の集合 として返される。本質的には、 でなくプログラム の集合を返すだけでよいが、ドキュメント に対する実行結果をキャッシュすることで計算にかかる時間を削減しているっぽい。
- TopAlignmentGroups()
前手順で列挙したプログラムの実行結果は、ドキュメント において親子関係を持つ可能性がある。そこで、親子関係にあるノードを生み出すプログラムの集合を としてグルーピングする。さらに、グループの中で根に近いノードを実行結果にもつプログラム をグループの代表とする。つまり、 を求める。たとえば、Figure 3 の motivating example の例では が .list_item
であり、 が .year_type
や .item_desc SPAN
である。
Top-down synthesis
Figure 7 の top-down なプログラムの合成を見てゆく。
- SynthTopDown(, , )
で表現されるプログラムを top-down に列挙してゆく。このとき、満たすべき出力例 が与えられるが、これを使用する DSL の命令 (ChildrenOf, Filter) の引数を合成するにあたっての新たな制約として伝播させるのがポイント。ここの仕組みが厳密に理解できていない。Figure 8 の line 2 で の親になり得るノード集合 を求め、line 3 で再帰的に SynthTopDown(, , ) を呼び出している。親方向のノード集合を再帰的に求めることになるので、やがて は根のシングルトンとなり、その後に空集合となるはず。 が空集合であれば も空集合となるので、再帰が停止しないように思う。
- SynthPredicate(, , , )
実行結果としてノードの列 をプレフィックスに持つような Filter の条件式を合成する。このとき、overfitting を避けるため、できる限りシンプルな条件式を合成したい。そこで minimal set cover として定式化して解く。具体的には、atomic な述語と、それによって取得できるノード集合 () を求めておき、 をカバーできる最小数の述語の組み合わせ (conjunction) を求める。
Hybrid synthesis
Figure 8 の hybrid なプログラム合成を見てゆく。なお、top-down な合成が成功した場合、解となるプログラムをより洗練させる形で hybrid synthesis を実行する。
- SyntheHybrid(, , , )
ここで は bottom-up に発見されたノードのグループ、 は top-down に求められたプログラムである。この2つの情報を組み合わせているので hybrid といえる。 は入出力の例とは独立に、ドキュメント のみから構築されたグループであるため、ドキュメントの構成要素を "自然な" まとまりとして集めたノード集合である。それに対し、入出力の例を考慮して top-down に作られたプログラム が に対して整合性があるかをチェックする。整合性がなければ制約を として追加して top-down な合成を再実行する。
たとえば、bottom-up に集めた映画のレコードが 100 件あったとして、そこから映画のタイトルを抽出したいとする。ただし、100 件中 1 件だけディレクターについての項目が欠落しており、タグ構造が特殊なレコードがあるとする。このとき、抽出するデータの例として先頭 2 件が与えらえたとする。この 2 件を満たすように top-down に合成したプログラム が 100 件中 99 件のタイトルしか抽出していないとき、合成結果を とするのは怪しい。そこで、100 件を結果として含むように制約を加えて合成を再実行する。その結果、100 件すべてから正しく映画タイトルを抽出するプログラムを合成できる。
Evaluation
論文参照。
所感
- Web ページのスクレイピングを自動的に行う手法。抽出するデータの形式がレコードである場合 wrapper induction と呼ばれるらしい。ここで wrapper は HTML などで表現されたページの構造からレコード集合への写像。
- 与えられる出力例が、期待する出力の一部のみが与えられる不完全なものであるため、完全な出力例を推測する必要がある。そのための heuristics が bottom-up な合成として表現されているように思えた。
- bottom-up にプログラムを列挙するアルゴリズムとして lifting functions を用いている。これは [34] に詳細が書かれているのでちゃんと見てみたい。