Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

スマート・マッチング : ディクショナリの作成

スマート・マッチングとは、iKnow インデックス作成プロセスの結果を、ディクショナリ、分類法、またはオントロジといった形で所有している外部の知識と組み合わせることです。こうしたインデックス作成結果により、どの単語をまとめて概念や関係を形成するかが特定されるため、一致の品質を判断することが可能になり、iKnow マッチングが “スマート“ になります。例えば、iKnow は、ディクショナリ用語である "flu" に一致する語が、実際にインデックス付きテキスト・ソースで "flu" という概念を示しているのか、それとも "bird flu" という概念を示しているのかを識別できます。後者は部分一致と呼ばれますが、この場合の一致は、インデックス付けされたテキスト・ソースのエンティティにディクショナリ用語が正確に対応する完全一致の場合とは異なる扱いが必要なこと (または異なる扱いが可能なこと) は明らかです。

スマート・マッチングを実行するには、ディクショナリを作成または取得する必要があります。ディクショナリを作成する場合は、マッチングに使用したい項目や用語を入力する必要があります。ディクショナリを生成したら、そのコンテンツを使用してマッチング処理を実行できます。

Note:

現時点では、ディクショナリの定義は日本語をサポートしていません。

この章では、以下について説明します。

ディクショナリ構造とマッチングの概要

iKnow ディクショナリを生成するには、まず項目を作成し、次に 1 つ以上の用語をその項目に関連付けます。ディクショナリは通常、複数項目から構成され、それぞれの項目は複数の用語に関連付けられています。項目は、ソース・テキストの多数のエンティティの関連タグとなる単語または語句です。ソース・テキストのエンティティが一致すると判別されると、その項目でタグ付けされます。例えば、項目 “ship“ は、“ship“、“boat“、“sail“、“oars“ などの関連タグです。

このマッチングを実行するには、ディクショナリの各項目にマッチングさせる用語を入力します。用語は、1 つのエンティティ (例 : “motor boat“) または語句や文 (例 : “boats are rowed with oars or paddles“) です。iKnow は、ソース・テキストに使用されているのと同じ言語モデルを使用して、ディクショナリ内の各用語のインデックスを作成します。次に iKnow は、各用語をソース・テキストの同じコンテンツ・ユニットとマッチングさせます (コンセプト用語はソース・テキストのコンセプトに対して、CRC 用語はソース・テキストの CRC に対してマッチングさせます)。iKnow は、用語とソース・テキスト・ユニットが一致することを識別すると、関連付けられたディクショナリ項目でそのソース・テキストにタグ付けします。このマッチングは同一でないことがよくありますが、用語とソース・テキストが一致すると見なしてタグ付けしていいかどうかを判断するために、iKnow はスコアリング・アルゴリズムを使用することが必要とされます。

iKnow ディクショナリ機能は、現在のドメインに対して語幹解析が有効になっている場合、語幹解析をサポートします。つまり、単一のディクショナリ用語をソース・テキスト内の同一単語の別の形式と照合できます。

用語

ディクショナリは、互いに論理的関連性のある異なる用語をグループ化するための方法です。ディクショナリは、例えば、都市、ICD10 コード、またはフランス産ワインとすることができます。ディクショナリは、マッチング API 内で使用される集約のレベルで、現実のどのレベルのグループ化をディクショナリに対応させるかは、それぞれの使用事例によって異なります。上位のレベル (例 : "すべての ICD10 コード") を使用すると、パフォーマンスが高まって使用するディスク容量が減りますが、低位のレベル (例 : "全 ICD10 カテゴリの個々のカテゴリ") を使用すると、より詳細にグループ化された結果になる場合があります。各ディクショナリには名前と説明があります。

ディクショナリ項目は、ディクショナリ内で一意に識別することが可能な項目です。ディクショナリ項目の例としては、都市、ICD10 の個々のコード、または個々のシャトーが挙げられます。各ディクショナリには、通常、多数のディクショナリ項目が含まれます (少数の項目を持つ小さなディクショナリを多数作成すると、パフォーマンスが低下します)。ディクショナリ項目は URI を持ちます。これはドメイン内で一意であることが必要で、外部識別子およびオプションの説明として使用できます。この URI は、後でマッチング結果を解釈するためのルールを作成するときに使用できます。

