.NET 用 Azure Cognitive Services Text Analytics クライアント ライブラリ - バージョン 5.3.0

Text Analyticsは、テキストを理解して分析するための自然言語処理 (NLP) 機能を提供するクラウドベースのサービスである Azure Cognitive Service for Language の一部です。 このクライアント ライブラリには、次の機能があります。

  • 言語検出
  • センチメント分析
  • キー フレーズの抽出
  • 固有表現認識 (NER)
  • 個人を特定できる情報 (PII) エンティティの認識
  • エンティティ リンク設定
  • Text Analytics for Health
  • カスタムの名前付きエンティティ認識 (Custom NER)
  • カスタム テキスト分類
  • 抽出テキストの要約
  • 抽象テキストの要約

ソースコード | パッケージ (NuGet) | API リファレンス ドキュメント | 製品ドキュメント | サンプル

作業の開始

パッケージをインストールする

NuGet を使用して .NET 用 Azure Text Analytics クライアント ライブラリをインストールします。

dotnet add package Azure.AI.TextAnalytics

SDK のバージョンとサービスのサポートされる API バージョンの関係を次の表に示します。

5.2.0は、Text Analytics クライアント ライブラリにある既存のテキスト分析機能と自然言語処理機能を含む Azure Cognitive Service for Language API を対象とするクライアント ライブラリの最初の安定バージョンであることに注意してください。 さらに、サービス API はセマンティックから日付ベースのバージョン管理に変更されました。

SDK バージョン サポートされている API バージョンのサービス
5.3.X 3.0、3.1、2022-05-01、2023-04-01 (既定値)
5.2.X 3.0、3.1、2022-05-01 (既定値)
5.1.X 3.0、3.1 (既定値)
5.0.X 3.0
1.0.X 3.0

前提条件

Cognitive Services リソースまたは言語サービス リソースを作成する

Azure Cognitive Service for Language では、 マルチサービス アクセスとシングルサービス アクセスの両方がサポートされています。 1 つのエンドポイントと API キーで複数のコグニティブ サービスにアクセスする予定の場合は、Cognitive Services リソースを作成します。 言語サービスの機能にのみアクセスするには、代わりに言語サービス リソースを作成します。

Azure portalを使用してリソースを作成することも、このドキュメントの手順に従って Azure CLI を使用してリソースを作成することもできます。

クライアントを認証する

クライアント ライブラリを使用したサービスとの対話は、 まず TextAnalyticsClient クラスのインスタンスの作成から始まります。 エンドポイントAPI キー、またはTokenCredentialクライアント オブジェクトをインスタンス化する必要があります。 コグニティブ サービスを使用した認証の詳細については、「 Azure Cognitive Services への要求を認証する」を参照してください。

API キーを取得する

と はendpointAPI keyAzure Portal の Cognitive Services リソースまたは言語サービス リソース情報から取得できます。

または、次の Azure CLI スニペットを使用して、言語サービス リソースから API キーを取得します。

az cognitiveservices account keys list --resource-group <your-resource-group-name> --name <your-resource-name>

API キー資格情報を TextAnalyticsClient 使用して を作成する

API キーの値を取得したら、 を作成します AzureKeyCredential。 これにより、新しいクライアントを作成せずに API キーを更新できます。

エンドポイントと の値を AzureKeyCredential使用すると、 TextAnalyticsClient を作成できます。

Uri endpoint = new("<endpoint>");
AzureKeyCredential credential = new("<apiKey>");
TextAnalyticsClient client = new(endpoint, credential);

Azure Active Directory 資格情報を使用して を TextAnalyticsClient 作成する

クライアント API キー認証は、この入門ガイドのほとんどの例で使用されますが、 Azure Id ライブラリを使用して Azure Active Directory で認証することもできます。 リージョン エンドポイントでは AAD 認証がサポートされないことに注意してください。 この種類の認証を使用するために、リソースのカスタム サブドメインを作成します。

次に示す DefaultAzureCredential プロバイダー、または Azure SDK で提供されているその他の資格情報プロバイダーを使用するには、Azure.Identity パッケージをインストールしてください。

dotnet add package Azure.Identity

