はじめに

近年のコンピュータの普及により、 教育・学習においてもコンピュータが利用される機会が増えてきた。 コンピュータを利用した学習はeラーニング(e-learning)と呼ばれており、 企業研修などでよく利用されているほか、 学校教育でも利用されるようになってきた [。 学習者がeラーニングを行うには、最低限eラーニング用電子教材が必要となる。 電子教材は、既存のアナログ教材を学習管理システム (Learning Management System)で利用できる形式に教師が 変換したものであったり、教師が独自に用意することもある。 電子教材には、ある事柄について説明した文章や画像から、 コンピュータ上で学習する事を生かしたインタラクティブコンテンツや 動画などがある。また、学習状況を確認するための小テストやドリルも これに含まれる。特に後者は、教師が学習者の状況を管理することが できるだけでなく、学習者も自身の学習状況の再確認ができるため、 モチベーションの向上にも繋がる重要な役割を果たすと考えられる。 以上のように電子教材はeラーニングにおいて必要不可欠なものだが、 学習に十分な分量の電子教材を用意する事は、 教師にとって負担が大きいものである。 教師の負担軽減のために、教師が重要語句や単語についての情報を入力しておき、 その内容を元に様々な形式の小テストを自動生成する方法が報告されている [

本研究では、Wikipedia記事を教材として、 情報理論の観点から重要単語を数学的に判断し、 多肢選択式問題や穴埋め問題などの生成に利用していくことにした。 学習内容の例として、日本の47都道府県について学習する事を想定し、 問題を自動生成するアプリケーションの開発を行った。 都道府県について理解する中でも、 とりわけ重要だと考えられる都道府県の歴史を効率よく学習するために、 年表の自動生成や歴史上の出来事や人物を自動検出といった機能も実装した。 そしてそのアプリケーションを使用して、 学習効率の高い問題ができたかを評価する。

予備知識

本章では、本研究で使用した技術について述べる。

XML

XML(Extensible Markup Language)とは、文章の構造や意味を記述できる マークアップ言語の一つである。マークアップ言語とは、 文章中にタグを付与する事により、文章構造(見出しや段落、箇条書き)、 見栄え(文字の色、大きさ)などの情報を埋め込む事に対応した言語である。 文章構造の記述に特化したマークアップ言語として開発された SGML(Standard Generalized Markup Language)から派生して、 World Wide Web Consortium(W3C)によって記法や仕様が策定、勧告されている。 XMLで記述された文書の事は、XML文書と呼ぶ。 プログラム中でXML文書を利用する際は、 XMLパーサと呼ばれるソフトウェアを用いてプログラム中で扱いやすい 形式のデータに変換してから利用する。

XMLはタグによって文章に情報を付加できるが、 ユーザー側で独自の意味のタグを作ることも可能である。 統一された記法を用いながらも、独自の意味を持たせることができるため、 様々な情報をコンピュータ上で扱うために利用される。 下図に、XMLを使用して連絡先データを記述する例を示す。 (ただし行番号は説明の便宜上付けたものであり、本来不要である。)

XMLを使用した連絡先データの例 XMLを使用した連絡先データの例

次に、XML文書の記法について簡単に説明する。 文章の情報を付加するためのタグは、情報の意味を表す文字列を <>で囲むことで表す。 タグには「開始タグ」と「終了タグ」の2種類あり、 それぞれ<文字列></文字列>で表す。 情報を付加したい文字列を、開始タグと終了タグで囲むと、 その文字列には情報が付加された事になる。 開始タグと終了タグで囲むと、その部分は「要素」と呼び、 タグで囲んだ内容は「要素の内容」と呼ぶ。 例えば、2行目に<contacts>から、 25行目の</contacts>までをcontacts要素と呼び、 3行目から24行目までが、contacts要素の内容である。

XML文書では、要素の中に更に他の要素を含むことができる。 図1のXML文書の例では、contacts要素は2つのperson要素を含んでおり、 この場合はperson要素はcontacts要素の子要素であるという。 この規則は主に、各要素同士の関係性を表すために利用される。 例えばこのXML文書では、contacts要素の子要素は連絡先の情報であることを示す。 現在contacts要素には個人の連絡先を示すperson要素が含まれているが、 もしcontacts要素に会社の連絡先を示すcompany要素などが追加された場合でも、 連絡先の一つとして扱うことができる。

XML文書中で、一番最初に登場する要素(図1ではcontacts要素)は 最上位要素という。最上位要素は通常、XML文書中に1つしか存在できない。 そのためXML文書は、基本的に最上位要素の開始タグ及び終了タグの間に 記述することとなる。 また、最上位要素の直前には、XML宣言を記述する必要がある。 XML宣言とは、使用するXMLのバージョンや文書の文字コードを宣言するもので、 図1では1行目がXML宣言にある。

XML文書内の要素には「属性」を指定することができる。 属性は要素に追加できる情報のことで、名前と値の組み合わせである。 開始タグの要素名以降に、属性名="属性値"と書く。 半角スペースで区切ると複数の属性について記述できる。 例えば、4行目のlast_name要素の内容は名字だが、 読み方の情報を付加するためにruby属性を指定している。 また、10行目では住所について記述するaddress要素に、 郵便番号の情報を付加している。

XML文書を構成する要素や属性、要素内にあるテキストなどは、 それぞれ「要素ノード」、「属性ノード」、「テキストノード」と呼ぶ。 特に前述の「最上位要素」は「ルートノード」とも呼び、 XML文書は最上位要素がルートノードのツリー構造で表すことができる。 図1のXML文書をツリー構造で表した図を以下に示す。

ツリー構造 ツリー構造

以上の知識を踏まえて、本研究で扱うWikipediaの記事を 解析するために必要となるXHTMLについて説明する。

XHTML

Webページを記述する事に特化した、HTMLと呼ばれるマークアップ言語を、 XML準拠になるように一部の仕様を変更したのがXHTMLである。 XHTMLでは、Webページを構成するための要素が数多く定義されている。 下図に簡単なXHTML文書の例を示す。

XHTML 簡単なXHTML文書の例

また、XHTMLにはいくつかのバージョンが存在し、 バージョンごとに利用できる要素や属性が異なる。 文書のバージョン宣言の事を「DOCTYPE宣言」と呼ぶ。 上図では2行目から3行目の部分がDOCTYPE宣言にあたる。

次に、XHTMLで定義されている代表的な要素を以下の表に示す。

XHTMLで定義されている主な要素
要素名説明使用例
html XHTMLの最上位要素。 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
...
</html>
head XHTML文書のヘッダ情報を記述する。 子要素にtitle要素が含まれていなければならない。 <head>
<title>ページタイトル</title>
</head>
title XHTML文書のタイトルを記述する。 <title>ページタイトル</title>
body XHTML文書の本文を記述する。 <body>
...
</body>
h1, h2, h3, h4, h5, h6 見出しを記述する。数字が小さいものほど優先度が高い。 <h1>e-ラーニング用問題自動生成サービスの制作と評価</h1>
p 段落を記述する。 <p>Webページを記述する事に特化した、 HTMLと呼ばれるマークアップ言語を...</p>
<p>また、XHTMLにはいくつかのバージョンが存在し...</p>
br この要素が挿入された場所で強制的に改行する。 この要素はテキストノードを含めることはできない。 この場合は、終了タグの代わりに<br />と記述する。 <p>ここで改行→<br />
します。
ここは改行→
しません。</p>
a 別のHTML/XHTML文書へのリンクを記述する。 文書内の特定の位置に移動するという情報も追加できる。 別の文書へのリンクの記述の例:
→<a href="appendix.html">付録ページ</a>
文書内の特定の位置に移動する記述の例:
<a href="#auto_generation">例題の自動生成アルゴリズム</a>
div これ自体は特に意味を持たない要素で、 内容を含むブロックを構成する。 属性を付与してスタイリングに使用したり、 他の要素をまとめるために使用する。 <div id="bodyContent">
<div class="section">
<p>本文</p>
...
</div>
</div>
img この要素が挿入された場所に画像を表示させる。 br要素と同様の理由により、<img 〜 />と記述する。 <p>これがテスト画像です。
<img alt="テスト画像" src="image.png" />
</p>
ul, ol, li リストを記述する。ulは並列列挙リストで、 項目の順序が重要な意味を持たないリストを記述するのに使用する。 olは順序付きリストで、 順序が意味を持つ場合はこちらを使用する。 liは、ul, olの子要素で、リスト項目を記述する。 ulの使用例:
<p>用意する材料は以下の通りです。</p> <ul>
<li>肉150g</li>
<li>にんじん1個</li>
</ul>
olの使用例:
<p>以下の手順で作業を行ってください。</p> <ol>
<li>電源をONにする</li>
<li>30秒待つ</li>
<li>プログラムを実行する</li>
</ol>
dl, dt, dd 定義リストを記述する。ある用語などの名前をdt要素で 定義し、dd要素で直前に定義した用語の説明を行う。 <dl>
<dt>XML</dt>
<dd>Extensible Markup Languageの略で、 文章の構造や意味を記述できる マークアップ言語の一つである。</dd>
<dt>Wikipedia</dt>
<dd> ウィキメディア財団が運営する インターネット百科事典のことである。</dd>
</dl>
table, tr, th, td 表を記述する。trで行、thで見出し、tdで列を記述する。 <table>
<tr> <th>単語</th> <th>意味</th> </tr>
<tr> <td>language</td> <td>言語</td> </tr>
<tr> <td>node</td> <td>節, ノード</td> </tr>
<tr> <td>space</td> <td>空間</td> </tr>
</table>

DOMとXPath

DOMとは、Document Object Modelの略であり、 World Wide Web Consortium(W3C)が公式に公開しているAPIである。 XML文書をDOMツリーと呼ばれるツリー構造として扱う事ができる。 ツリー構造とは、「2.1 XML」節の図2で示した通りである。 DOMツリーを生成するために、長いXML文書であるほど多くのメモリを要求する。 しかし、XML文書中の特定の要素へのアクセスを素早く行う事ができるため、 プログラム中でXML文書を扱う際によく利用される。

XPathとは、XML文書の特定の要素・属性がある位置を指定する言語構文である。 下図に、XML文書から「あるdiv要素の子要素になっているh2要素」 を指定するために使用する構文の例を示す。

XPath XPath

図3は、ロケーションパスと呼ばれる式を用いてXML文書中の要素を示した例で、 XPathではよく使われる表記方法である。 ロケーションパスの書き方についての詳細はここでは説明せず、 本研究で使用した表現のみ紹介する。

本研究で使用した表現
表現意味使用例
//要素 要素とその子要素を全て選択 //div/ (文書中のdiv要素及びその子要素を全て選択)
要素[@属性名='属性値'] 属性名が属性値の要素を選択 //p[@class='test']  (文書中のclass属性がtestのp要素を全て選択)
要素/* 要素の子要素を全て選択 //div/p/* (文書中の、div要素の子要素になっている p要素の子要素を全て選択)

XPathは、様々なプログラミング言語で利用可能である。 (例:PHP, Java, JavaScript等) 通常は、DOMとXPath式を表す文字列を与えると、 ノードの集合を配列として受け取ることができる。

問題の自動生成

まず、学習者と教師が居る学習モデルについて考える。 教師は学習目標を設定し、その学習目標を学習者が達成できるように 授業や宿題、小テストなどの課題を学習者に与える。 学習者は課題をこなし、成果を教師に提出する。 そして、提出された成果より、 教師は学習者が学習目標を達成しているかを評価する。 以上が、学校教育等で主に使用される一般的な学習モデルである。 eラーニングは、 上記のうち教師が行う仕事の一部をコンピュータが担うものである。 具体的には、学習者が行った小テストの採点、評価の管理を行う事ができる。

一方で、eラーニング用教材である小テストなどのデータは、 予め教師が用意しておかなければならない。 当然ながら学習者の一人一人の学習ペースはみな異なるため、 学習者に応じた教材が必要となる。 しかし、一人一人に最適な教材を用意していては、膨大な時間が掛かってしまう。 そこで、学習者の意思で学習したい問題を自動生成する事により、 学習ペースを保ちながらも教師が教材を作る手間を省くという方法を提案する。 教師が学習者用に問題を用意する負担を削減するだけではなく、 学習者が自主的に勉強するケースにも適用できる。 予め重要単語などをまとめたデータを用意し、そこから問題を自動生成することで 教師の負担を削減させる事を目的とした先行研究も存在する [。 本研究では、問題の自動生成を行う際に予め用意する必要がある データ量を最小限にとどめつつ、質の良い問題を生成することを目標とする。

良い問題とは

私は、これまでに様々な学校教育を受けてきたが、その経験から感じたことは どの科目でも通用する良い問題の形式は存在しないという事である。 例えば漢字の問題では、微妙に違う漢字について読み書きを問う問題や、 「とめ、はね、はらい等」を覚えていないといけない漢字について問われる。 また、算数の問題では繰り上がりの練習をさせるために敢えて 繰り上がる組み合わせの計算を中心に問われる事があった。

漢字の問題 漢字の問題
算数の問題 算数の問題

上図に例示される、やや難しい問題を解いた方が学習効率が良いと感じた。 しかしこれはあくまでも筆者個人がそう感じたに過ぎず、 人によっては、 繰り上がりの計算は得意なので同じ時間を使って文章題を練習をしたい、 と思う場合も考えられる。 そのため、学習者一人一人に対して最適な問題を用意しなければ、 学習者全員が最高の学習効率を得ることはできない。 一人一人に最適な問題を用意することは、 学習者の人数にもよるが現実的ではないため、妥協点を見つける必要がある。

そこで、学習者の基礎的な能力・知識を向上させる形式の問題を出題する ことを提案する。例えば漢字を覚えたい時は、 漢字ドリルなどで漢字の読みや書きを何度も繰り返し学習して覚える。 算数や数学では、計算精度を高めたり公式を覚えるために問題を繰り返し 解いて学習する。 上記の例に共通することは、問題を反復して解くということである。 反復学習形式であれば、内容のレベルにもよるものの、 少なくとも学習効果が全く得られない学習者は居なくなると考えられる。 そして、充実した反復学習を行うためにはより多くの問題を揃える必要があるが、 問題の自動生成を行うことで問題を用意する負担を大きく軽減できる。

問題をコンピュータなどによって自動で生成する場合、 質の良い問題の作りやすさは科目によって大きく異なる。 例えば算数の計算ドリルを自動生成する場合、 テンプレートとなる計算式を用意し、その式で使われる数字を 乱数によって変化させただけのものでも十分である。 ただし、電卓を使わなければ困難な計算を要求することがないように、 数字の範囲はある程度決めておく必要はある。 他にも、繰り上がり/下がり等の計算をさせるために、 値を1つ決めたら次の値は繰り上がり/下がりが発生する値にする事も 簡単に行うことができる。 この方法の場合、事前に用意しなければならないものが少ないため、 問題を作る負荷が低い。

算数の問題を自動生成する方法の一例 算数の問題を自動生成する方法の一例

次に、漢字や歴史の問題を自動生成することを考える。 学校教育などで利用できる漢字の問題を出す場合、 文部科学省の定める学習指導要領 [に記述されたものから 出題することが効果的である。また、出題範囲を広げるならば、 文部科学省の定める常用漢字 [を使用することになる。 出題範囲が決まったが、その中から漢字の読みを問う問題を生成するためには、 各漢字の「出題のために必要となる情報」(音読み、訓読み、画数など)を コンピュータで扱える形式で記録しなければならない。 そのうえ、読みを問う問題では音読みか訓読みかが重要となってくるため、 出題する漢字を使用した文になってなくてはいけない。 また、問題の質を向上させるためには、 間違えやすい漢字や頻出漢字などの情報も必要である。 よって、算数の問題を比べると負荷が大きいといえる。

漢字の問題を自動生成する方法の一例 漢字の問題を自動生成する方法の一例

算数のように多くの問題を解かせて学習者の処理能力を高めることを目的とした 問題の生成は比較的楽だが、その他の知識問題を生成するとなると、 前述の通り人的負担が大きくなってしまう。 問題を用意する負担を軽減するために自動生成を行うのに、 別の面で負担が大きくなってしまうのでは本末転倒である。 そこで、負担を減らすために、「出題のために必要となる情報」を 教師が作るのではなくコンピュータに自動で集計・ 生成させるということを提案する。

コンピュータに情報を集計・生成させるためには、情報源が必要となる。 本研究では情報源として、インターネットに接続できるコンピュータであれば 容易にアクセスできる、Webサイトを利用することにする。 近年、Webサイトを利用して様々なジャンルの情報が得られるようになってきた。 国語や歴史などを学習するためのWebサイトなども、 個人・法人問わず趣向を凝らしたサイトが多くの人々によって公開されている。 そのため、我々は自分が知りたい様々な情報をWebサイトから得る事ができる。

しかし、コンピュータがWebサイトからの情報を収集する場合、 注意すべき事がいくつか存在する。まず、世界中のWebサイト上の情報は、 記述方法が統一されているわけではないという事である。 コンピュータによってあるWebサイトから情報を取得する方法が、 別のWebサイトでも通用するとは限らないため、 Webサイトの数だけ情報を得るアルゴリズムを作らなければならない。 また、Webサイト上の情報が必ずしも文字で書かれているとは限らない事もある。 Webサイトのデザインのために文字が画像を使って表現されている場合、 人間なら一目で分かるが、コンピュータが文字として認識することは困難である。 更に、そのWebサイト上に掲載されている情報を利用するために、 著作者の許可を得なければならない事もある。

上記の内容を考慮した結果、本研究では情報源となるWebサイトには 百科事典サイトWikipediaに絞ることにした。 次節でWikipediaについて述べる。

Wikipediaについて

Wikipediaとは、アメリカ合衆国のNPO非営利団体、 ウィキメディア財団が運営するフリーの百科事典サイトである。 百科事典の名の通り、ある言葉について調べると、 調べた言葉について書かれた専用の記事が開くようになっている。 英語、日本語をはじめとした多くの言語で利用することができ、 日本語の記事だけでも2011年12月現在で約78万本の記事が存在する。 全ての編集者には平等に権限が与えられているため、編集方針に反した 不適切な記事の修正・削除なども、 ウィキメディア財団側が関与することなく行われる。 特定のスポンサーによる広告などは存在しないため、 中立的な観点で物事についての記事を書くことができる。

Wikipedia Wikipedia

記事の作成・編集などの操作を、Wikipediaを閲覧できる環境がある者ならば 誰でも行うことが出来るのが特徴である。 ただし、所謂荒らし行為を行うユーザーは編集をブロックされる。 また、誰でも編集を行えるという特性上、ある記事に対して複数の編集者による 編集合戦が発生することもあるが、その場合は匿名ユーザーによる 編集を拒否するシステムが組み込まれている。

編集方針が明確に定められており [、 編集者はそれに従って記事の編集を行っている。 不特定多数の編集者が記事を編集し、記事の内容が明らかに誤っているものや 上記の編集方針に相応しくないものは、別の編集者が訂正することができる。 Wikipediaのシステムとして、記事ごとにノートページ [という、 内容について利用者・編集者が質問や議論を行う場が用意されており、 百科事典の記事として洗練することに役立てられている。 記事の洗練が行われている例としては、 Wikipediaの「集会の自由」という記事が挙げられる。 (http://ja.wikipedia.org/wiki/%e9%9b%86%e4%bc%9a%e3%81%ae%e8%87%aa%e7%94%b1) この記事は、記事作成当初は悪ふざけであるとみなされていた [。 しかし、不特定多数の編集者により幾度もの編集が加えられ、今に至っている。 これは、記事の変更履歴から確認することができる。

では、上記の特徴を持つWikipediaは、 問題の自動生成に利用する情報源としてふさわしいのかどうかを考える。 まず記事の内容だが、百科事典の体裁をとっているだけあって 質の差はあれど学習に利用するには申し分ないと判断した。 不特定多数の人々が編集することから内容の信憑性が疑問視されるが、 先に説明した記事を洗練するユーザーの動きもあることも考慮すると 全く利用できないという程でもないと言える。 次に記事の扱いやすさだが、Wikipediaの記事は、 解説に図などが利用される事もあるが、本文は基本的に全てXMLで表される。 そのため、記事の情報をコンピュータで扱う事は容易である。 更に、Wikipediaの記事の内容を二次的著作物において利用することは 許可されている。 以上より、前節で挙げた注意点をクリアしていることから、 Wikipediaを情報源として使用することにした。

例題の自動生成アルゴリズム

本研究では、ユーザーの学習用として使える穴埋めや選択形式の問題を Wikipedia上の記事から自動生成することを目標とする。 しかし、あらゆるジャンルの問題生成アルゴリズムを全てカバーすることは 困難である。 そこで、出題する問題のジャンルを絞ることで、 より出題精度を高めることにした。 自動生成問題による学習の一例として、 問題のジャンルを日本の都道府県に限定し、 日本の都道府県について学習できる問題を生成するアルゴリズムを提案する。

本章では、記事の分析方法、並びに問題の自動生成方法について述べる。

記事の分析方法

本研究ではWikipediaを情報源として扱うため、 まずはWikipediaの記事について述べる。

Wikipediaの記事は、独自のウィキテキスト言語に従って記述されている [。 しかし、記事を利用する際はWikipediaが使用するウィキソフトウェアの MediaWikiが自動的にXHTML文書に変換する。 このときのXHTMLのバージョンはXHTML 1.0 Transitionalである。 よって、記事を分析する際はWikipediaの記事をXHTML文書として 扱うこととなる。この場合、下図のように見出しや本文が書かれた部分を XMLパーサによって取り出すことができるという利点がある。

Wikipedia記事の一例 Wikipedia記事の一例

また、Wikipedia記事から情報を取り出すために、XPathを使用する。

多肢選択式問題の自動生成

本研究で扱う多肢選択式問題は、問題文をWikipediaの記事中から抽出して生成し、 問題文の内容に該当する都道府県名を選択する、という形式のものである。 多肢選択式問題は、選択肢の内容がどれも同じ分類のものになるのが 問題としては理想であると考えられるため、上記の形式を提案する。

では、都道府県名以外を答えさせる問題が向かない理由は何故か。 例えば、ある都道府県の主な農産物を答えさせる問題で、 正解が「リンゴ」だということが記事から自動的に検出できたとする。 この場合、他の選択肢は数ある農産物からランダムで選出することになる。 しかし、都道府県の主な農産物が一つに定まるとは限らないため、 選出された選択肢によってはリンゴ以外も正解となる可能性がある。

しかし都道府県を選ばせる問題であれば、そもそも問題文が都道府県の事を 書いた文章から生成されているので、選択肢が一つに定まりやすい。

以上の理由により、都道府県の名前を選択させる問題形式とした。 次に、実際に多肢選択式問題を生成する方法について述べる。

Wikipediaの都道府県についての記事中には様々な項目があるが、そのうちの 「概要」と、「目次の前に書いてある文章」を利用する。 この2つの文章は47都道府県の記事ほぼ全てに存在し、各都道府県の特徴を 捉えているため、問題にしやすいためである。

概要の文章 概要の文章
目次の前に書いてある文章 目次の前に書いてある文章

概要の文章を取得するには、まずは次のXPathを使ってh2要素を取得する。

//div/h2

h2要素を全て取得したら、その中からテキストノードが「概要」の要素を探す。 「概要」ではなく「概説」となっている記事も存在するので、「概説」も探す。 次に、h2要素の次に存在する要素を順番に見ていき、テキストノードを バッファに貯める。ただし、h2〜h6要素や、table要素が見つかった場合は その時点で検索を終了し、バッファの内容を「概要の文章」として記録する。

概要の文章取得方法 概要の文章取得方法

これに対し、「目次の前に書いてある文章」の取得方法は少し異なる。 この文章は、XML文書上では、基礎データが書かれたtable要素の次に存在する。 そのため、まず基礎データが書かれたtable要素を次のXPathで取得する。

//div/table[@class='infobox bordered']

取得した要素の次に存在する要素を順番に見ていき、テキストノードを バッファに貯めていく。終了条件や終了後の処理は概要の時と同様である。

目次の前に書いてある文章の取得方法 目次の前に書いてある文章の取得方法

上記の方法で文章を取得できたら、取得した文章を句点で区切り、一つ一つを 文に分ける。このときに出来た文が問題文の候補となる。

問題文の候補を生成 問題文の候補を生成

次に、それぞれの文に対して語尾の変換を行い、問題文らしい文章にする。 また、問題として適切でない表現を含むNGワードリストを使用して、 NGワードに該当する表現がある問題文は候補から取り除く。

NGワードに該当する表現を削除し、問題文らしい文章に変換 NGワードに該当する表現を削除し、問題文らしい 文章に変換

あとは、この問題文に選択肢を追加すれば問題が完成する。 都道府県名を選ぶ問題なので、正解以外の選択肢は都道府県名からランダムで 選択することにした。

穴埋め問題の自動生成

本研究で扱う穴埋め問題は、問題文の一部を隠し、隠した部分をユーザーに記述 してもらう形式である。問題文の生成方法は、多肢選択式問題の問題文の候補を 取得する方法を一部流用する。概要などから文章を取得し、 句点で区切る所までで完成である。

学習効率の高い穴埋め問題を生成するためには、ユーザーが覚えるべき 重要度の高い単語を穴埋めにできることが必要である。 そのために、47都道府県の記事全てに登場する単語とその単語の「情報量」を まとめたデータベースを作成し、問題文中に情報量の高い単語を見つけたら その部分を隠すアルゴリズムとした。

単語と情報量をまとめたデータベースを作成するために、まず単語を47都道府県 全ての記事中から抽出する。 本研究では、記事中のリンクとなっている要素(a要素)のテキストノードの 内容を「単語」とする。

単語の抽出 単語の抽出

また、ここで使用する単語の「情報量」とは、情報理論の平均情報量 (エントロピー)を指す。この値が高いほど、その単語は重要であると みなすことができる。 そこで図18に示すエントロピー関数に当てはめて単語の情報量の算出した。 ただし、Xは47都道府県全ての記事のうち単語が1度でも登場した記事の数を、 47で割った値である。

エントロピー関数 エントロピー関数

以上の方法で取得した単語及び情報量を、データベースにまとめておく。 このデータを用いて、穴埋めする単語を決定する。

単語データベース 単語データベース

まず、多肢選択式問題の時と同様に問題文を生成する。 次に、前述した単語データベースを情報量の値で降順ソートし、 情報量の高い順に単語を選び、その単語が問題文中に含まれているか検索する。 単語がある場合はその部分を隠すことで穴埋め問題にする。 単語がない場合は次の単語で再度検索を試みる。

穴埋め問題生成方法 穴埋め問題生成方法

以上の処理を繰り返すことで、穴埋め問題を生成することができる。

単語群問題の自動生成

穴埋め問題の場合、回答者は隠れている正解の単語を完全に覚えている 必要がある。しかし、学習を始める最初の段階で正解を完全に覚えていることは 考えにくい。全く分からない事に対して正確な解答を求めるのは酷であり、 答えが分からない問題ばかりでは学習意欲の低下に繋がるのではないか、 と筆者の経験から感じた。 また、単語群を利用した選択問題は義務教育における歴史科目の小テスト等で 実際に利用されている [ため、 学習効率やモチベーションの向上に一定の効果があるとみなすことができる。 本研究では、問題文の穴埋めを、予め用意した単語群から選んで 埋める形式の問題を提案する。

また、問題文は多肢選択式問題や穴埋め問題とは別に、次の方法を用いて生成する。 単語群問題では問題文自体にある程度の長さが必要なため、記事中の概要などの 問題文として使える文章を、 問題文として適切な長さで区切って使用することになる。 区切った部分で文が途切れていてはならないので、 文の終わりである句点で区切る必要がある。しかし、単純に句点で区切る場合は 段落の区切りが分からないため、不自然な問題文ができあがる可能性がある。 下図は、段落を無視して句点で区切った例である。

不自然な問題文 不自然な問題文

そこでXHTMLではp要素が「段落」を意味していることを利用し、 記事の文章をp要素ごとに区切り、連結して問題文とする。 下図はp要素ごとに区切った例である。

自然な問題文 自然な問題文

実際に単語群問題を生成する方法について述べる。 まず「概要」の項目の文章を、p要素ごとに分ける。 次に、分割したp要素のテキストノードをバッファに追加していく。 そして、バッファの内容がある一定の文字数(本研究では暫定的に300文字とした) を超えたら、バッファの内容を問題文とする。 これを、取得できたp要素がなくなるまで繰り返す。

単語群問題の問題文生成 単語群問題の問題文生成

次に、問題文から穴埋めにする場所を決定し、単語群を生成する処理を行う。 前項で述べた単語データベースを利用し、重要度の高い単語から順番に選び、 本文にその単語があるかを検索する。 単語があった場合、その部分を穴埋めとし、単語群に追加する。

具体的な処理方法を説明する。 まず、単語データベースから単語を重要度の高い順に取り出していく。 この時取り出した単語をWとする。問題文中にWが含まれているかを検索し、 単語が見つかった場合は、問題文中のWを全て#n#(nは数値)と置き換える。 この時#n#と置き換えた単語は、単語とnが対応するように配列に記録しておく。 nは、単語データベースに含まれる単語を見つけるごとに、 1ずつ増えていくカウンタである。 ただし、見つけた単語が既出の場合は、その単語に対応する#n#と置き換え、 カウンタは増やさないものとする。 #n#は後にアルファベット大文字のA〜Z及び小文字のa〜zに置き換える。 よってnが52(アルファベット26種類×2)になったら、単語の検索を終了する。

単語群問題の穴埋め及び単語群の生成1 単語群問題の穴埋め及び単語群の生成1

図22は、前述の操作が終了した直後の状態である。 この状態では、見つかった単語全てが穴埋めとなっている。 主観的に判断すると、単語群形式の問題としては穴の数が多い。 そこで、穴の数をランダムである程度減らすことにする。 問題を生成するたびに穴埋めの場所が毎回変化するので、反復して勉強をする 意欲の向上に繋がるではないかと考えられる。

本研究では、暫定的に、穴埋めにした箇所の6割程度を元の単語に戻すことにする。 前の処理で予め記録しておいた単語をランダムで選出し、 対応するキーから元の単語に直す。

単語群問題の穴埋め及び単語群の生成2 単語群問題の穴埋め及び単語群の生成2

最後に、穴埋めにした箇所に先頭から順番に数字を振っていく処理を行う。 #n#(nは数値)となっている箇所を先頭から順番に探し、 発見したらその場所を( m )(mは数値)と置き換える。 そして、mと「#n#が表す単語」が対応するように配列に記録する。 この配列をシャッフルし、アルファベットA〜Z及びa〜zを振ったものが、 回答者が見る単語群となる。

単語群問題の穴埋め及び単語群の生成3 単語群問題の穴埋め及び単語群の生成3

歴史についての問題の自動生成

Wikipediaの47都道府県の記事には、どの記事においても歴史についての記述が 存在する。それらを利用して、都道府県の歴史についての問題を出題すると より深く都道府県について学べるかもしれない、と考えた。 本章では、記事中の歴史に関する記述から問題を生成する手法に ついて述べる。

準備

歴史について学ぶ際は、歴史上の出来事や人物などが重要になると 考えられる。しかし、前述の単語データベースには「歴史上の出来事・ 人物かどうか」という情報はない。そこで、単語データベースを 情報量が高い順に並べ替えた時、「歴史上の出来事・人物の単語」が 優先して選ばれるようにする。

歴史上の出来事・人物の単語を47都道府県の記事から取得する方法に ついて述べる。まず、記事中の「歴史」の項目の文章を全て取得する。 そして、文章中の全てのa要素(リンク)が持つhref属性(リンク先)が 示す記事を読み込む。

歴史上の出来事・人物の単語の候補を探す 歴史上の出来事・人物の単語の候補を探す

次に、リンク先記事の要素群を、次のXPathを使って取得する。

//div[@id='bodyContent']/div[@class='mw-content-ltr']/*

上記のXPath構文は、id属性値がbodyContentのdiv要素の中にある、 class属性値がmw-content-ltrのdiv要素が持つ全ての子要素を表す。

要素群の先頭要素のテキストノードに、「○○年」という表現が含まれて いないかどうかを調べる。 含まれていた場合は、リンク先の記事名を「歴史上の出来事・人物」の単語 だと見なす。含まれていない場合は、次の要素にて同様の処理を行う。 この処理を要素を3つ辿るまで行い、上記の表現が含まれていなかった場合は 「歴史上の出来事・人物」の単語では無いということにする。

歴史上の出来事・人物の単語かどうか判定する 歴史上の出来事・人物の単語かどうか判定する

「歴史上の出来事・人物」の単語だと判断した場合は、 その記事の長さを取得する。重要な出来事ほど記事に書くことが多く、 長くなる傾向があるため、記事の長さを取得することで 「歴史上の出来事・人物」の中で更に重要度のランク付けを行うことが できるためである。 ここでいう記事の長さとは、記事をXML文書として見たときの文字数である。 記事の長さを取得できたら、単語データベースに登録を行う。 記事の長さの値を情報量の項目に登録する。情報量は0〜1の値になるため、 必然的に1以上になる記事の長さを情報量として記録しておけば、 通常の穴埋め問題の時と同じアルゴリズムを使いつつ 歴史上の出来事・人物の単語を優先させることができる。

また、歴史に関する問題を生成し易くするため、 記事中の文章から都道府県の年表を生成する機能を実装した。 これは歴史上の出来事・人物の単語を取得する時と同様に、 記事中の「歴史」の項目の文章を利用する。 文を順番に見ていき、日付と出来事が書いてある文があった場合は、 正規表現を使用して日付と出来事を分けて、年表として記録する。 使用した正規表現については数が多いため、付録に記載する。 記事によってはリスト形式で年表が書かれており、 そういったものは非常に利用し易い。

年表の生成 年表の生成

歴史についての多肢選択式問題

4.5.1 準備で生成した年表を利用して、多肢選択式問題を生成する。 何年にどんな出来事があったのかを、選択肢から選ぶ形式である。 この形式の場合、選択肢をどのように生成するかが重要である。

n年に起きた出来事を選ぶ問題で、選択肢にnと大きく離れたm年の 出来事が書いてある場合、その選択肢はあまり意味のないものに なってしまうと考えられる。例えば、西暦600年に青森県で起きた出来事を 答える問題で、選択肢に青森駅の話が書いてあった場合、 それはまず正解ではないと容易に予想することができる。

こういった事が起きにくくなるように、出来事の選択肢はなるべく 正解の前後100年以内から選出するようにした。 しかし、正解と非常に近い日に起きた出来事が選択肢に選ばれる事もある。 それでは問題自体の難易度が上がりすぎてしまうため、正解の前後10年からは 選択肢を選出しないようにした。

選択肢の選出方法 選択肢の選出方法

では、実際に問題を生成する方法について述べる。 まず最初に、正解となる年数を、 年表に含まれる出来事の年数から適当に決める。 この時に決めた年数によって、 問題文は「○○県で□□年の出来事を答えよ」と定まる。 次に選択肢を選出する処理を行う。 最初に、年表のデータを予め全てバッファに入れる。 その後、バッファから正解と正解の前後10年以内のデータを削除する。

選択肢選出方法1 選択肢選出方法1

更に、前後100年以上のデータを削除扱いとする。 もし、この処理によってバッファに格納したデータの数が 4個未満になってしまった場合は、 正解の年数に近い順にデータの削除扱いを解除する。

選択肢選出方法2 選択肢選出方法2

あとは、バッファに残った選択肢から出来事をランダムで4つ選べば、 問題が完成する。

歴史選択問題の完成 歴史選択問題の完成

歴史についての穴埋め問題

歴史穴埋め問題は、5.3. 穴埋め問題の自動生成で述べた アルゴリズムを、先に生成した年表に適用することで生成する。 その際、「歴史上の出来事・人物」の情報を活用し、 歴史を学ぶ上で重要度の高い単語が優先して穴埋めになる。

歴史穴埋め問題の出題イメージ 歴史穴埋め問題の出題イメージ

歴史についての並び替え問題

歴史上の出来事を覚える際、出来事が発生した具体的な日付が あまり重要ではないものもあると考えられる。 そこで、出来事を発生した時系列順に並び替える問題を 出題することにした。

歴史並び替え問題の生成方法について述べる。 まず、歴史選択問題の時と同様に、年表のデータを全てバッファに入れる。 次に、バッファの中からランダムで1つずつデータを取り出し、 別のバッファに溜める。

歴史並び替え問題生成方法1 歴史並び替え問題生成方法1

データが4つ溜まったら、4つのデータの順番をシャッフルし、 問題文を生成する。

歴史並び替え問題生成方法2 歴史並び替え問題生成方法2

Wikipediaの問題点

本章では、本研究を進めていくなかで遭遇したWikipedia側の 問題点について述べる。

システム側の問題

XML文書では、文書中に含む事ができる文字が予め定められている。 XMLの定義によると、Unicodeコードで

Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

を含む事ができる[。 #x9はタブ文字、#xAは改行文字, #xDは復帰文字を示している。

上記以外の文字は本来含まれてはならないのだが、Wikipedia上の一部の記事に Unicodeコード0000が含まれているものが存在した。 このため、XMLパーサで記事を解釈する前に、予め禁止文字を削除する必要があった。

また、XML文書では、あらゆる要素のID属性の値が同じ文書中で 被ってはならないと定められている[。 しかし、脚注の項目で、同じISBNの書籍を参照している場合にID属性値が被る 事を確認した。 このため、XMLパーサで記事を解釈する前に、被っているID属性を調べ 修正する必要があった。

また、Wikipediaの記事はDOCTYPE宣言によるとXHTML 1.0 Transitionalで 記述されている。 しかし、XHTML 1.1で追加されたルビ関係の要素を使用している記事が いくつか存在した。 今回使用したXMLパーサ(XPath)では、Warningメッセージが出るだけで 文書の解釈を行う事ができたが、パーサによっては予め文書に修正を 加えなければならない可能性がある。

以上より、Wikipediaのシステム側が出力する文書は必ずしも 妥当な文書ではないので、WikipediaのデータをXMLパーサで解釈する際に、 記事の内容と関係ない事に関して修正を加える必要がある。

編集者の問題

本研究で使用した記事の解析法を使う場合、(ある程度の修正を行ってはいるが) 記事の論理構造がXHTML文書として正確に記述されている必要がある。 しかし、Wikipediaの編集者は世界中の不特定多数の人々であり、 全員が必ずしもXHTML文書について理解しているとは限らない。 むしろ、そのことをあまり意識しなくても記事を書く事ができるのが Wikipediaの利点でもあるのだが、記事を人間ではなくコンピュータによって 解析を行う場合は厄介な問題となる。

顕著に見られた問題として、編集者が記事の見た目のためだけに 論理構造を示す要素を本来の用途に反した使い方をしていることが挙げられる。 例えば、本来「見出し(h1〜h6)」の要素を使うべき箇所で、 「段落(p)」要素の中に「太字(b)」で装飾し、 あたかも見出しのように見せている。しかしこの記述では、Webブラウザが レンダリングした時は見出しに見えるが、XHTML文書だけ読んだ場合は ただの「段落」に過ぎない。 他にも、インデントのためだけに「定義リスト(dl, dd)」要素を使用している 記事も存在した。

Wikipediaの記事を情報源とする際は、文書の論理構造に完全に依存した 解析アルゴリズムを使用すると想定した情報を得る事ができない恐れがある。 また、この問題はWikipedia以外の多くのWebサイトにも あてはまる事だと考えられる。

結果と評価

動作環境

本研究のプログラムは表3の環境で動作確認を行った。

動作環境
機種 MacBook Air (Mid 2009)
CPU 1.86 GHz Intel Core 2 Duo
メモリ 2 GB 1067 MHz DDR3
OS Mac OS X Lion 10.7.2(11C74)

また、動作に必要なプログラムやライブラリは表4の通りである。

必要なプログラム・ライブラリ
名前 役割
Apache 2.2.19 HTTP サーバ
PHP 5.3.6 プログラミング言語
mbstring, libxml PHPエクステンション
MySQL 5.1.57 データベースサーバ

作成したプログラムは、付録「3. プログラム」を参照。

結果

本項に、作成したプログラムの実行例を示す。 以下の実験では2012年1月8日現在のWikipedia内の記事を使用している。 なお、出力した問題内容は選択肢や穴埋め箇所などをランダムで 決定している部分もあるため、必ずしも示した図の通りにならない事がある。

また、ある都道府県Aの歴史に関する問題を生成する際は、 事前に「歴史年表を生成」及び「歴史上の出来事を検索してDBに書き込む」に チェックを入れた状態で送信ボタンを押し、 Aに記述されている歴史上の出来事をデータベースに書き込む必要がある。 この作業はAの問題を生成する際に一度だけ行えば良い。

作成したプログラムの実行画面 作成したプログラムの実行画面

プログラムを実行すると、図37の画面が現れる。 図37の画面で、articleに「青森県」と入力し、 「穴埋めと選択を生成」にチェックを入れると、図38の出力が得られる。

4.2.の多肢選択式問題の生成結果 4.2.の多肢選択式問題の生成結果

正解は青森県となる。

図37の画面で、articleに「千葉県」と入力し、 「穴埋めと選択を生成」にチェックを入れると、図39の出力が得られる。

4.3.の穴埋め問題の生成結果 4.3.の穴埋め問題の生成結果

正解は灰色で書かれている部分である。

図37の画面で、articleに「香川県」と入力し、 「穴埋めと選択を生成」及び「穴埋め+単語群問題を生成」 にチェックを入れると、図40の出力が得られる。

4.4.の単語群問題の生成結果 4.4.の単語群問題の生成結果

正解は灰色で書かれている部分である。

図37の画面で、articleに「山口県」と入力し、 「歴史年表を生成」及び「歴史選択問題を生成」 にチェックを入れると、図41の出力が得られる。

4.5.2.の歴史選択問題の生成結果 4.5.2.の歴史選択問題の生成結果

正解は灰色で書かれている部分である。

図37の画面で、articleに「群馬県」と入力し、 「歴史年表を生成」及び「歴史穴埋め問題を生成」 にチェックを入れると、図42の出力が得られる。

4.5.3.の歴史穴埋め問題の生成結果 4.5.3.の歴史穴埋め問題の生成結果

正解は灰色で書かれている部分である。

図37の画面で、articleに「群馬県」と入力し、 「歴史年表を生成」及び「歴史並べ替え問題を生成」 にチェックを入れると、図43の出力が得られる。

4.5.4.の歴史並び替え問題の生成結果 4.5.4.の歴史並び替え問題の生成結果

正解は灰色で書かれている部分である。

評価

まず、情報理論の平均情報量を用いた単語データベースの有用性について述べる。 前節で示した出力から筆者は、平均情報量を用いる事で 理不尽な問題を出来にくくして、学習効率を高めるという役割は 果たせたのではないかと判断した。 逆に情報量が低い順に問題を生成すると、 難易度が高い問題が得られることが分かった。 都道府県独特の行事など、 都道府県を理解するためには重要となる単語は情報量が低くなるため、 そういった分野から出題する場合は情報量を低い順に扱った方がかえって有効な 場合もあると考えられる。 以上より、 平均情報量は問題を生成する上で十分利用する価値があるものだと判断した。

次に、問題形式ごとに生成結果についての評価を述べる。

多肢選択式問題は、概要の文章から問題文を生成するものである。 概要では確かに特定の都道府県についての説明をしているものの、 都道府県特有のものだけを説明しているとは限らない。 よって、この生成方法を使用する場合、 問題の内容が他の都道府県にも当てはまる事があった。 そのため、明らかに都道府県が特定できる問題文ではない場合、 選択肢にある都道府県1つ1つに対して、 問題文の内容が当てはまるかどうかをチェックする必要があると考えられる。

穴埋め問題も、 多肢選択式問題と同様に概要の文章から元の問題文を生成するものである。 穴埋めにする箇所については、単語の情報量を使用して決定した。 これに関しては、確かに重要な単語が選ばれる事が多く、 概ね成功していると考えられる。ただし一部問題もある。 単語の重要度は文脈によって変化するものだが、このアルゴリズムでは 穴埋めにする単語を選択する際に文脈を考慮せず、 一般的に重要と考えられる(情報量が高い)単語を選択しているため、 文章内容を考えると相応しくない単語が選ばれる事もあった。 例えば他の都道府県の記事に載らない都道府県特有の固有名詞は、 平均情報量が低くなるため、都道府県の特徴を表す重要な単語であったとしても 穴埋めの対象にはならない。

単語群問題は、上記の穴埋め問題の問題文を長くして、 穴埋めにあてはめる単語群を用意したものである。 単語群がある事で、難易度が高くなりやすい傾向にある穴埋め問題が 解きやすくなっているという特徴がある。 しかし、こちらも単語の情報量を使用している以上、通常の穴埋め問題と同様に 都道府県特有の固有名詞が穴埋めに登場しにくいという欠点がある。 また、概要の文章をほぼ丸ごと使用するため、概要の文章が 記事上の概要以外(「人口」や「気候」、「経済」等) の文章へ続けて記述されている場合は、 問題としては不自然なものとなってしまう事が判明した。 単純な穴埋め問題では、「後述」など他の見出しの文章に続きそうな 単語を発見したらその部分は除外しているため、問題は発生しない。

歴史に関する問題は、多肢選択式問題、穴埋め問題、 並び替え問題の3種類を用意した。 いずれの問題も、4.5.1.で生成した年表のデータを使用して生成しているため、 年表データの生成の出来によって問題の質が変化する。 そもそも年表が殆ど作れないような都道府県の記事も存在し、 そのような場合は有効な問題が全くといっていいほど得られなかった。

歴史選択問題は、正解の年付近の出来事やあまりに時期が離れた出来事は 選択肢に入らないアルゴリズムにしているため、 理不尽な問題が出来にくくなっていると考えられる。 ただし、Wikipediaの都道府県の記事は近年の出来事の方が多く記述されている 傾向がある。このため、かなり昔の出来事が正解になっている問題の場合、 選択肢として選出される出来事の数が限られてしまうことがある。

歴史穴埋め問題は、通常の穴埋め問題と同様に単語の情報量を使用している。 加えて、歴史上の出来事や人物を優先的に穴埋めにするようにしたため、 そういった単語が出てきた場合はほぼ間違いなく穴埋めとなっている。 しかし、実際に生成してみると、 年表上に歴史上の出来事や人物の単語が登場する頻度はやや低いことが分かった。 概要の文章の穴埋めと同じように、見出しが「歴史」の項目にある文章から 穴埋め問題を出すようにすれば、 より多くの重要単語が登場する問題を生成できるのではないかと考えられる。

歴史並び替え問題は、歴史に関する問題ならではの形式である。 選択肢を、年表データ全体からランダムで出来事を選出して生成したため、 問題の質にだいぶムラがあるように感じられた。 全く違う時期の出来事が混ざっていることもあれば、 殆ど同じような時期の出来事が並んでいることもあった。 そのため、問題の難易度は並べ替えという形式でありながら高めだと感じた。 出来事が起きた時期をより特定しやすいようなヒントが必要だと考えられる。

まとめ

本稿では、eラーニングにおいて使用する膨大な教材を用意する助けとなる プログラムを制作し、使用したアルゴリズムや生成結果、評価を報告した。 Wikipedia上の記事をもとに単語の情報量を取得し、 その情報から出題する問題の最適化を行った。 教師が重要度の高い単語を後から追加することも簡単に行うことができる。

今回は、日本の都道府県についてのみ扱った。 他の分野の問題自動生成にも対応することは、今後の課題の一つではある。 しかし、まだまだ都道府県に関することを完全にカバーできているとは言えない。 地域の特産品や祭事などの都道府県の特色について、 詳しく学べる問題の生成アルゴリズムを考え、 実装するということも今後の課題となるだろう。

参考文献

  1. 博多高等学校、iPadを100台導入――eラーニングに活用 - ITmedia プロフェッショナル モバイル, http://www.itmedia.co.jp/promobile/articles/1004/26/news072.html
  2. 宮地 功, eラーニングにおける客観テスト問題の自動生成方法の提案, 信学技報, vol. 108, no. 247, ET2008-39, pp. 1-4, 2008年10月
  3. 新学習指導要領-文部科学省, http://www.mext.go.jp/b_menu/shuppan/sonota/990301.htm
  4. 常用漢字表:文部科学省, http://www.mext.go.jp/b_menu/hakusho/nc/k19811001001/k19811001001.html
  5. Wikipedia:五本の柱 - Wikipedia, http://ja.wikipedia.org/wiki/Wikipedia%3a%e4%ba%94%e6%9c%ac%e3%81%ae%e6%9f%b1
  6. Help:ノートページ - Wikipedia, http://ja.wikipedia.org/wiki/Help%3A%E3%83%8E%E3%83%BC%E3%83%88%E3%83%9A%E3%83%BC%E3%82%B8
  7. Wikipedia:削除された悪ふざけとナンセンス - Wikipedia, http://ja.wikipedia.org/wiki/Wikipedia%3a%e5%89%8a%e9%99%a4%e3%81%95%e3%82%8c%e3%81%9f%e6%82%aa%e3%81%b5%e3%81%96%e3%81%91%e3%81%a8%e3%83%8a%e3%83%b3%e3%82%bb%e3%83%b3%e3%82%b9%232005
  8. Help:ページの編集 - Wikipedia, http://ja.wikipedia.org/wiki/Help%3a%e3%83%9a%e3%83%bc%e3%82%b8%e3%81%ae%e7%b7%a8%e9%9b%86
  9. 中学社会科問題集前編 (縄文~江戸時代) | なまら北海道だべさ, http://n-hokkaido.com/20100114/school-3/
  10. 2.2 Characters - Extensible Markup Language (XML) 1.0 (Fifth Edition), http://www.w3.org/TR/REC-xml/#charsets
  11. 3.3.1 Attribute Types - Extensible Markup Language (XML) 1.0 (Fifth Edition), http://www.w3.org/TR/REC-xml/#sec-attribute-types

付録

使用した正規表現、ソースコードなどを下記リンク先に掲載しました。
付録ページ