ディクショナリ用語とは、テキストのどこかに出現する可能性のある文字列で、それが属するディクショナリ項目を表します。例えば、"Antwerp"、"Anvers"、"Antwerpen" は、Antwerp という都市を表す同じディクショナリ項目に関連付けられた異なる用語の可能性があります。ディクショナリ用語はフリー・テキスト文字列で、文字列ベースのマッチングを行う際の実際のマッチングはこれに基づいて行われます。ディクショナリ項目が表すものの異なる綴り、翻訳、または同義語である可能性があります。これらの文字列はエンジンを通して渡されて、単なる 1 つのエンティティを超えるものを含む場合は、単独の概念の境界を越えてマッチングできるように、より複雑な構造に自動的に変換されます (CRC またはパス)。ディクショナリ用語をエンジンで処理することが必要な場合は、言語も関連付けられているはずです。

iKnow エンジンを通して新しいディクショナリ用語を渡すことでこれを処理すると、用語内で識別された異なるエンティティを表すために 1 つ以上の ディクショナリ要素が生成されます。例えば、ディクショナリ用語の "failure of the liver" は、"failure"、"of"、および "liver" の 3 つの要素に変換され、"the" は無関係として破棄されます。これらの要素は自動的に生成、管理され、ある種の出力のみに関係するため、あまり気にする必要はありません。

日付、数字、または他のフォーマットされた文字列を識別したい場合は、ディクショナリ形式を使用してこれらを指定することで、完全な用語を表すものとして、または複雑な用語の 1 つの要素として、これらをディクショナリ用語に含めることが可能になります。形式とは、日付形式といった意味のある文字パターンです。例えば、“nn/nn/nnnn” および “nnnn-nn-nn” という形式を Date という項目と関連付けることができます。iKnow は、ソース・テキストにこれらの形式が出現すると、Date 項目でタグ付けします。

ディクショナリの作成

ディクショナリを定義するには、このセクションで説明されているディクショナリの定義および生成用の %iKnow.Matching.DictionaryAPIOpens in a new tab クラス・メソッドを使用します。ドメイン専用のディクショナリを定義したり、ドメイン非依存で現在のネームスペースの任意のドメインで使用できるディクショナリを定義したりできます。

%iKnow.Matching.DictionaryAPIOpens in a new tab には、新しいディクショナリを作成し、それに項目、用語、および形式を割り当てるための多数のメソッドが用意されています。

  • CreateDictionary()Opens in a new tab は、iKnow ディクショナリを作成するために使用します。

    1 番目の引数は、ドメイン ID を整数に指定します。ドメインにディクショナリを割り当てるには、そのドメイン ID を正の整数として指定します。ディクショナリをドメイン非依存として定義するには、そのドメイン ID として 0 を指定します。2 番目の引数には、意味のあるディクショナリ名を指定できます。残りの引数は省略可能です。3 番目の引数にはディクショナリの説明を入力し、4 番目には言語を指定 (既定は英語)、そして 5 番目にはカスタム・マッチング・プロファイルを入力します。CreateDictionary() は、一意の整数である dictId を返します。このディクショナリ ID は、以降のスマート・マッチング・メソッドで使用されます。指定された名前のディクショナリが既に存在している場合、CreateDictionary() は -1 を返します。

  • CreateDictionaryItem()Opens in a new tab は、ディクショナリ内で項目を作成するために使用します。dictId を指定すると、CreateDictionaryItem() によって一意の整数である dictItemId が返されます。

  • CreateDictionaryTerm()Opens in a new tab は、用語を既存の項目と関連付けるために使用します。dictItemId を指定すると、CreateDictionaryTerm() によって一意の整数である dictTermId が返されます。

  • CreateDictionaryItemAndTerm()Opens in a new tab は、特定の場合に使用できるショートカットです。これを使用して項目を作成し、用語と項目の値が同じ場合は、その項目に関連付けられる用語を作成できます。例えば、“flu“ という項目には、いくつかの用語 (“influenza“、“le grippe“、“bird flu“、“H1N1“ など) を関連付けられますが、CreateDictionaryItemAndTerm() を使用すると、項目 “flu“ を作成し、関連付けられる用語の “flu“ をそれに割り当てることができます。もちろん、2 つのメソッド呼び出し (CreateDictionaryItem() および CreateDictionaryTerm()) を使用して、同じ処理を実行することも可能です。

  • CreateDictionaryTermFormat()Opens in a new tab は、形式から構成される用語を既存の項目と関連付けるために使用します。dictItemId を指定すると、CreateDictionaryTermFormat() によって一意の整数である dictTermId が返されます。

ディクショナリおよびドメイン

