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?

テキスト・カテゴリ化

テキストのカテゴリ化により、ソース・テキストの内容に基づいて、カテゴリ・ラベルをそれらのテキストに割り当てることができます。

例えば、数多くの Aviation Event (航空イベント) テキストがあり、それらを “airplane”、“helicopter”、“glider” などの AircraftCategory ラベルで分類する場合を想定します。これらのサンプル・テキストの内容において、いずれの iKnow エンティティ がカテゴリ・ラベルと強く結び付くかを決めることで、テキスト分類モデルを作成でき、以降の Aviation Event テキスト (割り当てられたカテゴリがないもの) に適用できます。

以下のように、適切なカテゴリを定義することは、テキストのカテゴリ化にとって欠かせない準備作業となります。

  • 各ソースは 1 つのカテゴリのみに割り当てることができます。1 つのソースは 1 つのカテゴリへの割り当てとなり、複数のソースに 1 つのカテゴリが割り当てられることはありません。各ソースは、定義されたカテゴリのいずれかと一義的に対応する必要があります。

  • カテゴリ値 (ラベル) の数は固定となります。さらなるカテゴリ・ラベルをテキスト分類モデルに追加することはできないので、将来的ソースはすべて当初のカテゴリ・ラベルのいずれかにて割り当てができるようにする必要があります。

  • カテゴリ値 (ラベル) の数は少なくする必要があります。カテゴリの設計において、おおよそ同数のソースが各カテゴリ値に割り当てられるようにする必要があります。

テキスト・カテゴリ化の実装

iKnow では、テキスト分類モデルの構築について、以下の 2 つの手法をサポートしています。

  • 分析: カテゴリ・ラベルを持つ既存テキストのセットを分析して、テキスト内のいずれのエンティティがそれらの各カテゴリのメンバシップにおいて最も強力な指示子となるかを判断します。これには、カテゴリ化済みのテキストを代表的するサンプルが必要になります。

  • 規則基準: 既存テキストのセットについての iKnow エンティティ・クエリを実施します。例えば、上位の TFIDF または BM25 エンティティを決定します。%AddCategory()Opens in a new tab を使用して、カテゴリを定義します。テキスト内における価値の高いエンティティの存在について、規則 (ブーリアン・テスト) を策定して、特定のカテゴリを特定の規則で関連付けます。これらの規則を適用することで、あるカテゴリ内におけるテキストのメンバシップを一括して決めることになり、ブーリアン・テストの最高点数によってカテゴリが決定します。これにおいては、カテゴリ化済みのテキスト・セットが必要がありません

以下の説明を、テキスト分類モデルの構築に対する分析手法に適用します。分析手法では、Naive Bayes の統計的分析やユーザ定義の決定規則など、あらゆる分析手法を使用することができます。

テキスト・カテゴリ化を実施するには、最初にテキスト分類子 (テキスト分類モデル) を作成する必要があります。このモデルは、カテゴリ・ラベル割り当て済みソース・テキストのトレーニング・セットに基づきます。それらのトレーニング・セット・テキストの内容を分析することにより、iKnow はいずれの iKnow エンティティがいずれのカテゴリと強く結び付くか判断します。これらの iKnow エンティティをカテゴリと統計的に関連付けたテキスト分類子を構築して、なおかつそのテストを行います。正確なテキスト分類子を得れば、それを新しいソース・テキストで使用して、カテゴリ・ラベルを割り当てることができます。

一般的に、カテゴリはメタデータ・フィールドにて指定されます。各テキストは単一のカテゴリ・ラベルに関連付けられます。各カテゴリをトレーニング・セット内の数多くのテキストにより適度に表現して、各種カテゴリ・ラベルの数をソース・テキストの数に比べて低く抑える必要があります。

iKnow のテキスト分類は、ソース・テキスト内の iKnow エンティティ (単語ではない) から開始します。分析においては、ソース・テキスト内エンティティの頻度だけでなく、エンティティのコンテキスト (エンティティが否定されているかどうかなど)、およびより大きなテキスト・ユニット (CRC や文など) におけるエンティティの出現も使用できます。iKnow 意味分析の全領域を使用することにより、テキスト分類では高精度で価値の高いテキストの分類を実現できます。

分析的なテキスト分類は以下の 3 つのアクティビティで構成されます。

  • テキスト分類子の構築。これには、1 つのテキスト・セット (トレーニング・セット) が必要となり、それぞれのテキストにはカテゴリ・ラベルが割り当てられています。この手順では、それらのテキスト内に存在し、かつ差別化に役立つ可能性のある用語のセット (エンティティ) を選択します。また、トレーニング・セット・テキストにおけるそれらの用語の存在と関連カテゴリ・ラベルとがどのように相関しているかを判断する ClassificationMethod (アルゴリズム) を選択します。

  • テキスト分類子をテストして、その適合性を判断します。これには、別のテキスト・セット (テスト・セット) が必要となり、それぞれのテキストにはカテゴリ・ラベルが割り当てられています。このテスト情報に基づき、構築手順を再検討して、用語の追加や削除を行うことができます。これにより、テキスト分類子モデルの精度が反復的に改善することになります。

  • テキスト分類子を使用して、カテゴリ割り当てのないテキストを分類します。

