XQuery を使ってコンテンツを分類する

非構造化コンテンツおよび半構造化コンテンツをカテゴリー分けする

XML などの半構造化データと非構造化データの増加に伴い、簡単かつ迅速に、より関連性を持ったクエリーを行えるように、コンテンツをカテゴリー分けして分類する必要が出てきています。この記事では、XQuery を使用したコンテンツおよび構造の解析に基づくコンテンツのカテゴリー分けにより、XML 文書に自動的にタグを付ける数々の手法について試してみます。

James R. Fuller, Technical Director, Webcomposite s.r.o.

Photo of Jim FullerJames Fuller はプロとして 15 年以上の経験を持つ開発者で、自国のアメリカ、そしてイギリスの両方で数々の一流ソフトウェア会社と協力しています。技術関連の本を共同で執筆した経験があり、XML 技術をテーマとした講演、記事の執筆活動は定期的に行っています。彼は、XML Prague 設立時の委員会メンバーで、EXSLT の責任者の 1 人でもありました。彼はほとんどの時間、XML データベースと XQuery をいじって過ごしています。



2011年 3月 22日

コンテンツ分類とは、データの検索、保管、管理、そして他のプロセスへの統合を容易にするために、データを拡充して編成するあらゆるプロセスのことです。このようなメタデータを生成することで、既存のコンテンツからより多くの価値を引き出せるようになります。

よく使われる頭文字語

  • API: Application Programming Interface
  • FLWOR: For, Let, Where, Order by, and Return
  • HTML: HyperText Markup Language
  • HTTP: HyperText Transfer Protocol
  • NASA: National Aeronautics and Space Administration (米国)
  • SQL: Structured Query Language
  • URL: Uniform Resource Locator
  • XML: Extensible Markup Language

分類に伴う大きな問題の 1 つは、人々がそれぞれ独自のロジックを基準に誤った分類をすることによって、異なる分類結果に至ってしまうことです。分類システムを定義するときには、すべての利害関係者の意見を考慮して、一貫性のある手法でカテゴリー分けをしなければなりません。けれども、これには多くの問題があります。例えば、ある部門に属する人々が、別の部門の人々にとってどのメタデータが重要であるかを認識していない場合もあります。さらに、関係者が分類を理解して一貫して適用するように教育するには、かなりの時間がかかる可能性があります。

データが生成されて次第に量を増していくにつれ (これを称して「デジタルごみ処理場 (digital landfill)」という人もいます)、データを人間の手で分類するのはほとんど不可能になってきます。そこで必要となるのが、多種多様なフォーマットと入力のコンテンツを自動で解析する手法です。

分類を自動化することで、以下のような多数のメリットがもたらされます。

  • 経費を節約できること
  • 時間を節約できること
  • 分類によってメタデータを追加する共通のメカニズムが提供されるため、一貫性が生まれること
  • 組織が既存のコンテンツからより多くの価値を引き出せること

サンプル・コードのインストールおよび実行

この記事のサンプル・コードは、eXist XML Database または Zorba XQuery プロセッサーで使用する目的で作成しました。サンプル・コードを eXist XML Database で使用するには、このデータベースをインストールしておく必要があります。データベースをインストールしない場合には、オンライン・サンドボックスから入手できる Zorba XQuery プロセッサーを使用してください。

eXist XML Database をインストールする場合

eXist XML Database をインストールする手順は以下のとおりです。

  1. サンプル・コードをダウンロードして解凍します。
  2. 解凍したコードが含まれるディレクトリーをデータベース・コレクション (例えば、/db/content-classification) にアップロードします。
  3. Microsoft® Office Access® を使用している場合は、ブラウザーでサンプル・コードを実行します。

Zorba XQuery プロセッサーを使用する場合