作成する各ディクショナリは、ドメイン固有にするか、ドメイン非依存にして現在のネームスペースの任意のドメインで使用できるようにすることができます。

  • ドメイン固有のディクショナリは、CreateDictionary() メソッドで domainId を指定することでドメインに割り当てられます。ディクショナリの項目、用語、および形式に対して同じ domainId を指定します。このメソッドは、連続する正の整数として dictId を返します。このディクショナリを使用するマッチング・メソッドは、この dictId によってこれを参照します。

  • ドメイン非依存のディクショナリはドメインに割り当てられません。代わりに CreateDictionary() メソッドで 0 の domainId を指定します。ディクショナリの項目、用語、および形式に対しても domainId を 0 に指定します。このメソッドは、連続する正の整数として dictId を返します。このディクショナリを使用するマッチング・メソッドは、負の dictId によってこれを参照します。例えば、dictId 8 で識別されるディクショナリは dictId 値 -8 で参照されます。

    Note:

    ドメイン非依存のディクショナリは、バージョン 4 (以降) のドメインでのみ使用可能です。ドメイン非依存のディクショナリを使用するには、Caché 2014.1 以前に作成されたドメインをバージョン 4 にアップグレードする必要があります。

    ドメイン非依存のディクショナリの使用は、語幹解析の結果に重要な役割を果たします。ドメインが語幹抽出済みで構成されているためにディクショナリの用語とソース・テキストが一致する場合、ドメイン固有の通常用語のディクショナリを作成すると、iKnow は自動的にディクショナリの用語の語幹解析を実行します。ドメイン非依存のディクショナリを作成すると、ディクショナリの用語の語幹変換は実行されません。ユーザは通常の (語幹抽出されていない) 用語のディクショナリまたは語幹抽出済み用語のディクショナリのいずれかを作成できます。ドメイン非依存の通常用語のディクショナリでは、語幹抽出済みドメインに対する照合はできません。ドメイン非依存の語幹抽出済み用語のディクショナリでは、語幹抽出されていないドメインに対する照合はできません。

いくつかのドメインすべてが同じ dictId 値のドメイン固有のディクショナリを持つことができることとちょうど同じように、ドメイン固有のディクショナリとドメイン非依存のディクショナリの両方が同じ整数の dictId 値を持つことができます。ディクショナリ・マッチング処理は、ドメイン固有のディクショナリ (正の整数 ID で指定) とドメイン非依存のディクショナリ (負の整数 ID で指定) の任意の組み合わせを使用できます。

マッチング結果を返すマッチング API のクエリは、マッチングがドメイン非依存ディクショナリのエントリに対応する場合、(dictId、itemId、および termId に) 負の識別子を返します。すべてのクエリは、ドメイン固有のディクショナリのマッチングおよびドメイン非依存のディクショナリのマッチングの結果の組み合わせを返します。ただし、dictId パラメータで指定された値に応じて、ドメイン固有のディクショナリまたはドメイン非依存のディクショナリのいずれかの結果のみを返す、GetDictionaryMatches()GetDictionaryMatchesById() は例外です。既定は、ドメイン固有のディクショナリのマッチングです。

ディクショナリ作成例

以下の例では、"AviationTerms" という名前のディクショナリを作成し、2 つの項目とそれらに関連付けられる用語を入力します。このディクショナリは特定のドメインに割り当てられます。

  SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain")
  /* ... */
CreateDictionary
  SET dictname="AviationTerms"
  SET dictdesc="A dictionary of aviation terms"
  SET dictId=##class(%iKnow.Matching.DictionaryAPI).CreateDictionary(domId,dictname,dictdesc)
  IF dictId=-1 {WRITE "Dictionary ",dictname," already exists",!
                GOTO ResetForNextTime }
  ELSE {WRITE "created a dictionary ",dictId,!}
PopulateDictionaryItem1
  SET itemId=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryItem(domId,dictId,
       "aircraft",domId_dictId_"aircraft")
    SET term1Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(domId,itemId,
       "airplane")
    SET term2Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(domId,itemId,
       "helicopter")
PopulateDictionaryItem2
 SET itemId2=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryItemAndTerm(domId,dictId,
        "weather",domId_dictId_"weather")
    SET i2term1Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(domId,itemId2,
        "meteorological information")
    SET i2term2Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(domId,itemId2,
        "visibility")
    SET i2term3Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(domId,itemId2,
        "winds")
DisplayDictionary
  SET stat=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryItemsAndTerms(.result,domId,dictId)
  SET i=1
  WHILE $DATA(result(i)) {
      WRITE $LISTTOSTRING(result(i),",",1),!
      SET i=i+1 }
  WRITE "End of items in dictionary ",dictId,!!
   /* ... */
ResetForNextTime
  IF dictId = -1 {
     SET dictId=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryId(domId,dictname)}
  SET stat=##class(%iKnow.Matching.DictionaryAPI).DropDictionary(domId,dictId)
  IF stat {WRITE "deleted dictionary ",dictId,! }
  ELSE    { WRITE "DropDictionary error ",$System.Status.DisplayError(stat) } 