実装インタフェース

テキスト分類モデルは、以下 2 つの方法のいずれかにより実装することができます。

トレーニング・セットとテスト・セットの確立

いずれのインタフェースを使用するかに関係なく、テキスト分類子を構築する前には、関連付けられたカテゴリ・ラベル付きのデータ・ソースのグループをドメインにロードする必要があります。これらのソースを使用して、テキスト分類子のトレーニングとテストを行います。

Note:

関連付けられたカテゴリ・ラベル付きのソースの既存グループを必要としない規則基準テキスト分類子を作成することも可能です。ただし、この章の例においては、トレーニング・セットとテスト・セットのソースを使用することが必要となります。

ロードしたそれらのソースを (最低 ) 2 つのソース・グループに分割できるようにすることが必要です。それらは、ソースのトレーニング・セットおよびソースのテスト・セットとなります。トレーニング・セットを使うことによって、いずれのエンティティが特定のカテゴリにとって適した指示子となるかを定めます。また、テスト・セット (または複数テスト・セット) を使うことによって、このカテゴリ・ラベル予測割り当てがトレーニング・セット以外のソースに対して意味を成すかどうかを判断します。これにより、特定ソース・グループに対して用語の “重複適合” を防ぎます。トレーニング・セットは 2 つのセットの内で ソースの約 70% を占める大きい方として、残り 30% をテスト・セットとすることをお勧めします。

SQL ソースのトレーニング・セットとテスト・セットへの分割化についての一般的方法の 1 つは、ソースのフィールドをメタデータ・フィールドとして使用することです。< (より小さい) および > (より大きい) の演算子を AddField() に指定すれば、そのフィールドの値に対するブーリアン・テストを実行して、ソースを 2 つのグループに分けることができます。このソース分割はできるだけランダムとする必要があり、通常は SQL RowID をメタデータ・フィールドとして使用することで、これを実現します。

管理ポータルの [テキスト・カテゴリ化] [モデル・ビルダ] は、メタデータ・フィールドの値を使用して、ソースのグループをトレーニング・セットとテスト・セットに分割するように設計されています。

以下の例では、SQL RowID をメタデータ・フィールドとして確立することで、ロードしたソースをトレーニング・セットとテスト・セットに分割するために使用できるようにしています。

  SET myquery="SELECT ID,SkyConditionCeiling,Type,NarrativeFull FROM Aviation.Event"
  SET idfld="ID"
  SET grpfld="Type"
  SET dataflds=$LB("NarrativeFull")   // text data field
  SET metaflds=$LB("SkyConditionCeiling","ID")
  DO ##class(%iKnow.Queries.MetadataAPI).AddField(domId,"SkyConditionCeiling")  // categories field
  DO ##class(%iKnow.Queries.MetadataAPI).AddField(domId,"ID",$LB("=","<=",">")) // set divider field

また、iKnow ソース ID 値を使用すれば、ロードした任意のタイプのソースをグループに分割することができます。%iKnow.Filters.SourceIdFilterOpens in a new tab クラスの使用により、ソースのグループをトレーニング・セットとテスト・セットに分けることが可能です。以下の例では、ソース ID に対してモジュロ除算を使用することで、ロードしたソースの 2/3 を tTrainingSet に配置して、さらに残りを tTestSet に配置しています。

FilterBySrcId
     SET numsrc = ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
     DO ##class(%iKnow.Queries.SourceAPI).GetByDomain(.result,domId,1,numsrc)
       SET j=1
       SET filtlist=""
       WHILE $DATA(result(j)) {
         SET intId = $LISTGET(result(j),1)
         IF intId#3 > 0 {SET filtlist=filtlist_","_intId }
         SET j=j+1
      }
  SET tTrainingSet=##class(%iKnow.Filters.SourceIdFilter).%New(domId,filtlist)
  SET tTestSet = ##class(%iKnow.Filters.GroupFilter).%New(domId, "AND", 1) // NOT filter
  DO tTestSet.AddSubFilter(tTrainingSet)
DisplaySourceCounts
  SET trainsrc = ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId,tTrainingSet)
     WRITE "The training set contains ",trainsrc," sources",!
  SET testsrc = ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId,tTestSet)
     WRITE "The test set contains ",testsrc," sources",!

%iKnow.Filters.RandomFilterOpens in a new tab は、ソースのグループを分割するための別手法となります。ただし、%iKnow.Filters.RandomFilterOpens in a new tab を呼び出すごとに、結果のトレーニング・セットは異なるソースで構成されます。