サンプル・コードを実行するには、もう 1 つの方法として、オンライン・バージョンの Zorba XQuery プロセッサーを使用することもできます。その場合には、以下の手順に従ってください。

  1. サンプル・コードをダウンロードして解凍します。
  2. サンプル・コードを Zorba XQuery プロセッサーのオンライン・サンドボックス (http://try.zorba-xquery.com/) にカット・アンド・ペーストします。
  3. Execute (実行)」をクリックしてコードを実行します。

eXist を使用する場合と、Zorba を使用する場合の違いは、ほんのわずかしかありません。けれども、観察力の鋭い読者は、それぞれが EXPath HTTP Client ライブラリーを使用する方法に 1 つの違いがあることにお気付きのことでしょう。Zorba にはデフォルトでこのライブラリーが組み込まれていますが、eXist データベースには組み込まれていません。eXist 専用に設計されたスタンドアロンの http-client.xqm という XQuery ライブラリーを提供しているのは、そのためです。この記事の例では EXPath HTTP Client ライブラリーを使用して、リモート・データと Web サービスにアクセスします。さらに記事の後半では、YQL (Yahoo! Query Language) および AlchemyAPI のツールを使用した、さらに高度な処理を統合します。

注: これらのサービスを利用するには、サインアップして API キーを受け取る必要があることに注意してください。


XQuery を使用した単純な分類

記事の前半では、XQuery だけを使用してコンテンツを分類する初歩的な方法を説明します。

テキスト・アナリティクス: 非構造化のコンテキストでの単語の出現頻度を明らかにする

テキスト・アナリティクス (またはテキスト・マイニング) という用語は、テキスト・ソースから情報のメタデータを抽出してモデル化するためのマシン・ラーニングおよび言語に関する一連の手法を意味します。テキスト・アナリティクスは、自然言語処理 (NLP) と解析手法をテキスト・コンテンツに適用し、以下のような有用なメタデータを抽出します。

  • 言語形式: 文字コード、単語、およびコンテンツのスタイルを解析することで、テキスト・データがどの言語であるかを簡単に、しかも高い確率で判断することができます。
  • キーワード: テキスト解析では、その文書を特徴付ける一連のキーワードを抽出することができます。
  • 共通エンティティー: テキストをスキャンして共通パターン (E メール・アドレス、電話番号、人の名前や場所の名前) を見つけるアルゴリズムは、名前付きエンティティーを抽出する際に役立ちます。
  • セマンティックな関係: より説得力のある深い洞察を得る目的で、さまざまな手法を利用してコンテンツを調べます。

このようなテキスト・マイニングの一例は、単語が使われている回数が多ければ多いほど、その単語は文書全体により深く関係することを前提として、文書内に含まれる単語の出現頻度を判断することです。

最もよく使われている単語は文書のキーワードであると解釈できますが、通常は、キーワードという用語はより高度なアルゴリズムによる出力に適用されることに注意してください。その高度なアルゴリズムでは、単語の出現頻度を明らかにする以上のことが行われます。例えば、キーワード解析ではよく使われている単語を同義語のルックアップ・テーブルと相互参照するのが通常です。さらに、文書全体の文脈における単語の重要性を判断できるように、単語間の距離を解析することもできます。

あらゆるテキスト解析に共通する最初のステップは、テキスト・コンテンツからコーパス (言語資料) を生成することです。以降の解析は、このコーパスに適用されます。コーパスを生成する理由の 1 つは、テキストを正規化し、関連性のない部分をすべて取り除くことにあります。

リスト 1 に記載する XQuery プログラムは、HTML ページを取り込み (EXPath HTTP Client ライブラリーを使用)、Web ページからすべてのパラグラフ要素を抽出します。単語の大/小文字は関係ないため、コンテンツから生成するコーパスはすべて小文字です。

リスト 1. 単語の出現頻度のリストを生成する XQuery プログラム
xquery version "1.0";
import module namespace http = "http://expath.org/ns/http-client";
let $content-url     := 'http://en.wikipedia.org/wiki/Asteroid_impact_avoidance'
let $content-request := 
         <http:request href="{$content-url}" method="get" follow-redirect="true"/>
let $content         := 
         fn:string-join(http:send-request($content-request)[2],' ')
return
let $corpus := for $w in tokenize($content, '\W+') return lower-case($w)
let $wordList := distinct-values($corpus)
return
<words> {
for $w in $wordList
let $freq := count($corpus[. eq $w])
order by $freq descending
return <word word="{$w}" frequency="{$freq}"/>
}</words>

次のステップでは、コーパスから固有の単語をすべて抽出します。それには、FLWOR を使用して各単語を処理し、(すべての単語が含まれるコーパスを逆参照することによって) 単語カウントを生成してから、<word/> 要素を出力します。

注: 記事のすべての例では、それぞれの手法の有効性を明らかにするために、テキスト・ソースには同じ Web URL (http://en.wikipedia.org/wiki/Asteroid_impact_avoidance) を使用します。

リスト 1 のプログラムを実行すると、<word/> 要素が含まれる XML 文書が出力されます。ここには、ウィキペディアの小惑星衝突回避 (asteroid impact avoidance) に関するページに含まれる単語とその出現頻度が、出現頻度順に記載されます。リスト 2 に、このリストを記載します。

リスト 2. 単語の出現頻度のリスト
<words>
<word word="the" frequency="377"/>
<word word="of" frequency="236"/>
<word word="a" frequency="193"/>
<word word="to" frequency="167"/>
<word word="and" frequency="141"/>
<word word="in" frequency="124"/>
<word word="earth" frequency="121"/>
<word word="â" frequency="109"/>
<word word="asteroid" frequency="102"/>
....
</words>

上記のとおり、解析によって多数の単語が返されますが、出現頻度の多い単語のなかには、英語で一般的に使用される単語であることから関連性がないものもあります。この事態は、ほんのいくつかの単純なルールを定義し、それによってノイズの量を減らすことで修正することができます。例えば、3 文字以下の単語をすべて除外するというルールや、出現頻度が 3 回以下の単語を除外するというルールです。

リスト 3 に、単語の文字列の長さと出現頻度をテストするロジックを追加した後のコードを記載します。

リスト 3. 単語の出現頻度のリストを生成する XQuery プログラムの修正版
xquery version "1.0";
import module namespace http = "http://expath.org/ns/http-client";
let $content-url     := 'http://en.wikipedia.org/wiki/Asteroid_impact_avoidance'
let $content-request := 
<http:request href="{$content-url}" method="get" follow-redirect="true"/>
let $response := http:send-request($content-request)[2]
let $content := fn:string-join($response,' ')
return
let $corpus := for $w in tokenize($content, '\W+') return lower-case($w)
let $wordList := distinct-values($corpus)
return
<words> {
         for $w in $wordList
         let $freq := count($corpus[. eq $w])
         order by $freq descending
         return 
         if(string-length($w) gt 3 and $freq gt 3) then
           <word word="{$w}" frequency="{$freq}"/>
         else
           ()
         }</words>

上記の設定は、さまざまなデータ・セットに応じて、除外対象とする単語の文字列の長さや出現回数を調整 (もっと大きい値に設定するなど) しなければなりませんが、リスト 4 に示されているように、この最小限の設定によってノイズの多くは削除され、リストは前よりも関連性の高い単語に絞り込まれています。

リスト 4. 設定修正後の単語の出現頻度のリスト
<words>
<word word="earth" frequency="121"/>
<word word="asteroid" frequency="102"/>
<word word="impact" frequency="58"/>
<word word="near" frequency="56"/>
<word word="with" frequency="55"/>
<word word="that" frequency="53"/>
<word word="space" frequency="49"/>
<word word="nasa" frequency="43"/>
<word word="object" frequency="36"/>
<word word="from" frequency="34"/>
<word word="this" frequency="32"/>
...
</words>

上記の手法には制限があることは確かですが、出だしとしては順調です。この例から、ほんのわずかな XQuery によって、文書のテキスト・コンテンツを特徴付ける基本的なキーワードのセットを取得できることがわかります。

単語の出現頻度に構造を追加する

メタデータに関する決定事項

通常、メタデータを生成するときに最初に決定しなければならないことの 1 つは、メタデータをコンテンツ XML 内に保持するか、それとも別のメタ文書に保存するかどうかです。メタデータを保存する場所を決定した後は、メタデータをコード化するフォーマットも決定する必要があります。メタデータをマークアップするには、さまざまな方法があります。例えば、以下の方法です。

  • DITA (Darwin Information Typing Architecture): 目的に合ったキーワード要素を定義します。
  • マイクロフォーマット:rel-tag タグを使用して、文書内のキーワード要素に直接アノテーションを付けることができます。
  • その他: 例えば RDF (Research Description Framework) や OWL (Web Ontology Language) など、さまざまな semweb マークアップ・フォーマットを使用できます。

独自のマークアップを設計するよりも、既存のマークアップ言語を採用するようにしてください。ただし、簡潔さを維持するとともに、メタデータにできるだけ柔軟性を与えられるフォーマットを選択することが重要です。

テキスト解析を HTML や XML などの半構造化文書に適用する場合、解析で構造が完全に無視されるとしたら、限られた内部情報しか入手することができません。その一方、テキスト解析の重要度を要素の構造と関連させ、要素ごとに解析の重要度を重み付けすることよって、より踏み込んで推論できるとしたらどうでしょうか。

HTML に関して言うと、ネストされた構造内のどこに出現するかによって、単語に点数を付けられるとしたら効果的だと思いませんか? 例えば、以下のような採点基準を考えてみてください。

  • <title> 要素内に出現する単語は、重要性が高い
  • <noscript> 要素または <script> 要素内に出現する単語は、重要性が低い
  • <h1> 要素または <h2> 要素内に出現する単語は、重要性が高い

このような仕組みを実現するには、単語が上記の要素のいずれかに出現するかどうかをチェックするための属性として、各単語に適合度を表す fitness 属性を追加します。リスト 5 に、この属性に関する追加ロジックを記載します。このロジックにおけるチェックによって、重要と思われる要素のいずれかに各単語が含まれるかどうかの判別が行われます。

リスト 5. 単語の出現頻度のリストを生成する XQuery プログラムに適合度を表す fitness を追加する
xquery version "1.0";
import module namespace http = "http://expath.org/ns/http-client";
let $content-url := 'http://en.wikipedia.org/wiki/Asteroid_impact_avoidance'
let $content-request := 
    <http:request href="{$content-url}" 
                     method="get" follow-redirect="true"/>
let $response := http:send-request($content-request)[2]
let $content := fn:string-join($response,' ')

let $corpus := for $w in tokenize($content, '\W+') return lower-case($w)
let $wordList := distinct-values($corpus)
return
<words> {
    for $w in $wordList

let $fitness := if ( $response//*:title[contains(lower-case(.),$w)]) then 
    5 
    else if ($response//*:h1[contains(lower-case(.),$w)]) then
    4
    else if ($response//*:h2[contains(lower-case(.),$w)]) then
    3
    else if ($response//*:h3[contains(lower-case(.),$w)]) then
    2 
    else if ($response//*:noscript[contains(lower-case(.),$w)]) then
    -2
    else if ($response//*:script[contains(lower-case(.),$w)]) then
    -1
    else
    1

    let $freq := count($corpus[. eq $w])
    order by $freq descending
    return 

    if ($freq gt 4 and string-length($w) gt 3) then 
    <word word="{$w}" frequency="{$freq}" fitness="{$fitness}"/> 
    else ()
    }</words>

これで、2 番目のメトリックを使用して、単語の重要性に関する追加情報を収集することができます。

  • <word word="asteroid" frequency="102" fitness="5"/><title> 要素内に出現しました。
  • <word word="deflect" frequency="11" fitness="3"/><h2> 要素内に出現しました。
  • <word word="false" frequency="7" fitness="-1"/> が出現したのは <script> 要素内です。したがって、この単語にはマイナスの適合度を指定します。

この適合度メトリックは極めて単純化されています。重要な単語がどういうわけか <script> セクションに出現する場合もあれば、<title> 要素に含まれる単語が文書の本体にとってはそれほど重要でない場合もあるからです。文書を採点して、より適切なキーワードを生成するには、さらに改善を加えられるはずですが、ここではそれについては触れません。次は、さらに強力なテキスト解析用ツールを統合する方法を説明します。


Web サービスを使用したテキスト解析

自然言語処理 (NLP) を行う商用ツールおよびオープンソースのツールは数多くあります。以下に挙げるのは、なかでもとりわけよく使用されているオープンソースのパッケージの例です。

  • GATE: 自然言語処理およびエンジニアリング用のツールです。
  • Apache Unstructured Information Management Architecture: 元々は IBM によって開発された技術です。
  • RapidMiner: データおよびテキスト・マイニング・ソフトウェアです・
  • Carrot2: テキストおよび検索結果フレームワークです (クラスタリングを使用)。

さらに、テキスト解析に使用できる便利な Web サービスもいくつかあります。この記事の後半で焦点を当てるのは、このような Web サービスを XQuery ファイルの中で使用する方法です。サービスにアクセスするには、EXPath HTTP Client ライブラリーを使用します。

YQL を使用したキーワードの抽出

YQL は SQL に似た言語で、各種の Yahoo! Web サービスのデータに対してクエリーを実行するために使用することができます。Yahoo! の大量のデータとサービスは、一連の Web サービスで公開されています。Yahoo! はこれらのサービスにアクセスするために、さまざまなエンドポイントとメソッドを使用しますが、現在その共通のインターフェースとなっているのが、YQL です。

YQL により、今では同じ 1 つの言語を使用してインターネットのどこにあるデータにでもアクセスできるため、複数の異なる API を呼び出す方法を学ぶ必要はありません。Yahoo! のサービスのなかに、search.termextract という、テキスト・コンテンツの一式から共通の用語を抽出するサービスがあります。このサービスは、以下のようにオンライン YQL コンソールを使ってブラウザーから試してみることができます。

http://developer.yahoo.com/yql/console/
?q=select%20*%20from%20search.termextract%20where%20
context%3D%22Italian%20sculptors%20and%20painters%20of
%20the%20renaissance%20favored%20the%20Virgin%20Mary%20for%20inspiration%22

以下の YQL 文は、search.termextract という名前のテーブルから context 変数に指定されたテキストが含まれる行を選択することを宣言しています。

select * from search.termextract where context=

Test (テスト)」をクリックすると、<query/> 要素内に結果および診断内容が含まれた XML が生成されます (リスト 6 を参照)。

リスト 6. YQL の結果
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
    yahoo:count="5" yahoo:created="2010-12-05T14:36:25Z" yahoo:lang="en-US">
    <diagnostics>
         <publiclyCallable>true</publiclyCallable>
         <user-time>14</user-time>
         <service-time>11</service-time>
         <build-version>9962</build-version>
    </diagnostics> 
    <results>
         <Result xmlns="urn:yahoo:cate">italian sculptors</Result>
         <Result xmlns="urn:yahoo:cate">virgin mary</Result>
         <Result xmlns="urn:yahoo:cate">painters</Result>
         <Result xmlns="urn:yahoo:cate">renaissance</Result>
         <Result xmlns="urn:yahoo:cate">inspiration</Result>
    </results>
</query>

XQuery 内から EXPath HTTP Client ライブラリーを使用するのは簡単なので、今度は独自のコンテンツ分類プロセスの中で、このライブラリーを使って YQL Web サービスにアクセスしてみましょう。リスト 7 に、XQuery 内からこの Web サービスを呼び出す方法を示します。

リスト 7. XQuery から YQL Web サービスにアクセスする
xquery version "1.0";
import module namespace http = "http://expath.org/ns/http-client";
let $content-url     := 'http://en.wikipedia.org/wiki/Asteroid_impact_avoidance'
let $content-request := 
       <http:request href="{$content-url}" 
                        method="get" follow-redirect="true"/>
let $response := http:send-request($content-request)[2]
let $content := fn:string-join(subsequence(($response//*:title,$response//*:p),1,10),' ')

let $query  := fn:concat("select * from search.termextract where context=",$content," ")
let $query  := 
    fn:encode-for-uri(
        fn:concat("select * from search.termextract where context='",$content,"'")
        )
let $yahoo-url     :='http://query.yahooapis.com/v1/public/yql?diagnostics=true&q='
let $term-extraction-url     := fn:concat($yahoo-url,$query) 
let $term-extraction-request := <http:request href="{$term-extraction-url}" method="get"/>
return
http:send-request($term-extraction-request)[2]

上記の XQuery コードは、fn:encode-for-uri() 関数を使用してクエリー・ストリングのエンコードを行います。

YQL による解析では、遥かに質の高い用語リストが生成されます (リスト 8 を参照)。

リスト 8. YQL による用語の抽出結果
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="20"
yahoo:created="2010-12-05T20:14:37Z" yahoo:lang="en-US">
<diagnostics>
       <publiclyCallable>true</publiclyCallable>
       <url execution-time="433"
       >http://search.yahooapis.com/ContentAnalysisService/V1/termExtraction
       </url>
       <javascript execution-time="436" instructions-used="0"
              table-name="search.termextract"/>
       <user-time>437</user-time>
       <service-time>433</service-time>
       <build-version>9962</build-version>
</diagnostics>
<results>
       <Result xmlns="urn:yahoo:cate">tertiary extinction event</Result>
       <Result xmlns="urn:yahoo:cate">shoemaker levy 9</Result>
       <Result xmlns="urn:yahoo:cate">spaceguard survey</Result>
       <Result xmlns="urn:yahoo:cate">near earth objects</Result>
       <Result xmlns="urn:yahoo:cate">period comet</Result>
       <Result xmlns="urn:yahoo:cate">nasa report</Result>
       <Result xmlns="urn:yahoo:cate">extinction level event</Result>
       <Result xmlns="urn:yahoo:cate">deep impact probe</Result>
       <Result xmlns="urn:yahoo:cate">inner solar system</Result>
       <Result xmlns="urn:yahoo:cate">mitigation strategies</Result>
       <Result xmlns="urn:yahoo:cate">65 million years</Result>
       <Result xmlns="urn:yahoo:cate">material composition</Result>
       <Result xmlns="urn:yahoo:cate">impact winter</Result>
       <Result xmlns="urn:yahoo:cate">chicxulub crater</Result>
       <Result xmlns="urn:yahoo:cate">impact speed</Result>
       <Result xmlns="urn:yahoo:cate">catastrophic impact</Result>
       <Result xmlns="urn:yahoo:cate">catastrophic damage</Result>
       <Result xmlns="urn:yahoo:cate">planetary defense</Result>
       <Result xmlns="urn:yahoo:cate">impact events</Result>
       <Result xmlns="urn:yahoo:cate">astronomical events</Result>
</results>
</query>

YQL にも制限があります。例えば、YQL に渡すコンテンツがリクエストに設けられた制限を超えていないことを確認しなければなりません。また、YQL へのリクエストは HTTP GET リクエストとして送信されるため、適切にエンコードされている必要があります。


AlchemyAPI によるテキスト解析

AlchemyAPI は、興味深いコンテンツ解析ツールを提供している会社です (「参考文献」を参照)。この会社のツールはいずれも Web サービスとして利用することができます。この記事では、AlchemyAPI の用語抽出サービスと名前付きエンティティー抽出サービスのそれぞれを使用してテキスト解析を行います。

AlchemyAPI を使用したキーワード抽出

AlchemyAPI では、一般公開されたあらゆる Web ページからトピック・キーワードを抽出するための Web サービスを提供しています。単純明快な HTTP GET リクエストを使用して、AlchemyAPI Web サービスにアクセスして特定の URL を取得するように命令し、トピック・キーワードを抽出することができます。おまけに、AlchemyAPI の URL 処理を呼び出すと、自動的に必要な Web ページを取得し、そのページを正規化して余分なものを取り除き (広告やナビゲーション・リンクの他、重要ではないコンテンツを除去)、トピック・キーワードを抽出してくれます。リスト 9 に、このサービスの使用方法を示します。

リスト 9. AlchemyAPI のトピック抽出 Web サービスにアクセスするための URL
http://access.alchemyapi.com/calls/url/URLGetRankedKeywords?
apikey=PLACE_YOUR_APIKEY_HERE&
    url=http://en.wikipedia.org/wiki/Asteroid_impact_avoidance

AlchemyAPI には以下の 2 つの URL パラメーターが必要です。

  • 解析対象とする URL
  • API キー。AlchemyAPI の Web サービスを呼び出すには、例外なくこのキーが必要となります。

AlchemyAPI の API キーは、AlchemyAPI サイトの登録フォームから登録することで入手することができます。

AlchemyAPI が自動的に URL を取得してくれることから、XQuery から Web サービスを呼び出す方法は、前に取り上げた YQL を呼び出す例よりも多少単純です。リスト 10 に、そのためのコードを記載します。

リスト 10. AlchemyAPI を使用してキーワードを生成する XQuery
xquery version "1.0";
import module namespace http = "http://expath.org/ns/http-client";
let $url    := 'http://en.wikipedia.org/wiki/Asteroid_impact_avoidance'
let $apikey := 'PLACE_YOUR_APIKEY_HERE'
let $alchemey_uri := 'http://access.alchemyapi.com/calls/url/URLGetRankedKeywords?'
let $href    := fn:concat($alchemey_uri,'&apikey=',$apikey,'&url=',$url)
let $content-request := <http:request href="{$href}" method="get" follow-redirect="true"/>
return
http:send-request($content-request)[2]

リスト 11 の結果には、このテスト Web ページのキーワードが含まれています。

リスト 11. トピック抽出 Web サービスによる結果
<results>
     <status>OK</status>
     <usage>By accessing AlchemyAPI or using information 
     generated by AlchemyAPI, you are agreeing to be bound by 
     the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html</usage>
     <url>http://en.wikipedia.org/wiki/Asteroid_impact_avoidance</url>
     <language>english</language>
     <keywords>
          <keyword>
               <text>asteroid</text>
               <relevance>0.983321</relevance>
          </keyword>
          <keyword>
               <text>NASA</text>
               <relevance>0.376168</relevance>
          </keyword>
          <keyword>
               <text>comet</text>
               <relevance>0.370371</relevance>
          </keyword>
          <keyword>
               <text>near-earth object</text>
               <relevance>0.363529</relevance>
          </keyword>
          <keyword>
               <text>survey program</text>
               <relevance>0.3417</relevance>
          </keyword>
     .... more keywords ....
     </keywords>
</results>

このように、キーワードには関連性に関するスコアも一緒に示されるため (遥かに意味のある結果です)、AlchemyAPI Web サービスによる出力は、品質という点で YQL による出力よりも優れています。

AlchemyAPI を使用したエンティティー抽出

さらに高度な解析を行うには、コンテンツ内の人、企業、組織、都市、地理に関する特徴やその他の型付きエンティティーを識別できる AlchemyAPI の名前付きエンティティー抽出 Web サービスを使用することができます。このサービスでは強力な NLP が行われ、エンティティーがその意味と一緒に抽出されます。

トピック・キーワード Web サービスの場合と同じく、このサービスを使用する上で必要なことは、API キーと解析対象のコンテンツが含まれる URL を指定することだけです (リスト 12 を参照)。

リスト 12. AlchemyAPI の名前付きエンティティー抽出 Web サービスにアクセスするための URL
http://access.alchemyapi.com/calls/url/URLGetRankedNamedEntities?
    apikey=PLACE_YOUR_APIKEY_HERE&
    url=http://en.wikipedia.org/wiki/Asteroid_impact_avoidance

XQuery からこの Web サービスを呼び出す方法に関しては、前のリスト 10 の例とまったく同じです (リスト 13 を参照)。

リスト 13. AlchemyAPI を使用してエンティティーを生成する XQuery
xquery version "1.0";
import module namespace http = "http://expath.org/ns/http-client";
let $url    := 'http://en.wikipedia.org/wiki/Asteroid_impact_avoidance'
let $apikey := 'PLACE_YOUR_APIKEY_HERE'
let $alchemey_uri := 'http://access.alchemyapi.com/calls/url/URLGetRankedNamedEntities?'
let $href    := fn:concat($alchemey_uri,'&apikey=',$apikey,'&url=',$url)
let $content-request := <http:request href="{$href}" method="get" follow-redirect="true"/>
return
http:send-request($content-request)[2]

テキスト解析の結果はかなり長く、また説得力のあるものとなります (リスト 14 を参照)。

リスト 14. 名前付きエンティティー抽出 Web サービスによる結果
<results>
    <status>OK</status>
    <usage>By accessing AlchemyAPI or using information generated by AlchemyAPI, 
    you are agreeing to be bound by the AlchemyAPI Terms of 
    Use: http://www.alchemyapi.com/company/terms.html</usage>
    <url>http://en.wikipedia.org/wiki/Asteroid_impact_avoidance</url>
    <language>english</language>
    <entities>
         <entity>
              <type>GeographicFeature</type>
              <relevance>0.667231</relevance>
              <count>44</count>
              <text>Earth</text>
         </entity>
         <entity>
              <type>Organization</type>
              <relevance>0.472053</relevance>
              <count>25</count>
              <text>NASA</text>
              <disambiguated>
                   <name>NASA</name>
                   <subType>Company</subType>
                   <subType>GovernmentAgency</subType>
                   <subType>AirportOperator</subType>
                   <subType>AwardPresentingOrganization</subType>
                   <subType>SoftwareDeveloper</subType>
                   <subType>SpaceAgency</subType>
                   <subType>SpacecraftManufacturer</subType>
                   <geo>38.88305555555556 -77.01638888888888</geo>
                   <website>http://www.nasa.gov/home/index.html</website>
                   <dbpedia>http://dbpedia.org/resource/NASA</dbpedia>
                   <umbel>http://umbel.org/umbel/ne/wikipedia/NASA</umbel>
                   <yago>http://mpii.de/yago/resource/NASA</yago>
              </disambiguated>
         </entity>

         .... entities ....
    </entities>
</results>

このように、AlchemyAPI の名前付きエンティティー抽出 Web サービスは、あらゆる類の内容を識別します。例えば、このサービスでは以下のことを認識します。

  • Earth は地理的特徴であること。
  • NASA は組織であり、複数の関連リンクがあること。
  • United States は国であること。
  • George E. Brown 代表は人であり、政治家と見なされること。

こうした点から、テキスト・マイニングはコンテンツから収集可能な内容に関して万能のように思えますが、関連性のスコアに注意するに越したことはありません。100 パーセント正確なシステムというものはありません。また、特定のコンテンツが他のコンテンツよりもテキスト解析に上手く対応するという場合もあります。


まとめ

この記事では、皆さんが文書の分類に取り掛かる際の手法をいくつか紹介しました。記事の前半で焦点を当てたのは、単語の出現頻度を判断し、それを基に独自の XQuery テキスト・マイニング手法を構築する方法についてです。次に、Yahoo! および AlchemyAPI がテキスト解析用に提供している強力な外部 Web サービスを統合する方法を説明しました。

Web サービスが行うテキスト解析は、確かに品質の点で勝っていますが、XQuery を使用して単語の出現頻度を明らかにする初歩的な方法の例で示したように、XQuery だけを使ってデータから有用な推論を引き出すことは可能です。

この記事で紹介した手法には、いずれも何らかの制限があります。例えば、解析した文書は 1 つだけでした。一連の関連文書でテキスト解析を行えば、さらに大きなコーパスからの相互参照が可能になり、文書間に存在するより深い関係を収集できることから、結果的なカテゴリー分類はより品質の高いものになります。この記事で、コンテンツのカテゴリー分類を自動化する上で XQuery がいかに強力な言語であるかを明らかにできたことを願います。皆さんも独自に XQuery をテキスト解析に適用してみてください。皆さんからのフィードバックを期待しています。


ダウンロード

内容ファイル名サイズ
Sample scripts for this articlecontent_catigorisation_src.zip20KB

参考文献

学ぶために

製品や技術を入手するために

  • EXPath HTTP Client モジュール: モジュールの実装ならびに、この関数一式を使用して HTTP および HTTPS リクエストを送信し、レスポンスを処理する例を調べてください。
  • Zorba XQuery Processor オンライン・デモ: サンドボックスにアクセスして、オンラインで Zorba での XQuery を試してみてください。
  • AlchemyAPI: コンテンツ解析ツールとメタデータ・アノテーション・ツールからなるこのスイートについての詳細を学び、ダウンロードしてください。
  • IBM 製品の評価版: DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を体験するには、評価版をダウンロードするか、IBM SOA Sandbox のオンライン試用版を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML, Web development
ArticleID=647229
ArticleTitle=XQuery を使ってコンテンツを分類する
publish-date=03222011