以下の例では、前の例と同じディクショナリが作成されますが、このディクショナリは現在のネームスペース内の任意のドメインで使用できます。

CreateDictionary
  SET dictname="AviationTerms"
  SET dictdesc="A dictionary of aviation terms"
  SET dictId=##class(%iKnow.Matching.DictionaryAPI).CreateDictionary(0,dictname,dictdesc)
  IF dictId=-1 {WRITE "Dictionary ",dictname," already exists",!
                GOTO ResetForNextTime }
  ELSE {WRITE "created a dictionary ",dictId,!}
PopulateDictionaryItem1
  SET itemId=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryItem(0,dictId,
       "aircraft",0_dictId_"aircraft")
    SET term1Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(0,itemId,
       "airplane")
    SET term2Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(0,itemId,
       "helicopter")
PopulateDictionaryItem2
 SET itemId2=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryItemAndTerm(0,dictId,
        "weather",0_dictId_"weather")
    SET i2term1Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(0,itemId2,
        "meteorological information")
    SET i2term2Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(0,itemId2,
        "visibility")
    SET i2term3Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(0,itemId2,
        "winds")
DisplayDictionary
  SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain")
  SET stat=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryItemsAndTerms(.result,0,dictId)
  SET i=1
  WHILE $DATA(result(i)) {
      WRITE $LISTTOSTRING(result(i),",",1),!
      SET i=i+1 }
  WRITE "End of items in dictionary ",dictId,!!
   /* ... */
ResetForNextTime
  IF dictId = -1 {
     SET dictId=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryId(0,dictname)}
  SET stat=##class(%iKnow.Matching.DictionaryAPI).DropDictionary(0,dictId)
  IF stat {WRITE "deleted dictionary ",dictId,! }
  ELSE    { WRITE "DropDictionary error ",$System.Status.DisplayError(stat) } 

形式用語の定義

%iKnow.Matching.Formats パッケージは、以下の 3 つのシンプルな形式クラスを提供します。

必要に応じて、追加の形式クラスを作成できます。

以下の例では %iKnow.Matching.Formats.SimpleSuffixFormatOpens in a new tab を使用しています。ここでは最初に、speed という 1 つの項目を含むディクショナリを定義します。“speed“ 項目には、“excessive speed“ および接尾語形式用語 “mph“ (マイル / 時) の 2 つの用語が含まれます。この接尾語形式は、接尾語 “mph“ で終わるあらゆるエンティティ (例 : “65mph“) と一致します。

  SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain")
  /* ... */
CreateDictionary
  SET dictname="Traffic"
  SET dictdesc="A dictionary of traffic enforcement terms"
  SET dictId=##class(%iKnow.Matching.DictionaryAPI).CreateDictionary(domId,dictname,dictdesc)
  IF dictId=-1 {WRITE "Dictionary ",dictname," already exists",!
                GOTO ResetForNextTime }
  ELSE {WRITE "created a dictionary ",dictId,!}
CreateDictionaryItemAndTerms
  SET item1Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryItem(domId,dictId,"speed",domId_dictId_"speed")
  SET term1Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTerm(domId,item1Id,
            "excessive speed")
  SET term2Id=##class(%iKnow.Matching.DictionaryAPI).CreateDictionaryTermFormat(domId,
            item1Id,"%iKnow.Matching.Formats.SimpleSuffixFormat",$LB("mph",0,3))
  WRITE "dictionary=",dictId,!,"item=",item1Id,!,"terms=",term1Id," ",term2Id,!!
   /* ... */
ResetForNextTime
  IF dictId = -1 {
     SET dictId=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryId(domId,dictname)}
  SET stat=##class(%iKnow.Matching.DictionaryAPI).DropDictionary(domId,dictId)
  IF stat {WRITE "deleted dictionary ",dictId,! }
  ELSE { WRITE "DropDictionary error ",$System.Status.DisplayError(stat) }

ディクショナリ用語における複数の形式

ディクショナリ用語の一部としてディクショナリ形式を直接入力できます。これにより、1 つ以上の形式要素と文字列要素を含む複数の要素で構成されるディクショナリ用語を作成できます。

この機能を使用するには、CreateDictionaryTerm()Opens in a new tab メソッドに送信される文字列の一部としてコード化された説明を指定します。このコード化された説明は以下の形式になります。

@@@User.MyFormatClass@@@param1@@@param2@@@