プログラムによるテキスト分類子の構築

テキスト分類子を構築するには、%iKnow.Classification.BuilderOpens in a new tab オブジェクトを使用します。以下の説明を、テキスト分類子の構築のための分析手法に適用します。

テキスト分類子の作成

テキスト分類子を作成するには、最初にビルダ・オブジェクトをインスタンス化して、これにトレーニング・セットのドメイン名と oref を指定します。さらに、テキスト分類子が使用することになる ClassificationMethod アルゴリズムを構成します。この最も使用が簡単なアルゴリズムは Naive Bayes の定理に基づいています。Naive Bayes では、トレーニング・セットの各カテゴリに対して個々のエンティティの確率を組み合わせて、各カテゴリに属する新しいテキストの全体的確率を計算します。

  SET tBuilder = ##class(%iKnow.Classification.IKnowBuilder).%New("mydomian",tTrainingSet)
  SET tBuilder.ClassificationMethod="naiveBayes"

さらに、テキスト分類子が使用することになるカテゴリを指定します。ソースがカテゴリ・ラベルをメタデータ・フィールドとして指定している場合、%LoadMetadataCategories()Opens in a new tab メソッドを 1 回呼び出すことができます。カテゴリ値またはカテゴリの数さえも指定する必要はありません。以下の例では、Aviation.Aircraft の AircraftCategory メタデータ・フィールドをカテゴリ・フィールドとして使用して、各レコードを 1 つのカテゴリ (“Airplane”、“Helicopter”、“Glider”、“Balloon” など) に割り当てています。

  SET myquery="SELECT TOP 100 E.ID,A.AircraftCategory,E.Type,E.NarrativeFull "_
  "FROM Aviation.Aircraft AS A,Aviation.Event AS E "_
  "WHERE A.Event=E.ID"
  SET idfld="ID"
  SET grpfld="Type"
  SET dataflds=$LB("NarrativeFull")
  SET metaflds=$LB("AircraftCategory")
  SET mstat=##class(%iKnow.Queries.MetadataAPI).AddField(domId,"AircraftCategory")
  IF mstat=1 { 
  SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds,metaflds) }
  .
  .
  .
  WRITE tBuilder.%LoadMetadataCategories("AircraftCategory")

レコードの大半のパーセンテージ (>80%) が “Airplane” に割り当てられている一方で、他のほとんどのラベルには割り当てられたレコードがほんの一握りしかないので、これは有益なカテゴリ・フィールドとなります (ただし、理想的ではない)。理想的には、各カテゴリ・ラベルがテキスト数とおよそ等しく対応する必要があります。各カテゴリがトレーニング・セットの最低 10% を示している限り、ほとんどの分類メソッドは正しく機能します。1 つのカテゴリ・ラベルは複数のソース・テキストと関連付ける必要があります。したがって、潜在的なカテゴリ値をごく少数のテキストと組み合わせて、“miscellaneous” などのカテゴリ・ラベルで、包括的カテゴリとしておくと役に立つ場合があります。

用語ディクショナリの生成

カテゴリを確立したら、テキスト分類子が各テキスト内を検索して、いずれのカテゴリ・ラベルを割り当てるか決めるために使用する用語を選択します。用語は個別に割り当てを行うか、または %PopulateTerms() を使用して、一定のメトリックに従いテキスト内にある複数用語を加えるかのいずれかとすることができます。

%PopulateTerms()Opens in a new tab を使用すれば、テキスト内での頻度に基づき、いくつもの用語を自動的に指定できます。既定では、Naive Bayes アルゴリズム (ほとんどがカテゴリごとの確率の差別化) を使用して、用語が選択されます。

  SET stat=tBuilder.%PopulateTerms(50)

Naive Bayes 以外のメトリックの実装は、サブクラスによって提供することができます。%PopulateTerms() を使用すれば、BM25 または TFIDF アルゴリズムを使って、トレーニング・セット・ドキュメントの上位 X 個の用語を指定できます。

一般的には、%PopulateTerms() および %AddEntity() メソッドの組み合わせを使用して、目的の用語セットを作成することになります。

個々の用語を指定して、テキスト分類子に含めるには、以下のように %AddEntity()%AddCRC()、および %AddCooccurrence() メソッドを使用します。

%AddEntity()Opens in a new tab では、エンティティを単一用語として加えたり、またはエンティティを配列もしくはリストとして指定することで、複数エンティティを単一の複合用語として加えることができます。iKnow はこれらエンティティのカウントおよびスコアを集計して、用語の同義語やグループ変異形を取得できるようにします。

  DO tBuilder.%AddEntity("hang glider")
  DO tBuilder.%AddEntity("fixed wing aircraft","explicit","partialCount")
    SET tData(1)="helicopter",tData(2)="helicopters",tData(3)="twin-rotor helicopter"
  DO tBuilder.%AddEntity(.tData)