また、新しい AAD アプリケーションを登録し、サービス プリンシパルにロールを割り当てて"Cognitive Services User"言語サービスへのアクセス権を付与する必要もあります。

AAD アプリケーションのクライアント ID、テナント ID、クライアント シークレットの値を環境変数として設定します(AZURE_CLIENT_ID、AZURE_TENANT_ID、AZURE_CLIENT_SECRET)。

Uri endpoint = new("<endpoint>");
TextAnalyticsClient client = new(endpoint, new DefaultAzureCredential());

主要な概念

TextAnalyticsClient

TextAnalyticsClientは、Text Analytics クライアント ライブラリを使用する開発者のための主要なインターフェイスです。 言語検出やキー フレーズ抽出など、テキスト分析の特定の用途にアクセスするための同期操作と非同期操作の両方が提供されます。

入力

ドキュメントは、言語サービスの予測モデルによって分析される 1 つの入力単位です。 の操作では TextAnalyticsClient 、1 つのドキュメントまたはドキュメントのコレクションをバッチとして分析できます。 ドキュメントの長さの制限、最大バッチ サイズ、およびサポートされているテキスト エンコードについては、 こちらを参照してください

複数のドキュメントに対する操作

サポートされている各操作に対して、TextAnalyticsClientドキュメントのバッチを文字列として受け入れるメソッド、または オブジェクトまたは DetectLanguageInput オブジェクトのTextDocumentInputバッチを提供します。 このメソッドを使用すると、呼び出し元は各ドキュメントに一意の ID を付与したり、バッチ内のドキュメントが異なる言語で書き込まれたり、ドキュメントの言語に関する国ヒントを提供したりできます。

メモ: 運用環境で作業する場合は、複数のドキュメントを含む 1 つの要求を送信できるため、バッチ方式を使用することをお勧めします。 これは、各ドキュメントごとに要求を送信するよりもパフォーマンスが高くなります。

戻り値

などのAnalyzeSentimentResult戻り値は、1 つのドキュメントに関する予測または予測を含むText Analytics操作の結果です。 操作の戻り値には、必要に応じて、ドキュメントとその処理方法に関する情報を含めることもできます。

戻り値コレクション

Return 値のコレクション ( など AnalyzeSentimentResultCollection) は操作結果のコレクションであり、それぞれが入力バッチで指定されたドキュメントのいずれかに対応します。 ドキュメントとその結果は、入力コレクションと結果コレクション内で同じインデックスを持つことになります。 戻り値には、指定されたドキュメントに対して実行された操作が成功したか失敗したかを識別できるプロパティも含 HasError まれています。 必要に応じて、ドキュメント バッチとその処理方法に関する情報を含めることができます。

Long-Running操作

実行に時間がかかる大規模なドキュメントの場合、これらの操作は 実行時間の長い操作として実装されます。 実行時間の長い操作は、操作を開始するためにサービスに送信された最初の要求で構成され、その後、間隔を指定してサービスをポーリングして、操作が完了したか失敗したか、成功したかどうかを判断して結果を取得します。

Azure SDK での実行時間の長い操作の場合、クライアントは または を Start<operation-name> 返す Operation<T> メソッドを PageableOperation<T>公開します。 拡張メソッド WaitForCompletionAsync() を使用すると、操作が完了するまで待機し、その結果を取得できます。 以下では、実行時間の長い操作の使用を示すサンプル コード スニペットが提供されています。

スレッド セーフ

すべてのクライアント インスタンス メソッドがスレッド セーフであり、相互に独立していることを保証します (ガイドライン)。 これにより、クライアント インスタンスの再利用に関する推奨事項は、スレッド間でも常に安全になります。

その他の概念

クライアント オプション | 応答 | へのアクセスエラーの | 処理診断 | あざける | クライアントの有効期間

次のセクションでは、上記で作成したclient使用するいくつかのコード スニペットを示し、このクライアント ライブラリに存在するメイン機能について説明します。 以下のスニペットのほとんどは同期サービス呼び出しを使用していますが、パッケージでは同期 API と非同期 API の両方がサポートされていること Azure.AI.TextAnalytics に注意してください。

同期の例

非同期の例

言語の検出

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチが書き込まれる言語を決定します。