この説明は、形式クラスの完全なクラス名 (%iKnow.Matching.Formats.Format の実装)、@@@ 区切り文字、および形式クラスに渡される形式パラメータの @@@ 区切りリストで構成されています。この説明全体の始めと終わりが @@@ マーカで区切られています。

形式クラスがパラメータを取得していない場合、または既定が使用されている場合は、@@@ マーカによって区切られた形式クラス名を指定します。

ディクショナリ用語の文字列にこの形式を追加する場合は、1 つのエンティティとして iKnow に確実に認識させる必要があります。例えば、”was born in @@@User.MyYearFormat@@@” という用語は 1 つのエンティティとして解釈されますが、”was born in the year @@@User.MyYearFormat@@@” という用語はそのように解釈されません。

指定された形式クラスが iKnow で見つけられない場合は、@@@ の使用が内部であると見なされ、エンティティ全体が単純な文字列要素として処理されます。

この構文を使用することで、形式に対する別の手順またはアクションが必要なくなり、ファイルまたはテーブルからのディクショナリのロードが容易になります。

ディクショナリのリストおよびコピー

%iKnow.Matching.DictionaryAPIOpens in a new tab クラスには、既存ディクショナリおよびその項目や用語をカウントまたはリストするためのメソッドが多数用意されています。

%iKnow.Utils.CopyUtilsOpens in a new tab クラスには、単一もしくはすべてのディクショナリをドメイン間でコピーするためのメソッドが多数用意されています。

既存のディクショナリのリスト

以下の例は、ドメイン内のすべてのディクショナリをリストします。デモンストレーションのために、この例では、最初に 2 つの空のディクショナリ (1 つは既定の言語である英語、もう 1 つはフランス語) を作成します。

  SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain")
  SET dictname1="Diseases",dictname2="Maladies"
  SET dictdesc1="English disease terms",dictdesc2="French disease terms"
CreateFirstDictionary
  SET dictId1=##class(%iKnow.Matching.DictionaryAPI).CreateDictionary(domId,dictname1,dictdesc1)
  IF dictId1 = -1 {
     SET dictId=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryId(domId,dictname1)
     SET stat=##class(%iKnow.Matching.DictionaryAPI).DropDictionary(domId,dictId)
     IF stat '= 1 { WRITE "DropDictionary error ",$System.Status.DisplayError(stat)
                    QUIT }
     GOTO CreateFirstDictionary }
    ELSE {WRITE "created a dictionary ",dictId1,!}
CreateSecondDictionary
  SET dictId2=##class(%iKnow.Matching.DictionaryAPI).CreateDictionary(domId,dictname2,dictdesc2,"fr")
  IF dictId2 = -1 {
     SET dictId=##class(%iKnow.Matching.DictionaryAPI).GetDictionaryId(domId,dictname2)
     SET stat=##class(%iKnow.Matching.DictionaryAPI).DropDictionary(domId,dictId)
     IF stat '= 1 { WRITE "DropDictionary error ",$System.Status.DisplayError(stat)
                    QUIT }
     GOTO CreateSecondDictionary }
  ELSE {WRITE "created a dictionary ",dictId2,!}

GetDictionaries
  SET stat=##class(%iKnow.Matching.DictionaryAPI).GetDictionaries(.dicts,domId)
  WRITE "get dictionaries status is:",$System.Status.DisplayError(stat),!!
  SET k=1
  WHILE $DATA(dicts(k)) {
      WRITE $LISTTOSTRING(dicts(k)),!
      SET k=k+1 }
  WRITE "End of list of dictionaries"

GetDictionaries()Opens in a new tab は、各ディクショナリの ID、名前、説明、および言語をリストします。

ディクショナリのコピー

現在のネームスペース内で、1 つのドメインから別のドメインにディクショナリをコピーできます。

ディクショナリ構造の拡張

iKnow ではマッチング API にある単純なディクショナリのみが記述されてますが、このことによって、オントロジ、分類法、またはその他より階層型の構造など、より高度なツールの使用が制限されません。マッチング API の目的は、シンプルなマッチングの仕組みを提供することで、あらゆる構造をカバーする一般的な構造をまた 1 つ追加することではありません。つまり、手持ちのオントロジや分類法の構造を単に平坦化すればいいのです。ディクショナリ項目の URI を適切に選択することにより、オントロジや分類法のコンテキスト内でマッチング結果を再構築または解釈することが可能になります。

例えば、%iKnow.Matching.Formats.FormatOpens in a new tab インタフェースの実装による正規表現マッチングを行うクラスの実装など、マッチング API では独自のクラス実装を提供できるという点で、フォーマット・ビットは着脱可能です。

FeedbackOpens in a new tab