%AddEntity() は、否定および部分一致の取り扱い方法を必要に応じて指定できます。これは、前の例における 2 番目の %AddEntity() にて示しています。

%AddCRC()Opens in a new tab では、CRC を単一用語として加えることができます。テキスト分類はソース・テキストの一致頻度によって異なるので、CRC をテキスト分類子用語として役立てることは一般的ではありません。ただし、特定カテゴリに対する強力な指示子となる、きわめて特殊な順序のエンティティ (CRC) がある場合、CRC の追加は合理的となる可能性があります。

%AddCooccurrence()Opens in a new tab によって、単一用語として同一文内に 2 つの指定エンティティの出現を追加できます (順不同)。オプションにより、否定および部分一致の取り扱い方法を指定することもできます。

  WRITE tBuilder.%AddCooccurrence($LISTBUILD("landed","helicopter pad"))

これらの用語は特定カテゴリに関連付けされないことに注意してください。Builder は自動的にこれらの用語を含む各テキストが各カテゴリとどの程度関連しているか計算します。

分類オプティマイザの実行

テキスト分類子の開発時には、試行錯誤によって用語を追加/削除する必要はありません。%iKnow.Classification.OptimizerOpens in a new tab クラスのメソッドを使用すれば、予測精度に大きく影響する該当エンティティを含めることができます。

  1. オプティマイザ・オブジェクトを作成して、そのビルダ・プロパティを使用することにより、関連付けのための %iKnow.Classification.Builder オブジェクトを指定します。オプションにより、ScoreMetric プロパティを設定して、パフォーマンスの測定方法を指定します (既定は MacroFMeasure)。

      SET tOpt = ##class(%iKnow.Classification.Optimizer).%New(domId,tBuilder)
      SET tOpt.ScoreMetric="MicroPrecision"
    
  2. 配列から (LoadTermsArray()Opens in a new tab を使用)、または SQL クエリを使用すること (LoadTermsSQL()Opens in a new tab を使用) のいずれかによって、多数の候補用語を含めます。

  3. Optimize()Opens in a new tab メソッドを実行します。これにより、用語の ScoreMetric 値に基づいて、自動的に用語の追加と削除が行われます。Optimize() では、潜在的に価値の高い用語の追加を指定回数実施して、それらの影響度を計算してから、価値の低い用語を削除します。

テキスト分類子の生成

カテゴリと用語を特定したら、テキスト分類子クラスを生成します。このテキスト分類子クラスには、ソースにある用語に基づいて、最適なカテゴリ・ラベルを特定するためのコードが組み込まれます。以下のように、テキスト分類子のクラス名を指定します。

   WRITE tBuilder.%CreateClassifierClass("User.MyClassifier")

このメソッドによって実行される操作は、指定した ClassificationMethod によって異なります。Naive Bayes では、実際のカテゴリについても把握されている各ソース・テキストの各用語に対する一致スコア/カウントを含んだマトリックスが最初に作成されます。これにより、割り当てられたカテゴリを指定用語がどの程度予測するものであるかについてのモデルを構築します。

ここで使用する例においては、カテゴリが AircraftCategory メタデータ・フィールド値より取得されたものとなります。各用語は各ソースと相関して、カテゴリの決定において、その用語の予測性がどの程度であるか判断します。例えば、用語 “helipad” の存在は AircraftCategory=helicopter を伴うソースを強く予測するものとなっています。用語 “engine” はいくつかのカテゴリ (airplane や helicopter ですが、glider や balloon ではない) を示しているので、単一カテゴリの予測としては弱くなります。ただし、このタイプの用語を含むことにより、一定カテゴリの排除には役立つことがあります。用語 “passenger” はいずれのカテゴリにとっても貧弱な予測に過ぎないので、テキスト分類子モデルには不向きな用語である可能性が高くなります。%AddEntity() および %RemoveTerm() を使用すれば、カテゴリ決定の貢献度に基づいて、用語ディクショナリに適合できます。

テキスト分類子のテスト

テキスト分類子モデルがドキュメントのトレーニング・セットに適合することにより、用語ディクショナリの用語セットが正確にカテゴリを判断します。ここで、ドキュメントの別個セットにてそのモデルをテストして、トレーニング・セットのドキュメント以外においても正確であるかどうか判断する必要があります。このためには、テスト・セットのドキュメントを使用します。トレーニング・セットと同様に、これらのドキュメントにも定義されたカテゴリ・ラベルがあります。

%TestClassifier()Opens in a new tab メソッドを使用すれば、単一の精度値を返すことができます。この精度は、試験したレコードの合計数にて除算された適正予測の数となります。テスト・セットのドキュメントに対してこの精度が上がれば、より良好なモデルということになります。

   WRITE tBuilder.%TestClassifier(tTestSet,,.accuracy),!
   WRITE "model accuracy: ",$FNUMBER(100*accuracy,"L",2)," percent"

