iKnow クエリ
iKnow 意味分析エンジンは多数のクエリ API を提供し、これらはテキスト・エンティティおよびこうしたテキスト・エンティティに関する統計を返すために使用されます。例えば、%iKnow.Queries.CrcAPI.GetTop()Opens in a new tab メソッドは、指定されたドメインで最も頻繁に出現している CRC を返します。また、%iKnow.Queries.CrcAPI.GetCountBySource()Opens in a new tab は、指定されたソースに出現する一意の CRC の合計数を返します。
クエリのタイプ
提供されるクエリには、以下の 3 つのタイプがあります。これらは、名前の接頭語によって区別されます。
-
API : ObjectScript クエリ
-
QAPI : Caché SQL クエリ
-
WSAPI : SOAP でアクセス可能な Web サービス・クエリ
それぞれのタイプに対して、iKnow は以下のクエリを提供します。
この章で説明するクエリ
この章では、以下のようなよく使用される多数の iKnow クエリについて説明し、その例を示します。
この章のクエリの例では、既定の構成を使用しています。ユーザが記述するクエリには、言語環境を確立するために所定の構成が必要になる場合があります。
クエリ・メソッド・パラメータ
以下のパラメータは、多数のクエリ・メソッドに共通です。
-
domainid : ドメイン ID はドメインを特定する整数です。
-
result : クエリが 1 つの結果値ではなく値の配列を返す場合は、結果のセットは参照渡しされます (.result のようにドット接頭語演算子を使用します)。その後で、ZWRITE を使用して、未加工の Caché リスト形式で全結果セットを表示できます。または、ループ構造とリストから文字列への変換を使用して一度に 1 行ずつ返すこともできます (この章の例を参照)。
-
page と pagesize (オプション) : メソッドが何千ものレコードを取得して返すのを防ぐために、クエリ API はページング・メカニズムを使用して、返される結果の数をユーザが制限できるようにしています。このメカニズムは、同じ長さのページに結果を分割します。各ページは、pagesize で指定した長さになります。例えば、最初の 10 個の結果が必要な場合は、page に 1、pagesize に 10 と指定します。次のページの結果が必要な場合は、page に 2、pagesize に 10 と指定します。既定値は page=1、pagesize=10 です。
-
setop (オプション) : 複数の選択条件にクエリを適用する場合は、Setop 論理演算子によって、クエリで結果セットの UNION (和集合) と INTERSECT (共通集合) のどちらを返すかを指定します。1 ($$$UNION) は、指定された選択条件のいずれかに一致する結果を返します。2 ($$$INTERSECT) は、指定された選択条件のすべてに一致する結果を返します。既定値は $$$UNION です。
-
entitylist : エンティティに一致するものを返すクエリ (例 : GetByEntities()、GetRelated()、GetSimilar()) における、Caché によるエンティティのリスト。entitylist のエンティティは、大文字と小文字を混ぜて指定できます。これらは iKnow により、小文字に正規化されてインデックスが作成されたエンティティに対してマッチングされます。
-
vSrcId : 仮想ソースのソース ID。負の整数で指定します。指定すると、その仮想ソースのエンティティのみがクエリで処理されます。省略した場合または 0 を指定した場合は、通常のソースのみがクエリの対象となり、仮想ソースは無視されます。既定値は 0 です。
ソースと文のカウント
ロードされたソースの数をカウントするには、%iKnow.Queries.SourceAPIOpens in a new tab クラスの GetCountByDomain()Opens in a new tab メソッドを使用できます。
ロードされた全ソース内の文をカウントするには、%iKnow.Queries.SentenceAPIOpens in a new tab クラスの GetCountByDomain()Opens in a new tab メソッドを使用できます。1 つのソース内の文をカウントするには、GetCountBySource()Opens in a new tab メソッドを使用できます。
以下の例では、.txt ファイルからロードしたデータを使用して、これらの文カウント・メソッドを示しています。既定の構成の使用となります。
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET mylister=##class(%iKnow.Source.File.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
SET stat=myloader.SetLister(mylister)
SET install=$SYSTEM.Util.InstallDirectory()
SET dirpath=install_"mgr\Temp\iknow\mytextfiles"
SET stat=myloader.ProcessList(dirpath,$LB("txt"),0,"")
IF stat '= 1 { WRITE "Loader error ",$System.Status.DisplayError(stat)
QUIT }
SourceSentenceQueries
SET numSrcD=##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
SET numSentD=##class(%iKnow.Queries.SentenceAPI).GetCountByDomain(domId)
WRITE "These sources contain ",numSentD," sentences",!!
DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId,1,20)
SET i=1
WHILE $DATA(result(i)) {
SET extId = $LISTGET(result(i),2)
SET fullref = $PIECE(extId,":",3,4)
SET fname = $PIECE(fullref,"\",$LENGTH(extId,"\"))
SET numSentS = ##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,result(i))
WRITE fname," has ",numSentS," sentences",!
SET i=i+1 }
以下の例では、Aviation.Event SQL テーブルのフィールドからロードしたデータを使用して、これらの文カウント・メソッドを示しています。この例においては、10 個のデータ・レコード (上位 10) のサンプルのみをロードしています。
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT Top 10 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceSentenceQueries
SET numSrcD=##class(%iKnow.Queries.SourceQAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
SET numSentD=##class(%iKnow.Queries.SentenceQAPI).GetCountByDomain(domId)
WRITE "These sources contain ",numSentD," sentences",!!
DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId,1,20)
SET i=1
WHILE $DATA(result(i)) {
SET extId = $LISTGET(result(i),2)
SET fullref = $PIECE(extId,":",3,4)
SET fname = $PIECE(fullref,"\",$LENGTH(extId,"\"))
SET numSentS = ##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,result(i))
WRITE fname," has ",numSentS," sentences",!
SET i=i+1 }
iKnow が何を文と判断するかについての詳細は、“コンセプトの概要” の章の "iKnow が識別する論理テキスト・ユニット" の節を参照してください。
エンティティのカウント
指定のエンティティが 1 か所以上出現するソースの数をカウントするには、%iKnow.Queries.SourceAPIOpens in a new tab クラスの GetCountByEntities()Opens in a new tab メソッドを使用できます。このメソッドでは、ロードされたソース内で検索する 1 つ以上のエンティティについてのリストを指定できます。
ここでは、また iKnow 全体を通して、“エンティティ“ という概念は、検索関連の用語として馴染んだ概念とは大きく異なることに注意してください。例えば、エンティティ “dog“ は、“The quick brown fox jumped over the lazy dog.“ という文には出現しません。この文に出現するのは、“lazy dog“ というエンティティです。エンティティは概念または関係になります。例えば、エンティティ “is“ またはエンティティ “jumped over“ を含むソースの数をカウントすることが可能です。ただし、この例や現実のほとんどのケースでは、iKnow は関係によって関連付けられた 1 つ以上の概念をマッチングさせます。
以下の例は、こうしたクエリ・カウント・メソッドを示しています。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
SET numSrcD=##class(%iKnow.Queries.SourceQAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
SingleEntityCounts
SET ent=$LB("NTSB","National Transportation Safety Board",
"NTSB investigator-in-charge","NTSB oversight","NTSB's Materials Laboratory",
"FAA","Federal Aviation Administration","FAA inspector")
SET entcnt=$LISTLENGTH(ent)
SET ptr=0
FOR x=1:1:entcnt {
SET stat=$LISTNEXT(ent,ptr,val)
WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByEntities(domId,val)," contain ",val,!
}
WRITE "end of listing"
上位エンティティのリスト
iKnow には、ドメインのソース・ドキュメントの “上位“ エンティティを返すために使用できる以下 3 つのクエリ・メソッドがあります。
-
GetTop()Opens in a new tab は、最も頻繁に出現しているエンティティを出現頻度の回数 (既定) による降順にてリストします。また、これを使用すれば、分散により最も頻繁に出現しているエンティティをリストすることもできます。このメソッドでは、各エンティティに対して頻度と分散を指定します。これは、上位エンティティの最も基本的なリストとなります。
-
GetTopTFIDF()Opens in a new tab は、TFIDF スコアと類似した頻度基準のメトリックを使用して、上位エンティティをリストします。エンティティの用語頻度 (TF :Term Frequency) を逆文書頻度 (IDF :Inverse Document Frequency) と組み合わせることで、このスコアを計算します。用語頻度では、単一ソース内でのエンティティの出現頻度をカウントします。逆文書頻度は、エンティティの分散 (“文書頻度“ とも言う) の逆数に基づきます。この IDF 頻度を使用することにより、用語頻度を減らします。したがって、少ないパーセンテージのソースにおいて複数回出現するエンティティは、TFIDF スコアが高くなります。大きいパーセンテージのソースにおいて複数回出現するエンティティは、TFIDF スコアが低くなります。
-
GetTopBM25()Opens in a new tab は、Okapi BM25 アルゴリズムと類似した頻度基準のメトリックを使用して、上位エンティティをリストします。これは、文書の長さを考慮しつつ、エンティティの用語頻度を逆文書頻度 (IDF) と組み合わせるものです。
これら 3 つのメソッドはすべて、既定にて上位の概念を返しますが、上位の関係を返すために使用することはできません。これら 3 つのメソッドはすべて、フィルタの適用により、使用するソースの対象範囲を制限することができます。
GetTop() メソッドは 3 文字未満のエンティティを無視します。GetTopTFIDF() および GetTopBM25() メソッドは 1 文字および 2 文字のエンティティを返すことができます。
GetTop() :最も頻繁に出現しているエンティティ
iKnow クエリは、ソース・ドキュメントにおいて最も頻繁に出現しているエンティティを、頻度または分散度の高いものから順番に返すことができます。各エンティティは、別個のレコードとして Caché リスト形式で返されます。
エンティティ・レコードの形式は以下のとおりです。
-
エンティティ ID : iKnow が割り当てる一意の整数。
-
エンティティ値 : 文字列として指定されます。
-
頻度 : ソース・ドキュメントにエンティティが出現する回数を表す整数値。
-
分散 : エンティティを含むソース・ドキュメントの数を表す整数値。
以下のクエリは、このプログラムがロードしたソースに最も頻繁に出現している (上位) エンティティを返します。既定により、これらは概念エンティティとなります。ここでは page (1) および pagesize (50) パラメータを設定して、何個のエンティティを返すかを指定しています。これは (最大で) 上位 50 個のエンティティを返します。これはドメインの既定の sorttype を使用しますが、以下のように頻度による降順となっています。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
SET numSrcD=##class(%iKnow.Queries.SourceQAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
TopEntitiesQuery
DO ##class(%iKnow.Queries.EntityAPI).GetTop(.result,domId,1,50)
SET i=1
WHILE $DATA(result(i)) {
SET outstr = $LISTTOSTRING(result(i),",",1)
SET entity = $PIECE(outstr,",",2)
SET freq = $PIECE(outstr,",",3)
SET spread = $PIECE(outstr,",",4)
WRITE "[",entity,"] appears ",freq," times in ",spread," sources",!
SET i=i+1 }
WRITE "Printed the top ",i-1," entities"
以下の GetTop() メソッドは分散による上位エンティティを返します。
DO ##class(%iKnow.Queries.EntityAPI).GetTop(.result,domId,1,50,,,$$$SORTBYSPREAD)
GetTopTFIDF() および GetTopBM25()
これらの 2 つのメソッドは、算出スコアによる降順にて上位エントリのリストを返します。既定により、これらは概念エンティティとなります。これらは異なるアルゴリズムを使用して、スコアをエンティティに割り当てるので、“上位“ エンティティのリストは大幅に異なる場合があります。例えば、以下のテーブルでは、各種メソッドを使用して分析を行った場合における、Aviation.Event データベースで 4 個のエントリの相対順序を示しています。
“airplane” | “helicopter” | “flight instructor” | “student pilot” | |
---|---|---|---|---|
GetTop() | 1 番 | 12 番 | 17 番 | 43 番 |
GetTopTFIDF() | (リストになし) | 1 番 | 4 番 | 22 番 |
GetTopBM25() | (リストになし) | 3 番 | 2 番 | 1 番 |
GetTop() にて返される Aviation.Event データベースの上位 5 つのエンティティは、“airplane“、“pilot“、“engine“、“flight“、および “accident“ となります。これらのエンティティはすべて、半数を超えるソースにて最低 1 回は出現します。これらは頻繁に出現するエンティティである一方で、特定ソースの内容を決定付けるにはほとんど価値のないものです。半数を超えるソースで出現するエンティティには、負の IDF 値が与えられます。このため、これらのエンティティは GetTopTFIDF() および GetTopBM25() のリストに現れません。
以下の例では、GetTopTFIDF() を使用して、上位 50 個のエンティティをリストします。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
SET numSrcD=##class(%iKnow.Queries.SourceQAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
TopEntitiesQuery
DO ##class(%iKnow.Queries.EntityAPI).GetTopTFIDF(.result,domId,1,50)
SET i=1
WHILE $DATA(result(i)) {
SET outstr = $LISTTOSTRING(result(i),",",1)
SET entity = $PIECE(outstr,",",2)
SET score = $PIECE(outstr,",",3)
WRITE "[",entity,"] has a TFIDF score of ",score,!
SET i=i+1 }
WRITE "Printed the top ",i-1," entities"
以下の例では、GetTopBM25() を使用して、上位 50 個のエンティティをリストします。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
SET numSrcD=##class(%iKnow.Queries.SourceQAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
TopEntitiesQuery
DO ##class(%iKnow.Queries.EntityAPI).GetTopBM25(.result,domId,1,50)
SET i=1
WHILE $DATA(result(i)) {
SET outstr = $LISTTOSTRING(result(i),",",1)
SET entity = $PIECE(outstr,",",2)
SET score = $PIECE(outstr,",",3)
WRITE "[",entity,"] has a BM25 score of ",score,!
SET i=i+1 }
WRITE "Printed the top ",i-1," entities"
CRC クエリ
CRC (コンセプト - リレーション - コンセプトのシーケンス) を返す iKnow クエリは、以下の形式でこれを返します。
-
CRC ID : iKnow が割り当てる一意の整数。
-
マスタ・コンセプト : 文字列として指定されます。
-
リレーション : 文字列として指定されます。
-
スレーブ・コンセプト : 文字列として指定されます。
-
頻度 : ソース・ドキュメントに CRC が出現する回数を表す整数値。
-
分散 : CRC を含むソース・ドキュメントの数を表す整数値。
エンティティを含む CRC のリスト
CRC の一般的な使用方法の 1 つに、エンティティ (通常はコンセプト) を指定して、そのエンティティを含む CRC を返す、というものがあります。この場合、1 つまたは複数のソースにエンティティが出現するさまざまなコンテキストを提供します。iKnow はすべてのテキストを小文字に正規化するため、一致させるエンティティは小文字で指定する必要があります。
以下のクエリは、指定されたコンセプト (“left wing“、"right wing"、"wings"、"leading edge" および "trailing edge") を含むすべての CRC を、CRC のマスタ概念またはスレーブ概念として返します。GetByEntities() メソッドの page 引数では、より多くの CRC を返すように、25 が設定されていますが、既定値は 10 となります。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
CRCQuery
SET myconcepts=$LB("left wing","right wing","wings","leading edge","trailing edge")
DO ##class(%iKnow.Queries.CrcAPI).GetByEntities(.result,domId,myconcepts,1,25)
SET i=1
WHILE $DATA(result(i)) {
SET mycrcs=$LISTTOSTRING(result(i),",",1)
WRITE "[",$PIECE(mycrcs,",",2,4),"]"
WRITE " appears ",$PIECE(mycrcs,",",5)," times in "
WRITE $PIECE(mycrcs,",",6)," sources",!
SET i=i+1 }
WRITE !,"End of listing"
CRC を含むソースのカウント
以下のサンプル・プログラムは、指定された CRC を含むソースの数を返します。CRC を GetCountByCrcs()Opens in a new tab メソッドに指定するには、($LB を使用して) それぞれの CRC を %List として指定してから、これらの CRC を %List としてグループ化する必要があります。詳細は、以下の例を参照してください。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
CRCCount
SET numSrcD=##class(%iKnow.Queries.SourceQAPI).GetCountByDomain(domId)
SET mycrcs=$LB($LB("leading edge","of","wing"),$LB("leading edge","of","right wing"),
$LB("leading edge","of","left wing"),$LB("leading edges","of","wings"),
$LB("leading edges","of","both wings"))
SET numSrc=##class(%iKnow.Queries.SourceAPI).GetCountByCrcs(domId,mycrcs)
WRITE "From ",numSrcD," indexed sources there are ",!
WRITE numSrc," sources containing one or more of the following CRCs:",!
FOR i=1:1:$LISTLENGTH(mycrcs) {
WRITE $LISTTOSTRING($LIST(mycrcs,i)," "),!
}
GetCountByCrcs() メソッドは、指定された CRC のいずれかを含むソースの数を返します。
CRC マスクを満たす 1 つまたは複数の文のリスト
CRC マスクを使用して、特定 CRC ポジションのエンティティ値を指定することができます。それぞれの CRC は、マスタ、関係、スレーブという 3 つのポジションを備えています。CRC マスクを使用して、各ポジションのエンティティ値またはワイルドカードを指定できます。CRC マスクにより、1 つ以上のポジション値が一致する CRC を含むソースや文をリストできます。GetByCrcMask() による部分的 CRC 一致ではポジションとエンティティ値の両方を指定するため、GetByEntities() より一致条件が制限されますが、GetByCrcs() ほどは制限されません。
以下の例では、マスタ・ポジションでエンティティ “student pilot“ に一致する CRC マスクを使用すると同時に、ワイルドカードを使用して、CRC の関係およびスレーブ・ポジションにおいて任意の値を許可しています。GetByCrcMask()Opens in a new tab メソッドは、各ソースのそれぞれの文に対してこのマスクをマッチングさせ、マスタ・ポジションに “student pilot“ の CRC を含む文の ID とテキストを返します。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
CRCMaskSentencesBySource
DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId,1,100)
SET i=1
WHILE $DATA(result(i)) {
SET srcId = $LISTGET(result(i),1)
SET extId = $LISTGET(result(i),2)
SET srcname = $PIECE($PIECE(extId,":",3,4),"\",$LENGTH(extId,"\"))
SET numSentS = ##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,result(i))
WRITE numSentS," sentences in ",srcname,!
SET stat=##class(%iKnow.Queries.SentenceAPI).GetByCrcMask(.sentresult,domId,"student pilot",
$$$WILDCARD,$$$WILDCARD,srcId)
SET i=i+1
FOR j=1:1:20 {
IF $DATA(sentresult(j)) {
SET sent = $LISTTOSTRING(sentresult(j),",",1)
SET sentId = $PIECE(sent,",",3)
WRITE "The SentenceId is ",sentId," in source ",srcname,":",!
WRITE " ",##class(%iKnow.Queries.SentenceAPI).GetValue(domId,sentId),!
}
ELSE { WRITE "Listed ",j-1," sentence that match the CRC mask",!!
QUIT }
}
}
類似エンティティのリスト
指定の文字列に類似した一意のエンティティをリストできます。以下のいずれかに該当する場合、エンティティは類似しています。
-
文字列がエンティティと同じである場合。
-
文字列がエンティティの単語の 1 つである場合。
-
文字列がエンティティの単語の 1 つの最初の文字である場合。
類似性クエリでは、それぞれの一意のエンティティ (マスタ・コンセプトまたはスレーブ・コンセプト) と共に、その頻度と分散の整数値が、それらの整数値の降順で返されます。類似性クエリでは、リレーションはマッチングされません。iKnow では常にそうであるように、マッチングでは大文字と小文字は区別されず、すべてのエンティティが小文字で返されます。類似性クエリでは語幹解析ロジックは使用されず、“cat“ と指定すると “cats“ と “category“ の両方が返されます。
以下の例では、文字列 “student pilot“ に類似したエンティティがリストされます。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)," total sources",!!
SimilarEntityQuery
WRITE "Entities similar to 'Student Pilot':",!
DO ##class(%iKnow.Queries.EntityAPI).GetSimilar(.simresult,domId,"student pilot",1,50)
SET j=1
WHILE $DATA(simresult(j)) {
SET outstr = $LISTTOSTRING(simresult(j),",",1)
SET entity = $PIECE(outstr,",",2)
SET freq = $PIECE(outstr,",",3)
SET spread = $PIECE(outstr,",",4)
WRITE "(",entity,") appears ",freq," times in ",spread," sources",!
SET j=j+1 }
エンティティの類似性を左右する既定のドメイン・パラメータ設定は、EnableNgrams というブーリアン値です。
パーツと N-gram
GetSimilar()Opens in a new tab および GetSimilarCounts()Opens in a new tab メソッドは、類似性を検索する場所を指定するモード・パラメータを備えています。利用可能な値は以下の 2 つです。
-
$$$USEPARTS を使用すると、iKnow は各パーツ (単語) の先頭をマッチングさせて類似性をチェックします。英語をはじめとするほとんどの言語のテキストでは、これは一般的に優先設定になります。$$$USEPARTS は既定値です。
-
$$$USENGRAMS を使用すると、iKnow は単語と単語内の言語単位 (N-gram) をマッチングさせて類似性をチェックします。このモードは、ソース・テキストの言語が単語を組み合わせる場合に使用されます。例えば、$$$USENGRAMS は、頻繁に複合語が形成されるドイツ語でよく使用されます。単語の組み合わせを行わない英語では、$$$USENGRAMS は使用されません。$$$USENGRAMS は、EnableNgrams ドメイン・パラメータのセットを持つドメインでのみ使用できます。
パスのカウント
以下の例は、50 個のソースのパスの数と文の数を示しています。通常は、ソース内の文よりも多くのパスが存在します。ただし、いくつかのソース内のパスよりも文が多く存在することは可能です。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 50 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)," total sources",!!
PathCountBySource
DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId,1,50)
SET i=1
WHILE $DATA(result(i)) {
SET srcId = $LISTGET(result(i),1)
SET extId = $LISTGET(result(i),2)
SET fullref = $PIECE(extId,":",3,4)
SET fname = $PIECE(fullref,"\",$LENGTH(extId,"\"))
SET numPathS = ##class(%iKnow.Queries.PathAPI).GetCountBySource(domId,$LB(srcId))
SET numSentS = ##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,result(i))
WRITE numPathS," paths and ",numSentS," sentences in ",fname,!
SET i=i+1 }
類似ソースのリスト
iKnow 意味分析エンジンは、指定のソースに類似するソースをリストできます。ソース間の類似性は、両方のソースに出現するエンティティ (重複) の数と、重複を含むソース・コンテンツのパーセンテージによって決まります。
GetSimilar()Opens in a new tab メソッドは指定のソースに対して、ソースの類似性を計算することができます。大量の類似ソースが存在する可能性があるので、通常はこのメソッドをフィルタと共に使用することで、考慮対象のソース・セットを制限します。GetSimilar() は、以下の 2 つのアルゴリズムから選択可能であり、それぞれがアルゴリズム・パラメータを持っています。
-
項目の基本的類似性 ($$$SIMSRCSIMPLE、既定) : 使用できるアルゴリズム・パラメータは、“ent“ (エンティティの類似性、既定)、“crc“ (コンセプト - リレーション - コンセプトのシーケンス)、または “cc“ (コンセプト - コンセプトのペア) となります。
-
意味的優位性 の計算 ($$$SIMSRCDOMENTS) : アルゴリズム・パラメータは、指定ソース内での優位性の高いエンティティでもある高優位性エンティティを含むソースに対して、類似性を制限するブーリアン・フラグとなります。
iKnow は、類似するそれぞれのソースについて、以下の形式で要素のリストを返します。
srcId,extId,percentageMatched,percentageNew,nbOfEntsInRefSrc,nbOfEntsInCommon,nbOfEntsInSimSrc,score
srcId | ソース ID。iKnow が割り当てる整数です。 |
extId | ソースの外部 ID (文字列値)。 |
percentageMatched | 一致元ソースと同じソース・コンテンツのパーセンテージ。 |
percentageNew | 新しいソース・コンテンツのパーセンテージ。新しいコンテンツは、一致元ソースと一致しないコンテンツです。 |
nbOfEntsInRefSrc | 参照される (このソースに対してマッチングされる) ソース内の一意のエンティティの数。 |
nbOfEntsInCommon | 両方のソースにある一意のエンティティの数。 |
nbOfEntsInSimSrc | このソース内の一意のエンティティの数。 |
スコア | 小数で表される類似性スコア。同一のソースは類似性スコアが 1 となります。 |
以下の例は、類似するソースのリストを示しています。最初に、GetByEntities() を使用して適切なエンティティ のリストを選択することにより、テスト・ソースのセットを engine failure incident (エンジン故障事故) を述べる可能性のあるものに制限しています。次に、GetSimilar() を使用して、これらのテスト・ソースと類似するソースを検出します。これは類似事象パターンを示している可能性があります。GetSimilar() は、既定の類似性アルゴリズム ($$$SIMSRCSIMPLE) およびその既定アルゴリズム・パラメータ (“ent“) を使用しています。このプログラムは、高類似性スコア (>.33) 持つ類似ソースのみを表示します。類似性の表示では、ソースの外部 ID は省略されています。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceCountQuery
SET totsrc = ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
WRITE totsrc," total sources",!
SimiarSourcesQuery
SET engineents = $LB("engine","engine failure","engine power","loss of power","carburetor","crankshaft","piston")
DO ##class(%iKnow.Queries.SourceAPI).GetByEntities(.result,domId,engineents,1,totsrc)
SET i=1
WHILE $DATA(result(i)) {
SET src = $LISTTOSTRING(result(i),",",1)
SET srcId = $PIECE(src,",",1)
WRITE "Source ",srcId," contains an engine incident",!
DO ##class(%iKnow.Queries.SourceAPI).GetSimilar(.sim,domId,srcId,1,50,"",$$$SIMSRCSIMPLE,$LB("ent"))
SET j=1
WHILE $DATA(sim(j)) {
SET simlist=$LISTTOSTRING(sim(j))
IF $PIECE(simlist,",",8) > .33 {
WRITE " similar to source ",$PIECE(simlist,",",1),": "
WRITE $PIECE(simlist,",",3,8),! }
SET j=j+1 }
SET i=i+1 }
ソースの要約
iKnow 意味分析エンジンは、最も関連性のある文を返すことでソース・テキストを要約できます。これは、ソース・テキストのコンテンツ全体に最も類似する文を選択して、それらの文をユーザが指定した数だけ、元の文の順序で返します。iKnow はそれぞれの文について内部関連性スコアを計算して、関連性を判断します。ソース・テキストに何度も出現する概念を含む文は、ソース・テキストに一度しか出現しない概念を含む文よりは、要約に含まれる可能性が高くなります。iKnow は、各概念の総合的な頻度、ソースにおいて最も頻度の高い概念に対する各概念の類似性、および他の要因を考慮します。
ソースの要約は、ソースのロード時に構成で Summarize プロパティが 1 に設定された場合にのみ利用可能となります。既定の構成では、Summarize=1 が指定されます。
したがって、要約の正確さは、以下の 2 つの要因によって左右されます。
-
ソース・テキストは、意味のある頻度分析ができるだけの十分な大きさがあることが必要ですが、大き過ぎることも禁物です。iKnow の要約は、長い章や項目のテキストで最も効果を発揮します。本一冊分のテキストは、章ごとに要約する必要があります。
-
ユーザが読んで理解できる要約テキストが返される文によって構成されるように、要約内の文の数は元のテキストの十分大きなサブセットであることが必要です。要約割合の最小値は、25 % ~ 33 % となり、テキストの内容により異なります。
iKnow には、以下の 3 つの要約メソッドが用意されています。
-
GetSummary()Opens in a new tab では、要約テキストの各文を個々の結果として返します。この文の ID は、返された各文の先頭要素として返されます。
-
GetSummaryDirect()Opens in a new tab では、要約テキストを 1 つの文字列として返します。既定では、この文字列内の文は省略記号 (空白スペース、3 つのピリオド、空白スペース) によって区切られます。例えば、“This is sentence one. ... This is sentence two.” のようになります。必要に応じて、別の文区切りを指定できます。このメソッドでは、複数の文を 1 つの文字列に連結するため、Caché の最大文字列長より長い文字列の作成を試みる場合があります。最大文字列長に達すると、Caché では、このメソッドの isTruncated というブーリアン出力パラメータが 1 に設定され、残りのテキストが切り捨てられます。
-
GetSummaryForText()Opens in a new tab では、特定のソース ID を指定するのではなく、ユーザ指定文字列の要約を直接編集する方式をサポートしています。
iKnow が何を文と判断するかについての詳細は、“コンセプトの概要” の章の "iKnow が識別する論理テキスト・ユニット" の節を参照してください。
以下の例では、101 以上の文を含むものを見つけるまで、ドメイン内のソース・テキストをチェックします。次に、GetSummary() を使用して、そのソースを元の文の半分に要約します。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceSentenceTotals
SET numSrcD=##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
SET numSentD=##class(%iKnow.Queries.SentenceAPI).GetCountByDomain(domId)
WRITE "These sources contain ",numSentD," sentences",!!
DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId)
SentenceCounts
FOR i=1:1:numSrcD {
SET srcId = $LISTGET(result(i),1)
SET extId = $LISTGET(result(i),2)
SET fullref = $PIECE(extId,":",3,4)
SET fname = $PIECE(fullref,"\",$LENGTH(extId,"\"))
SET numSentS = ##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,result(i))
IF numSentS > 100 {WRITE fname," has ",numSentS," sentences",!
GOTO SummarizeASource }
}
QUIT
SummarizeASource
SET sumlen=$NUMBER(numSentS/2,0)
WRITE "total sentences=",numSentS," summary=",sumlen," sentences",!!
DO ##class(%iKnow.Queries.SourceAPI).GetSummary(.sumresult,domId,srcId,sumlen)
FOR j=1:1:sumlen { WRITE "[S",j,"]: ",$LISTGET(sumresult(j),2),! }
WRITE !,"END OF ",fname," SUMMARY",!!
QUIT
$NUMBER は、要約文の指定数を確実に整数にするために使用されています。$LISTGET は、文 ID を削除して、文テキストだけを返すために使用されています。
以下の例では、GetSummaryDirect() を使用して、連結された 1 つの文字列として同じ要約が返されます。次に、$EXTRACT を使用して、その文字列を以下のように表示するために、38 文字の行に分割します。
#Include %IKPublic
ZNSPACE "Samples"
DomainCreateOrOpen
SET dname="mydomain"
IF (##class(%iKnow.Domain).Exists(dname))
{ WRITE "The ",dname," domain already exists",!
SET domoref=##class(%iKnow.Domain).Open(dname)
GOTO DeleteOldData }
ELSE
{ WRITE "The ",dname," domain does not exist",!
SET domoref=##class(%iKnow.Domain).%New(dname)
DO domoref.%Save()
WRITE "Created the ",dname," domain with domain ID ",domoref.Id,!
GOTO ListerAndLoader }
DeleteOldData
SET stat=domoref.DropData()
IF stat { WRITE "Deleted the data from the ",dname," domain",!!
GOTO ListerAndLoader }
ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat)
QUIT}
ListerAndLoader
SET domId=domoref.Id
SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId)
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
QueryBuild
SET myquery="SELECT TOP 100 ID AS UniqueVal,Type,NarrativeFull FROM Aviation.Event"
SET idfld="UniqueVal"
SET grpfld="Type"
SET dataflds=$LB("NarrativeFull")
UseLister
SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds)
IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT }
UseLoader
SET stat=myloader.ProcessBatch()
IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT }
SourceSentenceTotals
SET numSrcD=##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
WRITE "The domain contains ",numSrcD," sources",!
SET numSentD=##class(%iKnow.Queries.SentenceAPI).GetCountByDomain(domId)
WRITE "These sources contain ",numSentD," sentences",!!
DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId)
SentenceCounts
FOR i=1:1:numSrcD {
SET srcId = $LISTGET(result(i),1)
SET extId = $LISTGET(result(i),2)
SET fullref = $PIECE(extId,":",3,4)
SET fname = $PIECE(fullref,"\",$LENGTH(extId,"\"))
SET numSentS = ##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,result(i))
IF numSentS > 100 {WRITE fname," has ",numSentS," sentences",!
GOTO SummarizeASource }
}
QUIT
SummarizeASource
SET sumlen=$NUMBER(numSentS/2,0)
WRITE "total sentences=",numSentS," summary=",sumlen," sentences",!!
SET summary = ##class(%iKnow.Queries.SourceAPI).GetSummaryDirect(domId,srcId,sumlen)
FormatSummaryDisplay
SET x=1
SET totlines=$LENGTH(summary)/38
FOR i=1:1:totlines {
WRITE $EXTRACT(summary,x,x+38),!
SET x=x+39 }
WRITE !,"END OF ",fname," SUMMARY"
カスタム・サマリ
iKnow では、summaryConfig パラメータ文字列を指定することで、ソースのカスタム・サマリを生成できます。カスタム・サマリは、iKnow で生成されたサマリの内容を自身のニーズに合わせて調整したいユーザのために提供されています。カスタム・サマリにより、文の要約への絶対的な包含、優先的な包含、または文の要約からの絶対的な除外が可能になります。例えば、タイトル、署名、著作権、抜粋、または要旨など常に同じ位置に現れるソースの標準コンポーネントを包含または除外することができます。また、指定した単語を含む文を、絶対的または優先的に包含/除外することもできます。
ソースの要約処理では、始めに各文に数値的な要約重要度が付与された後、最も重要度の高い文の適切な番号を選択することにより、要約を作成します。要約メソッドに対して summaryConfig パラメータを指定することで、このランキングを左右することもできます。
summaryConfig パラメータの値は、1 つ以上の仕様から成る文字列となります。各仕様は垂直バー ( | ) で仕切られた 3 つの要素から成ります。例えば、"s|2|false" となります。垂直バー ( | ) を使用して、複数の仕様を連結できます。例えば、"s|1|true|s|2|false" となります。summaryConfig パラメータの既定値は空の文字列です。
以下に従って、要約を構成することで、文を選択することができます。
-
常に文を包めます (または一切包めない)。
-
文の番号によるもの : "s|1|true" は、文 (s) の番号 1 を常に要約に包める (true) という意味です。例えば、ソースが常にタイトルを含んでいる場合、要約に最初の文 (タイトル) を常に含むことが効果的となります。各ソースの 2 行目が署名である場合、かつこれを要約に含めない場合は、これを "s|2|false" として指定できます。また、次のように最後の文を要約に含めないことを指定できます。"s|-1|false" は、すべてのソースが写しの参照や刊行物の引用で終わっている場合に適しています。ソースの文は 1 から順番に番号を割り振るか、もしくは、ソースの最後から -1、-2 などと番号を割り振っていきます。
-
単語によるもの : "w|requirement|true" は、単語 (w) requirement を含む文はいずれも、常に要約に含める (true) という意味です。また、特定の単語を含む文を除外することもできます。例えば、"w|foreign|false" により、単語 foreign を含む文はすべて要約から除外されます。“単語“ を 1 つ以上の単語でまとめることもできます。その場合、空白で区切られた複数の単語の文字列で構成されます。部分語の文字列で構成することはできません。単語は正規化されるので、すべて小文字で指定する必要があります。
-
-
文に高い要約重要度を付与します。これにより、文が要約内で出現する可能性が高くなります。使用できる重要度の値は、 0 ~ 9 の整数となります。
-
文の番号によるもの : "s|1|3" は、文 (s) の番号 1 が 3 の要素により増加する要約重要度を備えているという意味です。例えば、内容をある程度記述している場合は、ソースのタイトル (最初の文) を含める必要がありますが、直接的な記述でない場合 (文学的な引用など) は、その必要はありません。ソースの文は 1 から順番に番号を割り振るか、もしくは、ソースの最後から -1、-2 などと番号を割り振っていきます。
-
単語によるもの : "w|requirement|2" は、単語 (w) requirement を含む文はいずれも、2 の要素により増加する要約重要度を備えているという意味です。“単語“ を 1 つ以上の単語でまとめることもできます。その場合、空白で区切られた複数の単語の文字列で構成されます。部分語の文字列で構成することはできません。単語は正規化されるので、すべて小文字で指定する必要があります。
-
連結演算により、複数の要約のカスタマイズを指定することができます。以下はその例です。"s|1|true|s|2|false|w|surgery|3|w|hypnosis|false" は、常に最初の文を含め、2 番目の文は除外し、単語 “surgery“ を含む文はすべて要約重要度を増やし、単語 “hypnosis“ を含む文はすべて除外するという意味になります。
したがって、特定の単語または文により高い (またはより低い) 重要性を与えることができます。summaryConfig の複数の仕様によって影響を受ける文の重要度は、カスタム・サマリ・アルゴリズムにより解決します。また、このアルゴリズムは、同じ文に適用する仕様の間で重複がある場合に適用します。
-
文 (s) の仕様と単語 (w) の仕様の間で重複がある場合、文の仕様が優先します。
-
2 つの s の仕様または 2 つの w の仕様に関して、包含 (true) と除外 (false) の間で重複がある場合、包含の仕様が優先します。
-
特定の要約の長さと、含める必要のある文の数または除外する必要のある文の数の間で重複がある場合、要約の長さは無視されます。
カスタム・サマリのオプションは、%iKnow.Queries.SourceAPI.GetSummary()Opens in a new tab および %iKnow.Queries.SourceAPI.GetSummaryForText()Opens in a new tab メソッドの summaryConfig パラメータにより設定できます。
ソースのサブセットのクエリ
iKnow のフィルタを使用すると、クエリにソースを含めたり、クエリからソースを除外できます。以下に基づいて、ソースを包含または除外することができます。
-
ソースのランダム・サンプリング
-
ソース・コンテンツ : 指定されるエンティティまたはディクショナリに一致するエンティティ
-
ソースの特性 (メタデータ) : ソース ID、文の数、およびソースのインデックス作成日 (ソースが iKnow にロードされた日付)
-
ソースのユーザ定義のメタデータ特性
iKnow では、論理 AND および論理 OR 演算子により、複数のフィルタを組み合わせて使用できます。詳細は、このドキュメントの "フィルタ処理" の章を参照してください。