string document =
    "Este documento está escrito en un lenguaje diferente al inglés. Su objectivo es demostrar cómo"
    + " invocar el método de Detección de Lenguaje del servicio de Text Analytics en Microsoft Azure."
    + " También muestra cómo acceder a la información retornada por el servicio. Esta funcionalidad es"
    + " útil para los sistemas de contenido que recopilan texto arbitrario, donde el lenguaje no se conoce"
    + " de antemano. Puede usarse para detectar una amplia gama de lenguajes, variantes, dialectos y"
    + " algunos idiomas regionales o culturales.";

try
{
    Response<DetectedLanguage> response = client.DetectLanguage(document);
    DetectedLanguage language = response.Value;

    Console.WriteLine($"Detected language is {language.Name} with a confidence score of {language.ConfidenceScore}.");
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

運用環境の推奨オプション DetectLanguageBatch の使用に関するサンプルについては 、こちらを参照してください

言語検出の概念的な説明については、サービス ドキュメントを参照してください。

感情の分析

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチに含まれる肯定的、否定的、中立的、または混合されたセンチメントを決定します。

string document =
    "I had the best day of my life. I decided to go sky-diving and it made me appreciate my whole life so"
    + "much more. I developed a deep-connection with my instructor as well, and I feel as if I've made a"
    + "life-long friend in her.";

try
{
    Response<DocumentSentiment> response = client.AnalyzeSentiment(document);
    DocumentSentiment docSentiment = response.Value;

    Console.WriteLine($"Document sentiment is {docSentiment.Sentiment} with: ");
    Console.WriteLine($"  Positive confidence score: {docSentiment.ConfidenceScores.Positive}");
    Console.WriteLine($"  Neutral confidence score: {docSentiment.ConfidenceScores.Neutral}");
    Console.WriteLine($"  Negative confidence score: {docSentiment.ConfidenceScores.Negative}");
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

運用環境の推奨オプション AnalyzeSentimentBatch の使用に関するサンプルについては 、こちらを参照してください

製品/サービスのターゲット (自然言語処理 (NLP) のアスペクトベースの感情分析とも呼ばれます) に関連する意見に関するより詳細な情報を取得するには、オピニオン マイニングを使用した感情分析のサンプル を参照してください

感情分析の概念的な説明については、サービスのドキュメントを参照してください。

キー フレーズを抽出する

モデルを実行して、渡されたドキュメントまたはドキュメントのバッチで見つかった重要なフレーズのコレクションを識別します。

string document =
    "My cat might need to see a veterinarian. It has been sneezing more than normal, and although my"
    + " little sister thinks it is funny, I am worried it has the cold that I got last week. We are going"
    + " to call tomorrow and try to schedule an appointment for this week. Hopefully it will be covered by"
    + " the cat's insurance. It might be good to not let it sleep in my room for a while.";

try
{
    Response<KeyPhraseCollection> response = client.ExtractKeyPhrases(document);
    KeyPhraseCollection keyPhrases = response.Value;

    Console.WriteLine($"Extracted {keyPhrases.Count} key phrases:");
    foreach (string keyPhrase in keyPhrases)
    {
        Console.WriteLine($"  {keyPhrase}");
    }
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

運用環境の推奨オプション ExtractKeyPhrasesBatch の使用に関するサンプルについては 、こちらを参照してください

キー フレーズ抽出の概念的な説明については、サービスドキュメントを参照してください。

名前付きエンティティを認識する

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチ内の名前付きエンティティのコレクションを識別し、それらのエンティティを人物、場所、organizationなどのカテゴリに分類します。 使用可能なカテゴリの詳細については、「Text Analytics名前付きエンティティ カテゴリ」を参照してください。

string document =
    "We love this trail and make the trip every year. The views are breathtaking and well worth the hike!"
    + " Yesterday was foggy though, so we missed the spectacular views. We tried again today and it was"
    + " amazing. Everyone in my family liked the trail although it was too challenging for the less"
    + " athletic among us. Not necessarily recommended for small children. A hotel close to the trail"
    + " offers services for childcare in case you want that.";

try
{
    Response<CategorizedEntityCollection> response = client.RecognizeEntities(document);
    CategorizedEntityCollection entitiesInDocument = response.Value;

    Console.WriteLine($"Recognized {entitiesInDocument.Count} entities:");
    foreach (CategorizedEntity entity in entitiesInDocument)
    {
        Console.WriteLine($"  Text: {entity.Text}");
        Console.WriteLine($"  Offset: {entity.Offset}");
        Console.WriteLine($"  Length: {entity.Length}");
        Console.WriteLine($"  Category: {entity.Category}");
        if (!string.IsNullOrEmpty(entity.SubCategory))
            Console.WriteLine($"  SubCategory: {entity.SubCategory}");
        Console.WriteLine($"  Confidence score: {entity.ConfidenceScore}");
        Console.WriteLine();
    }
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

運用環境の推奨オプション RecognizeEntitiesBatch の使用に関するサンプルについては 、こちらを参照してください

名前付きエンティティ認識の概念については、サービス ドキュメントを参照してください。

PII エンティティを認識する

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチで見つかった個人を特定できる情報を含むエンティティのコレクションを特定し、それらのエンティティを米国の社会保障番号、運転免許証番号、クレジット カード番号などのカテゴリに分類します。

string document =
    "Parker Doe has repaid all of their loans as of 2020-04-25. Their SSN is 859-98-0987. To contact them,"
    + " use their phone number 800-102-1100. They are originally from Brazil and have document ID number"
    + " 998.214.865-68.";

try
{
    Response<PiiEntityCollection> response = client.RecognizePiiEntities(document);
    PiiEntityCollection entities = response.Value;

    Console.WriteLine($"Redacted Text: {entities.RedactedText}");
    Console.WriteLine();
    Console.WriteLine($"Recognized {entities.Count} PII entities:");
    foreach (PiiEntity entity in entities)
    {
        Console.WriteLine($"  Text: {entity.Text}");
        Console.WriteLine($"  Category: {entity.Category}");
        if (!string.IsNullOrEmpty(entity.SubCategory))
            Console.WriteLine($"  SubCategory: {entity.SubCategory}");
        Console.WriteLine($"  Confidence score: {entity.ConfidenceScore}");
        Console.WriteLine();
    }
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

運用環境の推奨オプション RecognizePiiEntitiesBatch の使用に関するサンプルについては 、こちらを参照してください

サポートされている PII エンティティの種類については、サービスのドキュメントを参照してください。

リンクされたエンティティを認識する

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチで見つかったエンティティのコレクションを識別し、既知のサポート情報内の対応するエントリにエンティティをリンクする情報を含めます。

string document =
    "Microsoft was founded by Bill Gates with some friends he met at Harvard. One of his friends, Steve"
    + " Ballmer, eventually became CEO after Bill Gates as well. Steve Ballmer eventually stepped down as"
    + " CEO of Microsoft, and was succeeded by Satya Nadella. Microsoft originally moved its headquarters"
    + " to Bellevue, Washington in Januaray 1979, but is now headquartered in Redmond.";

try
{
    Response<LinkedEntityCollection> response = client.RecognizeLinkedEntities(document);
    LinkedEntityCollection linkedEntities = response.Value;

    Console.WriteLine($"Recognized {linkedEntities.Count} entities:");
    foreach (LinkedEntity linkedEntity in linkedEntities)
    {
        Console.WriteLine($"  Name: {linkedEntity.Name}");
        Console.WriteLine($"  Language: {linkedEntity.Language}");
        Console.WriteLine($"  Data Source: {linkedEntity.DataSource}");
        Console.WriteLine($"  URL: {linkedEntity.Url}");
        Console.WriteLine($"  Entity Id in Data Source: {linkedEntity.DataSourceEntityId}");
        foreach (LinkedEntityMatch match in linkedEntity.Matches)
        {
            Console.WriteLine($"    Match Text: {match.Text}");
            Console.WriteLine($"    Offset: {match.Offset}");
            Console.WriteLine($"    Length: {match.Length}");
            Console.WriteLine($"    Confidence score: {match.ConfidenceScore}");
        }
        Console.WriteLine();
    }
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

運用環境の推奨オプション RecognizeLinkedEntitiesBatch の使用に関するサンプルについては 、こちらを参照してください

エンティティ リンクの概念的な説明については、サービス ドキュメントを参照してください。

言語を非同期的に検出する

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチが書き込まれる言語を決定します。

string document =
    "Este documento está escrito en un lenguaje diferente al inglés. Su objectivo es demostrar cómo"
    + " invocar el método de Detección de Lenguaje del servicio de Text Analytics en Microsoft Azure."
    + " También muestra cómo acceder a la información retornada por el servicio. Esta funcionalidad es"
    + " útil para los sistemas de contenido que recopilan texto arbitrario, donde el lenguaje no se conoce"
    + " de antemano. Puede usarse para detectar una amplia gama de lenguajes, variantes, dialectos y"
    + " algunos idiomas regionales o culturales.";

try
{
    Response<DetectedLanguage> response = await client.DetectLanguageAsync(document);
    DetectedLanguage language = response.Value;

    Console.WriteLine($"Detected language is {language.Name} with a confidence score of {language.ConfidenceScore}.");
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

名前付きエンティティを非同期的に認識する

予測モデルを実行して、渡されたドキュメントまたはドキュメントのバッチ内の名前付きエンティティのコレクションを識別し、それらのエンティティを人物、場所、organizationなどのカテゴリに分類します。 使用可能なカテゴリの詳細については、「Text Analytics名前付きエンティティ カテゴリ」を参照してください。

string document =
    "We love this trail and make the trip every year. The views are breathtaking and well worth the hike!"
    + " Yesterday was foggy though, so we missed the spectacular views. We tried again today and it was"
    + " amazing. Everyone in my family liked the trail although it was too challenging for the less"
    + " athletic among us. Not necessarily recommended for small children. A hotel close to the trail"
    + " offers services for childcare in case you want that.";

try
{
    Response<CategorizedEntityCollection> response = await client.RecognizeEntitiesAsync(document);
    CategorizedEntityCollection entitiesInDocument = response.Value;

    Console.WriteLine($"Recognized {entitiesInDocument.Count} entities:");
    foreach (CategorizedEntity entity in entitiesInDocument)
    {
        Console.WriteLine($"  Text: {entity.Text}");
        Console.WriteLine($"  Offset: {entity.Offset}");
        Console.WriteLine($"  Length: {entity.Length}");
        Console.WriteLine($"  Category: {entity.Category}");
        if (!string.IsNullOrEmpty(entity.SubCategory))
            Console.WriteLine($"  SubCategory: {entity.SubCategory}");
        Console.WriteLine($"  Confidence score: {entity.ConfidenceScore}");
        Console.WriteLine();
    }
}
catch (RequestFailedException exception)
{
    Console.WriteLine($"Error Code: {exception.ErrorCode}");
    Console.WriteLine($"Message: {exception.Message}");
}

医療エンティティを非同期的に分析する

Text Analytics for Health は、医師のメモ、退院要約、臨床ドキュメント、電子健康記録などの非構造化テキストから関連する医療情報を抽出してラベル付けする、コンテナー化されたサービスです。 詳細については、「方法: Text Analyticsを正常性に使用する」を参照してください。

string documentA =
    "RECORD #333582770390100 | MH | 85986313 | | 054351 | 2/14/2001 12:00:00 AM |"
    + " CORONARY ARTERY DISEASE | Signed | DIS |"
    + Environment.NewLine
    + " Admission Date: 5/22/2001 Report Status: Signed Discharge Date: 4/24/2001"
    + " ADMISSION DIAGNOSIS: CORONARY ARTERY DISEASE."
    + Environment.NewLine
    + " HISTORY OF PRESENT ILLNESS: The patient is a 54-year-old gentleman with a history of progressive"
    + " angina over the past several months. The patient had a cardiac catheterization in July of this"
    + " year revealing total occlusion of the RCA and 50% left main disease, with a strong family history"
    + " of coronary artery disease with a brother dying at the age of 52 from a myocardial infarction and"
    + " another brother who is status post coronary artery bypass grafting. The patient had a stress"
    + " echocardiogram done on July, 2001, which showed no wall motion abnormalities, but this was a"
    + " difficult study due to body habitus. The patient went for six minutes with minimal ST depressions"
    + " in the anterior lateral leads, thought due to fatigue and wrist pain, his anginal equivalent. Due"
    + " to the patient'sincreased symptoms and family history and history left main disease with total"
    + " occasional of his RCA was referred for revascularization with open heart surgery.";

string documentB = "Prescribed 100mg ibuprofen, taken twice daily.";

// Prepare the input of the text analysis operation. You can add multiple documents to this list and
// perform the same operation on all of them simultaneously.
List<string> batchedDocuments = new()
{
    documentA,
    documentB
};

// Perform the text analysis operation.
AnalyzeHealthcareEntitiesOperation operation = await client.AnalyzeHealthcareEntitiesAsync(WaitUntil.Completed, batchedDocuments);

Console.WriteLine($"The operation has completed.");
Console.WriteLine();

// View the operation status.
Console.WriteLine($"Created On   : {operation.CreatedOn}");
Console.WriteLine($"Expires On   : {operation.ExpiresOn}");
Console.WriteLine($"Id           : {operation.Id}");
Console.WriteLine($"Status       : {operation.Status}");
Console.WriteLine($"Last Modified: {operation.LastModified}");
Console.WriteLine();

// View the operation results.
await foreach (AnalyzeHealthcareEntitiesResultCollection documentsInPage in operation.Value)
{
    Console.WriteLine($"Analyze Healthcare Entities, model version: \"{documentsInPage.ModelVersion}\"");
    Console.WriteLine();

    foreach (AnalyzeHealthcareEntitiesResult documentResult in documentsInPage)
    {
        if (documentResult.HasError)
        {
            Console.WriteLine($"  Error!");
            Console.WriteLine($"  Document error code: {documentResult.Error.ErrorCode}");
            Console.WriteLine($"  Message: {documentResult.Error.Message}");
            continue;
        }

        Console.WriteLine($"  Recognized the following {documentResult.Entities.Count} healthcare entities:");
        Console.WriteLine();

        // View the healthcare entities that were recognized.
        foreach (HealthcareEntity entity in documentResult.Entities)
        {
            Console.WriteLine($"  Entity: {entity.Text}");
            Console.WriteLine($"  Category: {entity.Category}");
            Console.WriteLine($"  Offset: {entity.Offset}");
            Console.WriteLine($"  Length: {entity.Length}");
            Console.WriteLine($"  NormalizedText: {entity.NormalizedText}");
            Console.WriteLine($"  Links:");

            // View the entity data sources.
            foreach (EntityDataSource entityDataSource in entity.DataSources)
            {
                Console.WriteLine($"    Entity ID in Data Source: {entityDataSource.EntityId}");
                Console.WriteLine($"    DataSource: {entityDataSource.Name}");
            }

            // View the entity assertions.
            if (entity.Assertion is not null)
            {
                Console.WriteLine($"  Assertions:");

                if (entity.Assertion?.Association is not null)
                {
                    Console.WriteLine($"    Association: {entity.Assertion?.Association}");
                }

                if (entity.Assertion?.Certainty is not null)
                {
                    Console.WriteLine($"    Certainty: {entity.Assertion?.Certainty}");
                }

                if (entity.Assertion?.Conditionality is not null)
                {
                    Console.WriteLine($"    Conditionality: {entity.Assertion?.Conditionality}");
                }
            }
        }

        Console.WriteLine($"  We found {documentResult.EntityRelations.Count} relations in the current document:");
        Console.WriteLine();

        // View the healthcare entity relations that were recognized.
        foreach (HealthcareEntityRelation relation in documentResult.EntityRelations)
        {
            Console.WriteLine($"    Relation: {relation.RelationType}");
            if (relation.ConfidenceScore is not null)
            {
                Console.WriteLine($"    ConfidenceScore: {relation.ConfidenceScore}");
            }
            Console.WriteLine($"    For this relation there are {relation.Roles.Count} roles");

            // View the relation roles.
            foreach (HealthcareEntityRelationRole role in relation.Roles)
            {
                Console.WriteLine($"      Role Name: {role.Name}");

                Console.WriteLine($"      Associated Entity Text: {role.Entity.Text}");
                Console.WriteLine($"      Associated Entity Category: {role.Entity.Category}");
                Console.WriteLine();
            }

            Console.WriteLine();
        }

        Console.WriteLine();
    }
}

複数のアクションを非同期に実行する

この機能を使用すると、1 つまたは複数のドキュメントで複数のアクションを実行できます。 "アクション" に含まれている項目:

  • 名前付きエンティティ認識
  • PII エンティティの認識
  • リンクされたエンティティの認識
  • キー フレーズ抽出
  • 感情分析
  • 医療エンティティの認識 ( こちらのサンプルを参照)
  • カスタムの名前付きエンティティ認識 ( こちらのサンプルを参照)
  • カスタムの単一ラベル分類 ( こちらのサンプルを参照)
  • カスタムマルチラベル分類 ( こちらのサンプルを参照)
    string documentA =
        "We love this trail and make the trip every year. The views are breathtaking and well worth the hike!"
        + " Yesterday was foggy though, so we missed the spectacular views. We tried again today and it was"
        + " amazing. Everyone in my family liked the trail although it was too challenging for the less"
        + " athletic among us.";

    string documentB =
        "Last week we stayed at Hotel Foo to celebrate our anniversary. The staff knew about our anniversary"
        + " so they helped me organize a little surprise for my partner. The room was clean and with the"
        + " decoration I requested. It was perfect!";

    // Prepare the input of the text analysis operation. You can add multiple documents to this list and
    // perform the same operation on all of them simultaneously.
    List<string> batchedDocuments = new()
    {
        documentA,
        documentB
    };

    TextAnalyticsActions actions = new()
    {
        ExtractKeyPhrasesActions = new List<ExtractKeyPhrasesAction>() { new ExtractKeyPhrasesAction() { ActionName = "ExtractKeyPhrasesSample" } },
        RecognizeEntitiesActions = new List<RecognizeEntitiesAction>() { new RecognizeEntitiesAction() { ActionName = "RecognizeEntitiesSample" } },
        DisplayName = "AnalyzeOperationSample"
    };

    // Perform the text analysis operation.
    AnalyzeActionsOperation operation = await client.AnalyzeActionsAsync(WaitUntil.Completed, batchedDocuments, actions);

    // View the operation status.
    Console.WriteLine($"Created On   : {operation.CreatedOn}");
    Console.WriteLine($"Expires On   : {operation.ExpiresOn}");
    Console.WriteLine($"Id           : {operation.Id}");
    Console.WriteLine($"Status       : {operation.Status}");
    Console.WriteLine($"Last Modified: {operation.LastModified}");
    Console.WriteLine();

    if (!string.IsNullOrEmpty(operation.DisplayName))
    {
        Console.WriteLine($"Display name: {operation.DisplayName}");
        Console.WriteLine();
    }

    Console.WriteLine($"Total actions: {operation.ActionsTotal}");
    Console.WriteLine($"  Succeeded actions: {operation.ActionsSucceeded}");
    Console.WriteLine($"  Failed actions: {operation.ActionsFailed}");
    Console.WriteLine($"  In progress actions: {operation.ActionsInProgress}");
    Console.WriteLine();

    await foreach (AnalyzeActionsResult documentsInPage in operation.Value)
    {
        IReadOnlyCollection<ExtractKeyPhrasesActionResult> keyPhrasesResults = documentsInPage.ExtractKeyPhrasesResults;
        IReadOnlyCollection<RecognizeEntitiesActionResult> entitiesResults = documentsInPage.RecognizeEntitiesResults;

        Console.WriteLine("Recognized Entities");
        int docNumber = 1;
        foreach (RecognizeEntitiesActionResult entitiesActionResults in entitiesResults)
        {
            Console.WriteLine($" Action name: {entitiesActionResults.ActionName}");
            Console.WriteLine();
            foreach (RecognizeEntitiesResult documentResult in entitiesActionResults.DocumentsResults)
            {
                Console.WriteLine($" Document #{docNumber++}");
                Console.WriteLine($"  Recognized {documentResult.Entities.Count} entities:");

                foreach (CategorizedEntity entity in documentResult.Entities)
                {
                    Console.WriteLine();
                    Console.WriteLine($"    Entity: {entity.Text}");
                    Console.WriteLine($"    Category: {entity.Category}");
                    Console.WriteLine($"    Offset: {entity.Offset}");
                    Console.WriteLine($"    Length: {entity.Length}");
                    Console.WriteLine($"    ConfidenceScore: {entity.ConfidenceScore}");
                    Console.WriteLine($"    SubCategory: {entity.SubCategory}");
                }
                Console.WriteLine();
            }
        }

        Console.WriteLine("Extracted Key Phrases");
        docNumber = 1;
        foreach (ExtractKeyPhrasesActionResult keyPhrasesActionResult in keyPhrasesResults)
        {
            Console.WriteLine($" Action name: {keyPhrasesActionResult.ActionName}");
            Console.WriteLine();
            foreach (ExtractKeyPhrasesResult documentResults in keyPhrasesActionResult.DocumentsResults)
            {
                Console.WriteLine($" Document #{docNumber++}");
                Console.WriteLine($"  Recognized the following {documentResults.KeyPhrases.Count} Keyphrases:");

                foreach (string keyphrase in documentResults.KeyPhrases)
                {
                    Console.WriteLine($"    {keyphrase}");
                }
                Console.WriteLine();
            }
        }
    }
}

トラブルシューティング

全般

.NET Text Analytics SDK を使用して Cognitive Services for Language と対話すると、言語サービスによって返されるエラーは、REST API 要求に返されるのと同じ HTTP 状態コードに対応します。

たとえば、重複するドキュメント ID を含むテキスト ドキュメント入力のバッチを送信すると、 400 "Bad Request" を示すエラーが返されます。

try
{
    DetectedLanguage result = client.DetectLanguage(document);
}
catch (RequestFailedException e)
{
    Console.WriteLine(e.ToString());
}

操作のクライアント要求 ID など、追加情報がログに記録されていることがわかります。

Message:
    Azure.RequestFailedException:
    Status: 400 (Bad Request)

Content:
    {"error":{"code":"InvalidRequest","innerError":{"code":"InvalidDocument","message":"Request contains duplicated Ids. Make sure each document has a unique Id."},"message":"Invalid document in request."}}

Headers:
    Transfer-Encoding: chunked
    x-aml-ta-request-id: 146ca04a-af54-43d4-9872-01a004bee5f8
    X-Content-Type-Options: nosniff
    x-envoy-upstream-service-time: 6
    apim-request-id: c650acda-2b59-4ff7-b96a-e316442ea01b
    Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
    Date: Wed, 18 Dec 2019 16:24:52 GMT
    Content-Type: application/json; charset=utf-8

コンソール ログの設定

ログを表示する最も簡単な方法は、コンソール ログを有効にすることです。 コンソールにメッセージを出力する Azure SDK ログ リスナーを作成するには、AzureEventSourceListener.CreateConsoleLogger メソッドを使用します。

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

その他のログメカニズムの詳細については、 こちらを参照してください

次のステップ

このクライアント ライブラリの使用方法を示すサンプルは、この GitHub リポジトリで入手できます。 サンプルは、メイン機能領域ごとに提供され、領域ごとに、1 つのドキュメントと、同期モードと非同期モードの両方のドキュメントのコレクションを分析するためのサンプルが提供されます。

高度なサンプル

共同作成

このライブラリのビルド、テスト、および投稿の詳細については、 CONTRIBUTING.md を参照してください。

このプロジェクトでは、共同作成と提案を歓迎しています。 ほとんどの共同作成では、共同作成者使用許諾契約書 (CLA) にご同意いただき、ご自身の共同作成内容を使用する権利を Microsoft に供与する権利をお持ちであり、かつ実際に供与することを宣言していただく必要があります。 詳細については、「 cla.microsoft.com」を参照してください。

pull request を送信すると、CLA を提供して PR (ラベル、コメントなど) を適宜装飾する必要があるかどうかを CLA ボットが自動的に決定します。 ボットによって提供される手順にそのまま従ってください。 この操作は、Microsoft の CLA を使用するすべてのリポジトリについて、1 回だけ行う必要があります。

このプロジェクトでは、Microsoft オープン ソースの倫理規定を採用しています。 詳しくは、「Code of Conduct FAQ (倫理規定についてよくある質問)」を参照するか、opencode@microsoft.com 宛てに質問またはコメントをお送りください。

インプレッション数