すべてのカテゴリに対して、予測精度は同一にならない可能性があります。したがって、個々のカテゴリに対して精度をテストする必要があります。

以下の例では、全体の精度と個別の誤った予測結果を返します。

TestClassifier
  WRITE tBuilder.%TestClassifier(tTestSet,.testresult,.accuracy),!
  WRITE "model accuracy: ",$FNUMBER(accuracy*100,"L",2)," percent",!
  SET n=1
  SET wrongs=0
  WHILE $DATA(testresult(n)) {
    IF $LISTGET(testresult(n),2) '= $LISTGET(testresult(n),3) {
      SET wrongcnt=wrongcnt+1
      WRITE "WRONG: ",$LISTGET(testresult(n),1)
      WRITE " actual ",$LISTGET(testresult(n),2)
      WRITE " pred. ",$LISTGET(testresult(n),3),! }
    SET n=n+1 }
  WRITE wrongcnt," out of ",n-1,!

カテゴリに対する予測精度は、既知のカテゴリに対する予測の一致について可能性のある以下 4 つの結果に基づいて計算されます。

  • True Positive (TP): 予測は Category X であり、実際に Category X である。

  • False Positive (FP): 予測は Category X であるが、実際には別のカテゴリである。

  • False Negative (FN): 予測は別のカテゴリであるが、実際には Category X である。

  • True Negative (TN): 予測は別のカテゴリであり、実際に別のカテゴリである。

これらのカウントを使用して、以下の比率が生成されます。

Precision は、特定のカテゴリについて返された結果の数に対する適正結果の比率となります: TP / (TP+FP)。例えば、用語 “helipad” はカテゴリ Helicopter について高精度の比率に貢献することになり、“helipad” について触れるほぼすべてのテキストはカテゴリ Helicopter に存在します。

Recall は、特定のカテゴリについて返されるはずだった結果の数に対する適正結果の比率となります: TP / (TP+FN)。例えば、用語 “helipad” は、カテゴリ “Helicopter” についての Recall 比率を改善する可能性は高くありません。なぜならば、“helipad” について触れるこれらのテキストはほんの僅かであるためです。

Category X に対するモデルの F-measure (F1) は Precision と Recall の値を組み合わせて、この 2 つの調和平均値を導き出します。Precision の増加は Recall が減少する原因となる場合があり、またその逆の場合もあります。この 2 つの内でいずれを最大化させるかは、使用事例に応じて異なります。例えば、医療スクリーニングのアプリケーションでは、より False Positives を受け入れて、False Negative 数の最小化が望まれる場合があります。

Note:

カテゴリの値がトレーニング・セットになかった場合、テキスト分類子はテスト・セットのテキストに対して、そのカテゴリを予測することはできません。この場合、True Positive (TP) および False Positive (FP) は共にゼロとなり、指定された該当カテゴリにおいて False Negative (FN) がテキストのフル・カウントとなります。

テスト結果の使用

トレーニング・セットの精度とテスト・セットの精度の間に重大な不一致がある場合、用語ディクショナリはトレーニング・セットに “重複適合” されていることになります。この問題を修正するには、ビルド・プロセスに戻り、用語ディクショナリを改訂します。個々の用語を用語配列で置き換えれば、用語ディクショナリを一般化することができます。

  SET stat=tBuilder.%RemoveTerm("Bell helicopter")
  SET tData(1)="Bell helicopter",tData(2)="Bell 206 helicopter",tData(3)="Bell 206A helicopter",
      tData(4)="Bell 206A-1 helicopter",tData(5)="Bell 206L helicopter",tData(6)="Bell 206L LongRanger"
  SET stat=tBuilder.%AddEntity(.tData)

また、個々の用語を変更することで、用語ディクショナリを一般化すれば、完全一致だけでなく、部分一致 ("partialCount") も認められるようになります。

UI を使用したテキスト分類子の構築

Caché 管理ポータルを使用すれば、テキスト分類子を構築できます。管理ポータルの [システム・エクスプローラ] オプションから、[iKnow] オプションを選択してから、[テキスト・カテゴリ化] を選択します。これにより、2 つのオプション [モデル・ビルダ] および [モデル・テスタ] が表示されます。

すべての iKnow ドメインは、特定のネームスペース内に存在します。したがって、使用するネームスペースを指定する必要があります。ネームスペースは、使用する前に、iKnow 対応にしておく必要があります。iKnow 対応ネームスペースを選択すると、iKnow の [テキスト・カテゴリ化] オプションが表示されます。

Note:

iKnow 処理に対して、%SYS ネームスペースを使用することはできません。%SYS ネームスペースにいる間は、管理ポータルの [iKnow] オプションが機能しません (灰色で表示)。したがって、[iKnow] オプションを使用する前に、任意の管理ポータル・インタフェース・ページの上部にある [切り替え] オプションをクリックして、使用する既存ネームスペースを指定する必要があります。

また、ご使用の Web アプリケーションに対して、%iKnow UI クラスを有効化する必要が生じる場合があります。ターミナルを開いて、次のように目的のネームスペースの有効化ユーティリティを実行します: DO EnableIKnow^%SYS.cspServer("/csp/samples/")。(この例では、Samples ネームスペースを有効化しています。)

このインタフェースでは、既存のテキスト分類子を開くか、または新規のテキスト分類子を構築するかのいずれかが可能です。新規のテキスト分類子を構築するには、データ・ソースを含む定義済みドメインが必要となります。データ・ソースはカテゴリ・フィールドを含む必要があります。

UI に対するデータ・セットの定義

新規のテキスト分類子を作成するには、ドメインを作成して、トレーニング・セットとテスト・セットとして使用可能なデータ・ソースによりそのドメインを生成している必要があります。通常、これらのソースのデータは以下の指定が必要になります。

  • テキスト分類子により分析されるテキストを含む 1 つ以上のデータ・フィールド。

  • テキスト分類子により使用されるカテゴリを含むメタデータ・フィールド。データ・ソースには、可能性のある各カテゴリ値に対して最低 1 つのソースが必要となります。

  • データ・ソースのトレーニング・セットとテスト・セットへの分割に使用可能な値を含むメタデータ・フィールド。このフィールドはデータの実際の内容とつながりを持つ必要がないので、ソースのランダム分割が可能になります。例えば、ソース ID 番号または日付や時間の値などがそれに当たります。多くの場合、< (より小さい) および > (より大きい) の演算子を指定して、セットへのソース分割を可能にする必要があります。

以下は、データ・ソース・フィールド定義の例です。

  SET myquery="SELECT TOP 200 E.ID,A.AircraftCategory,E.Type,E.NarrativeFull "_
     "FROM Aviation.Aircraft AS A,Aviation.Event AS E "_
     "WHERE A.Event=E.ID"
  SET idfld="ID"
  SET grpfld="Type"
  SET dataflds=$LB("NarrativeFull")
  SET metaflds=$LB("AircraftCategory","ID")
  DO ##class(%iKnow.Queries.MetadataAPI).AddField(domId,"AircraftCategory")
  DO ##class(%iKnow.Queries.MetadataAPI).AddField(domId,"ID",$LB("=","<=",">"))

テキスト分類子の構築

新規のテキスト分類子を作成するには、[新規] ボタンを選択します。これにより、[新規テキスト分類子の作成] ウィンドウが表示されます。テキスト分類子の新規 [クラス名] を作成します。既存ドメインのドロップダウン・リストから、iKnow の [ドメイン] を選択します。そのドメインに対して定義されたメタデータ・フィールドのドロップダウン・リストから、カテゴリ・ラベルを含む [カテゴリ・フィールド] を選択します。[トレーニング・セット] については、ドロップダウン・リストからメタデータ・フィールドを選択し、さらにドロップダウン・リストから演算子を選択して、値を指定します。例えば、EventDate <= 2004 となります。[テスト・セット] については、同じメタデータ・フィールドおよび補完的な演算子と値を選択します。例えば、EventDate > 2004 となります。また、SQL クエリで [SQL] を使用して、[トレーニング・セット] および [テスト・セット] を指定することができます。

[用語の生成] については、ドロップダウン・リストから派生用語のメソッドを選択して、派生用語の上位数を指定します。例えば、Naive Bayes (NB) に対しては、[NB 差別化による上位 n 個の用語] となります。その後、[作成] をクリックします。

これにより、以下の 3 つのパネルのスクリーンが表示されます。

右側のパネルに [モデルのプロパティ] が表示されます。通常は、これらの値を変更しません。データ・ソース・ドメイン名をクリックすれば、前の手順で指定した [カテゴリ・フィールド][トレーニング・セット]、または [テスト・セット] を変更することができます。ボタン・バーの [ギア] アイコンをクリックすれば、追加の高度制御がいくつか表示されます。

中央パネル ([選択された用語]) では、モデルの一部として選択済みの用語のツリー表示が現れます。左側のパネル ([用語の追加]) では、モデルに用語を追加することができます。

用語選択

以下に、用語ディクショナリにエンティティを追加するための最も一般的な方法を示します。

  • [エンティティ] タブ: 表示されるボックスに部分文字列を入力します。その部分文字列を含むすべてのエンティティが頻度と分散カウントを伴ってリストされます。

  • [上位] タブ: ドロップダウン・リストから [メトリック] (BM25 または TFIDF) を選択します。そのメトリックに従った上位エンティティが算出スコアを伴ってリストされます。

チェック・ボックスを使用して、個々のエンティティを用語として選択することができます。またはリストの下部にスクロールして、リスト化されたエンティティの現在ページに対して [すべて選択] をクリックすることもできます。必要に応じて、他のページに進むこともできます。エンティティを選択したら、[用語の追加] リストの上部までスクロールで戻り、[追加] ボタンをクリックします。これにより、選択したエンティティが中央パネルの [選択された用語] リストに追加されます。(重複用語を選択した場合、情報メッセージが表示されることがあります。)

高度用語選択 (オプション)

[追加] ボタンにより、複合用語を作成することができます。複合用語では、相似した複数のエンティティはすべて、同一の単一用語に解決されます。複合用語を定義することは、テキスト分類子のさらなる堅牢化と一般化する上において、およびトレーニング・セットの特定エンティティに対する “適合性” を低下する上において役立ちます。また、1 つの用語を別の用語の上にドラッグ・アンド・ドロップすることで、[選択された用語] リストに複合用語を作成することもできます。

既定では、選択した複数単語エンティティはすべて、同時出現として用語ディクショナリに追加されます。エンティティ内の単語はすべて、テキストで指定順序で出現して一致条件を満たす必要があります。ただし、代わりに個々のエンティティを部分一致エンティティとして指定することもできます。複数単語エンティティを追加する場合、[ギア] アイコンをクリックして、[カウント] ドロップダウン・ボックスを表示します。部分一致カウントを選択します。通常の複数単語エンティティを部分一致用語として定義することは、テキスト分類子のさらなる堅牢化と一般化する上において、およびトレーニング・セットの特定エンティティに対する “適合性” を低下する上においてに役立ちます。

[CRC] タブまたは [同時出現] タブを使用して、これらのエンティティを用語ディクショナリに追加することができます。表示されるボックスにエンティティを入力してから、[Enter] を押します。[用語の追加] リストに上位の CRC と同時出現が降順で表示されます。(同時出現とは、同一文における 2 つのコンセプト・エンティティの出現 (順不同) のことです。)通常、ほとんどの CRC と同時出現はきわめて特殊であるため、用語ディクショナリには追加しません。ただし、最も一般的な CRC または同時出現を用語ディクショナリに追加する場合もあります。

中央パネルの [選択された用語] リストから用語を削除することができます。これには、個々の用語 (または複合用語内のエンティティ) をクリックしてから、[削除] ボタンをクリックします。

保存

[モデルのプロパティ] および [選択された用語] リストが完成したら、[保存] ボタン (または [名前を付けて保存] ボタン) をクリックします。これにより、テキスト分類子が構築されます。

テキスト分類子の最適化

テキスト分類子の保存後には、オプティマイザを使用して、自動的に用語ディクショナリを最適化することができます。オプティマイザは追加候補用語のリストを取得して、各用語のテストを行い、テキスト分類子の精度に最高の影響度を備えた用語を加えます。

[最適化] ボタンをクリックします。これにより、[用語選択の最適化] ポップアップ・ウィンドウが表示されます。ドロップダウン・リストから、[関連メトリック] (BM25、TFIDF、または優位性) を選択します。該当のメトリックを使用し、候補用語の数を指定してから、[ロード] をクリックします。右側のパネルに [テスト用の候補用語] が一覧表示されます。[次へ] をクリックします。

これにより、既定値で [設定] パネルが表示されます。これらの既定値を受け入れて、[開始] をクリックできます。これにより、オプティマイザが実行され、用語の追加と削除が行われます。最適化プロセスが完了したら、[用語選択の最適化] ポップアップ・ウィンドウを閉じることができます。中央パネルの [選択された用語] リストが変化していることに注意してください。[保存] ボタンをクリックして、用語ディクショナリへのこれらの追加を保存します。

オプティマイザは異なる設定にて複数回実行することができます。各最適化の後には、テキスト分類子をテストすることができます。これは、以下のセクションで説明します。

データのテスト・セットに対するテキスト分類子のテスト

[テスト] ボタンをクリックします。これにより、新しいブラウザ・タブに [モデル・テスタ] が表示されます。[モデル・テスタ] により、テスト・データに対してテキスト分類子をテストすることができます。テスト後、[モデル・ビルダ] ブラウザ・タブに戻り、手動で [用語の追加] を使用するかオプティマイザを実行 (あるいは再実行) して、用語の追加や削除ができます。

[モデル・テスタ] では、以下の 2 通りのテキスト分類子テスト方法が用意されています。

  • [ドメイン] タブ: [ドメイン][カテゴリ・フィールド]、および [テスト・フィルタ][モデル・ビルダ] より値を取得する必要があります。[モデル・テスタ] にて、[実行] ボタンをクリックします。これにより、全体のテスト結果および各カテゴリの詳細テスト結果が表示されます。

  • [SQL] タブ: SQL クエリを指定すれば、データ・ソースの SQL セクションのテスト・データを提供することができます。以下の例に示すように、_Text と _Category の列エイリアスを使用して、ソース・テキストとメタデータ・カテゴリの列を指定します。

    SELECT E.ID,A.AircraftCategory AS _Category,E.Type,E.NarrativeFull AS _Text 
    FROM Aviation.Aircraft AS A,Aviation.Event AS E WHERE A.Event=E.ID

    次に、[テスト] をクリックします。これにより、テキスト分類子によって決定したカテゴリと実際のカテゴリ値が比較されます。ここでは、全体のテスト結果および各カテゴリの詳細が表示されます。

未分類データに対するテキスト分類子のテスト

テキスト文字列についてテキスト分類子を使用すれば、その文字列がどの程度カテゴリを導き出すかテストすることができます。[テスト] ボタンを選択します。これにより、[テキスト入力] ウィンドウが表示されます。テキスト文字列を指定してから、[分類] を押します。

  • [テキスト] タブでは、用語ディクショナリの用語をハイライトした形でテキストが表示されます。

  • [カテゴリ] タブでは、各カテゴリのスコア・バーが表示されます (緑は「正」、茶は「誤」を表す)。

  • [トレース情報] タブでは、入力テキストにある各用語に対する確率バーが表示されます。カテゴリのドロップダウン・リストに対してウェイトを使用すれば、すべてのカテゴリ (既定) または個々のカテゴリの各用語に対して、確率を求めることができます。

Th

テキスト分類子の使用

精度の高いテキスト分類子を構築したら、カテゴリ・ラベルが未割り当てのソース・テキストに適用してみます。%iKnow.Classification.ClassifierOpens in a new tab のメソッドを使用すれば、テキスト分類子を使って、任意単位のテキストのカテゴリを予測することができます。

テキスト分類子を作成するには、実行したいテキスト分類子を表す %iKnow.Classification.ClassifierOpens in a new tab のサブクラスを最初にインスタンス化する必要があります。作成後は、テキスト分類子が完全に移植可能になり、トレーニング・セットとテスト・セットのデータを含むドメインで、このテキスト分類子クラスを独立して使用できます。

  • iKnow ソース・テキストに対して、%Categorize() を使用します。分類するソース・テキストが iKnow ドメインでインデックス化されている場合、%Categorize()Opens in a new tab を使用すれば、そのカテゴリと照合できます。これにより、スコアによる降順にて、各カテゴリについての一致スコアが返ります。

       SET tClassifier = ##class(User.MyClassifier).%New("iKnow","MyDomain")
       WRITE tClassifier.%Categorize(.categories,srcId)
       ZWRITE categories
  • 文字列として指定したテキストに対して、%CategorizeText() を使用します。分類するソース・テキストが文字列である場合、%CategorizeText()Opens in a new tab を使用すれば、入力文字列をそのカテゴリと照合することができます。これにより、スコアによる降順にて、各カテゴリについての一致スコアが返ります。

       SET tClassifier = ##class(User.MyClassifier).%New()
       WRITE tClassifier.%CategorizeText(.categories,inputstring)
       ZWRITE categories

ZWRITE カテゴリでは、以下のような一致スコア・データを返します。

categories=4
categories(1)=$lb("AIRPLANE",.4314703807485703701)
categories(2)=$lb("HELICOPTER",.04128622469233822948)
categories(3)=$lb("GLIDER",.0228365968611826442)
categories(4)=$lb("GYROCRAFT",.005880588058805880587)

SQL においては、以下のように、メソッド・ストアド・プロシージャを使用して、テキスト文字列に対してテキスト分類子を実行することができます。

SELECT User.MyClassifier_sys_CategorizeSQL('input string') AS CategoryLabel

これにより、カテゴリ・ラベルが返ります。

以下の埋め込み SQL の例では、Sample.MyTC テキスト分類子を使用して、Aviation.Event の最初の 25 個のレコードについてカテゴリを判定します。

  ZNSPACE "Samples"
  FOR i=1:1:25 {
     SET rec=i
     &sql(SELECT %ID,NarrativeFull INTO :id,:inputstring FROM Aviation.Event WHERE %ID=:rec)
         WRITE "Record ",id
     &sql(SELECT Sample.MyTC_sys_CategorizeSQL(:inputstring) INTO :CategoryLabel)
        WRITE " assigned category: ",CategoryLabel,!
  }

テキストが分類されたら、%iKnow.Filters.SimpleMetadataFilterOpens in a new tab クラスの使用により、この分類を使用してテキストをフィルタ処理できます。詳細は、"ユーザ定義メタデータによるフィルタ処理" を参照してください。

FeedbackOpens in a new tab