Skip to content

Commit

Permalink
[TA] Analyze Healthcare entities updates (#18828)
Browse files Browse the repository at this point in the history
Include all updated changes to healthcare analysis endpoint based on the latest API design.
  • Loading branch information
mssfang authored Feb 5, 2021
1 parent 815526b commit b507bd6
Show file tree
Hide file tree
Showing 59 changed files with 2,004 additions and 2,450 deletions.
38 changes: 28 additions & 10 deletions sdk/textanalytics/azure-ai-textanalytics/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
# Release History
## 5.1.0-beta.4 (Unreleased)
### Breaking changes
#### Analysis healthcare entities
- Replace API
`PollerFlux<TextAnalyticsOperationResult, PagedFlux<HealthcareTaskResult>> beginAnalyzeHealthcare(Iterable<TextDocumentInput> documents, RecognizeHealthcareEntityOptions options)` to
`PollerFlux<AnalyzeHealthcareEntitiesOperationDetail, PagedFlux<AnalyzeHealthcareEntitiesResultCollection>> beginAnalyzeHealthcareEntities(Iterable<TextDocumentInput> documents, AnalyzeHealthcareEntitiesOptions options)`,
`SyncPoller<TextAnalyticsOperationResult, PagedIterable<HealthcareTaskResult>> beginAnalyzeHealthcare(Iterable<TextDocumentInput> documents, RecognizeHealthcareEntityOptions options, Context context)` to
`SyncPoller<AnalyzeHealthcareEntitiesOperationDetail, PagedIterable<AnalyzeHealthcareEntitiesResultCollection>> beginAnalyzeHealthcareEntities(Iterable<TextDocumentInput> documents, AnalyzeHealthcareEntitiesOptions options, Context context)`
- New overload APIs,
`PollerFlux<AnalyzeHealthcareEntitiesOperationDetail, PagedFlux<AnalyzeHealthcareEntitiesResultCollection>> beginAnalyzeHealthcareEntities(Iterable<String> documents, String language, AnalyzeHealthcareEntitiesOptions options)`,
`SyncPoller<AnalyzeHealthcareEntitiesOperationDetail, PagedIterable<AnalyzeHealthcareEntitiesResultCollection>> beginAnalyzeHealthcareEntities(Iterable<String> documents, String language, AnalyzeHealthcareEntitiesOptions options, Context context)`
- Added `AnalyzeHealthcareEntitiesResultCollection`, `AnalyzeHealthcareEntitiesResult`, `HealthcareEntityRelationType`
- Removed `HealthcareTaskResult`, `HealthcareEntityRelation`, `HealthcareEntityCollection`, `JobMetadata`, `JobState`
- Renamed
`HealthcareEntityLink` to `EntityDataSource`,
`RecognizeHealthcareEntityOptions` to `AnalyzeHealthcareEntitiesOptions`,
`RecognizeHealthcareEntitiesResult` to `AnalyzeHealthcareEntitiesResult`,
`RecognizeHealthcareEntitiesResultCollection` to `AnalyzeHealthcareEntitiesResultCollection`
`TextAnalyticsOperationResult` to `AnalyzeHealthcareEntitiesOperationDetail`

#### Analyze multiple actions
- Replace API `PollerFlux<TextAnalyticsOperationResult, PagedFlux<AnalyzeTasksResult>> beginAnalyzeTasks(
Iterable<TextDocumentInput> documents, AnalyzeTasksOptions options)` to
`PollerFlux<AnalyzeBatchActionsOperationDetail, PagedFlux<AnalyzeBatchActionsResult>>
beginAnalyzeBatchActions(Iterable<TextDocumentInput> documents, TextAnalyticsActions actions,
AnalyzeBatchActionsOptions options)`.
- New overload API, `PollerFlux<AnalyzeBatchActionsOperationDetail, PagedFlux<AnalyzeBatchActionsResult>>
beginAnalyzeBatchActions(Iterable<String> documents, TextAnalyticsActions actions, String language,
AnalyzeBatchActionsOptions options)`
- New class `ExtractKeyPhrasesActionResult`, `RecognizeEntitiesActionResult`, `RecognizePiiEntitiesActionResult`,
- Replace API
`PollerFlux<TextAnalyticsOperationResult, PagedFlux<AnalyzeTasksResult>> beginAnalyzeTasks(Iterable<TextDocumentInput> documents, AnalyzeTasksOptions options)`to
`PollerFlux<AnalyzeBatchActionsOperationDetail, PagedFlux<AnalyzeBatchActionsResult>> beginAnalyzeBatchActions(Iterable<TextDocumentInput> documents, TextAnalyticsActions actions, AnalyzeBatchActionsOptions options)`,
`SyncPoller<TextAnalyticsOperationResult, PagedIterable<AnalyzeTasksResult>> beginAnalyzeTasks(Iterable<TextDocumentInput> documents, AnalyzeTasksOptions options, Context context)`to
`SyncPoller<AnalyzeBatchActionsOperationDetail, PagedIterable<AnalyzeBatchActionsResult>> beginAnalyzeBatchActions(Iterable<TextDocumentInput> documents, TextAnalyticsActions actions, AnalyzeBatchActionsOptions options, Context context)`
- Added new overload APIs,
`PollerFlux<AnalyzeBatchActionsOperationDetail, PagedFlux<AnalyzeBatchActionsResult>> beginAnalyzeBatchActions(Iterable<String> documents, TextAnalyticsActions actions, String language, AnalyzeBatchActionsOptions options)`,
`SyncPoller<AnalyzeBatchActionsOperationDetail, PagedIterable<AnalyzeBatchActionsResult>> beginAnalyzeBatchActions(Iterable<String> documents, TextAnalyticsActions actions, String language, AnalyzeBatchActionsOptions options)`
- Added `ExtractKeyPhrasesActionResult`, `RecognizeEntitiesActionResult`, `RecognizePiiEntitiesActionResult`,
`TextAnalyticsActions`, `TextAnalyticsActionResult`
- Removed `EntitiesTask`, `KeyPhrasesTask`, `PiiTask`, `TextAnalyticsErrorInformation`
- Renamed
Expand All @@ -21,7 +39,7 @@
`PiiTaskParameters` to `RecognizePiiEntityOptions`,
`PiiEntityDomainType` to `PiiEntitiesDomainType`,
`RecognizePiiEntityOptions` to `RecognizePiiEntitiesOptions`,
`TextAnalyticsOperationResult` to `AnalyzeBatchActionsOperationDetail`,
`TextAnalyticsOperationResult` to `AnalyzeBatchActionsOperationDetail`

## 5.0.2 (2021-01-14)
### Dependency updates
Expand Down
90 changes: 49 additions & 41 deletions sdk/textanalytics/azure-ai-textanalytics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ and includes six main functions:
- Named Entity Recognition
- Personally Identifiable Information Entity Recognition
- Linked Entity Recognition
- Healthcare Recognition <sup>beta</sup>
- Support Analyze Healthcare Entity <sup>beta</sup>
- Support Multiple Actions Per Document <sup>beta</sup>

[Source code][source_code] | [Package (Maven)][package] | [API reference documentation][api_reference_doc] | [Product Documentation][product_documentation] | [Samples][samples_readme]
Expand Down Expand Up @@ -88,7 +88,7 @@ az cognitiveservices account keys list --resource-group <your-resource-group-nam
```

Use the key as the credential parameter to authenticate the client:
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L62-L65 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L66-L69 -->
```java
TextAnalyticsClient textAnalyticsClient = new TextAnalyticsClientBuilder()
.credential(new AzureKeyCredential("{key}"))
Expand All @@ -97,7 +97,7 @@ TextAnalyticsClient textAnalyticsClient = new TextAnalyticsClientBuilder()
```

The Azure Text Analytics client library provides a way to **rotate the existing key**.
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L93-L99 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L97-L103 -->
```java
AzureKeyCredential credential = new AzureKeyCredential("{key}");
TextAnalyticsClient textAnalyticsClient = new TextAnalyticsClientBuilder()
Expand Down Expand Up @@ -135,7 +135,7 @@ Authorization is easiest using [DefaultAzureCredential][wiki_identity]. It finds
running environment. For more information about using Azure Active Directory authorization with Text Analytics, please
refer to [the associated documentation][aad_authorization].

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L82-L86 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L86-L90 -->
```java
TokenCredential defaultCredential = new DefaultAzureCredentialBuilder().build();
TextAnalyticsAsyncClient textAnalyticsClient = new TextAnalyticsClientBuilder()
Expand Down Expand Up @@ -196,14 +196,14 @@ The following sections provide several code snippets covering some of the most c
Text analytics support both synchronous and asynchronous client creation by using
`TextAnalyticsClientBuilder`,

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L62-L65 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L66-L69 -->
``` java
TextAnalyticsClient textAnalyticsClient = new TextAnalyticsClientBuilder()
.credential(new AzureKeyCredential("{key}"))
.endpoint("{endpoint}")
.buildClient();
```
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L72-L75 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L76-L79 -->
``` java
TextAnalyticsAsyncClient textAnalyticsClient = new TextAnalyticsClientBuilder()
.credential(new AzureKeyCredential("{key}"))
Expand All @@ -215,7 +215,7 @@ TextAnalyticsAsyncClient textAnalyticsClient = new TextAnalyticsClientBuilder()
Run a Text Analytics predictive model to identify the positive, negative, neutral or mixed sentiment contained in the
provided document or batch of documents.

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L122-L126 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L126-L130 -->
```java
String document = "The hotel was dark and unclean. I like microsoft.";
DocumentSentiment documentSentiment = textAnalyticsClient.analyzeSentiment(document);
Expand All @@ -234,7 +234,7 @@ Please refer to the service documentation for a conceptual discussion of [sentim
### Detect language
Run a Text Analytics predictive model to determine the language that the provided document or batch of documents are written in.

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L133-L136 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L137-L140 -->
```java
String document = "Bonjour tout le monde";
DetectedLanguage detectedLanguage = textAnalyticsClient.detectLanguage(document);
Expand All @@ -247,7 +247,7 @@ Please refer to the service documentation for a conceptual discussion of [langua
### Extract key phrases
Run a model to identify a collection of significant phrases found in the provided document or batch of documents.

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L167-L169 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L171-L173 -->
```java
String document = "My cat might need to see a veterinarian.";
System.out.println("Extracted phrases:");
Expand All @@ -261,7 +261,7 @@ Run a predictive model to identify a collection of named entities in the provide
categorize those entities into categories such as person, location, or organization. For more information on available
categories, see [Text Analytics Named Entity Categories][named_entities_categories].

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L143-L146 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L147-L150 -->
```java
String document = "Satya Nadella is the CEO of Microsoft";
textAnalyticsClient.recognizeEntities(document).forEach(entity ->
Expand All @@ -277,7 +277,7 @@ document. It recognizes and categorizes PII entities in its input text, such as
Social Security Numbers, bank account information, credit card numbers, and more. This endpoint is only supported for
API versions v3.1-preview.1 and above.

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L176-L182 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L180-L186 -->
```java
String document = "My SSN is 859-98-0987";
PiiEntityCollection piiEntityCollection = textAnalyticsClient.recognizePiiEntities(document);
Expand All @@ -295,7 +295,7 @@ Please refer to the service documentation for [supported PII entity types][pii_e
Run a predictive model to identify a collection of entities found in the provided document or batch of documents,
and include information linking the entities to their corresponding entries in a well-known knowledge base.

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L153-L160 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L157-L164 -->

```java
String document = "Old Faithful is a geyser at Yellowstone Park.";
Expand All @@ -310,47 +310,55 @@ textAnalyticsClient.recognizeLinkedEntities(document).forEach(linkedEntity -> {
For samples on using the production recommended option `RecognizeLinkedEntitiesBatch` see [here][recognize_linked_entities_sample].
Please refer to the service documentation for a conceptual discussion of [entity linking][named_entity_recognition].

### Recognize healthcare entities
### Analyze healthcare entities
Text Analytics for health is a containerized service that extracts and labels relevant medical information from
unstructured texts such as doctor's notes, discharge summaries, clinical documents, and electronic health records.
Currently, Azure Active Directory (AAD) is not supported in the Healthcare recognition feature. In order to use this
functionality, request to access public preview is required. For more information see [How to: Use Text Analytics for health][healthcare].
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L189-L225 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L193-L237 -->
```java
List<TextDocumentInput> documents = Arrays.asList(new TextDocumentInput("0",
"RECORD #333582770390100 | MH | 85986313 | | 054351 | 2/14/2001 12:00:00 AM | "
+ "CORONARY ARTERY DISEASE | Signed | DIS | Admission Date: 5/22/2001 "
+ "Report Status: Signed Discharge Date: 4/24/2001 ADMISSION DIAGNOSIS: "
+ "CORONARY ARTERY DISEASE. 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's "
+ "increased symptoms and family history and history left main disease with total occasional of his RCA was referred "
+ "for revascularization with open heart surgery."
+ "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's increased symptoms and family history and"
+ " history left main disease with total occasional of his RCA was referred"
+ " for revascularization with open heart surgery."
));
RecognizeHealthcareEntityOptions options = new RecognizeHealthcareEntityOptions().setIncludeStatistics(true);
SyncPoller<TextAnalyticsOperationResult, PagedIterable<HealthcareTaskResult>> syncPoller =
textAnalyticsClient.beginAnalyzeHealthcare(documents, options, Context.NONE);
AnalyzeHealthcareEntitiesOptions options = new AnalyzeHealthcareEntitiesOptions().setIncludeStatistics(true);
SyncPoller<AnalyzeHealthcareEntitiesOperationDetail, PagedIterable<AnalyzeHealthcareEntitiesResultCollection>>
syncPoller = textAnalyticsClient.beginAnalyzeHealthcareEntities(documents, options, Context.NONE);
syncPoller.waitForCompletion();
syncPoller.getFinalResult().forEach(healthcareTaskResult ->
healthcareTaskResult.getResult().forEach(healthcareEntitiesResult -> {
syncPoller.getFinalResult().forEach(healthcareTaskResult -> healthcareTaskResult.forEach(
healthcareEntitiesResult -> {
System.out.println("Document entities: ");
HealthcareEntityCollection healthcareEntities = healthcareEntitiesResult.getEntities();
AtomicInteger ct = new AtomicInteger();
healthcareEntities.forEach(healthcareEntity -> {
System.out.printf("i = %d, Text: %s, category: %s, subcategory: %s, confidence score: %f.%n",
ct.getAndIncrement(),
healthcareEntity.getText(), healthcareEntity.getCategory(), healthcareEntity.getSubcategory(),
healthcareEntity.getConfidenceScore());
List<HealthcareEntityLink> links = healthcareEntity.getDataSourceEntityLinks();
if (links != null) {
links.forEach(healthcareEntityLink ->
System.out.printf("\tHealthcare data source ID: %s, data source: %s.%n",
healthcareEntityLink.getDataSourceId(), healthcareEntityLink.getDataSource()));
healthcareEntitiesResult.getEntities().forEach(healthcareEntity -> {
System.out.printf("\ti = %d, Text: %s, category: %s, subcategory: %s, confidence score: %f.%n",
ct.getAndIncrement(), healthcareEntity.getText(), healthcareEntity.getCategory(),
healthcareEntity.getSubcategory(), healthcareEntity.getConfidenceScore());
IterableStream<EntityDataSource> healthcareEntityDataSources =
healthcareEntity.getDataSources();
if (healthcareEntityDataSources != null) {
healthcareEntityDataSources.forEach(healthcareEntityLink -> System.out.printf(
"\t\tEntity ID in data source: %s, data source: %s.%n",
healthcareEntityLink.getEntityId(), healthcareEntityLink.getName()));
}
Map<HealthcareEntity, HealthcareEntityRelationType> relatedHealthcareEntities =
healthcareEntity.getRelatedEntities();
if (!CoreUtils.isNullOrEmpty(relatedHealthcareEntities)) {
relatedHealthcareEntities.forEach((relatedHealthcareEntity, entityRelationType) -> System.out.printf(
"\t\tRelated entity: %s, relation type: %s.%n",
relatedHealthcareEntity.getText(), entityRelationType));
}
});
}));
Expand All @@ -360,7 +368,7 @@ syncPoller.getFinalResult().forEach(healthcareTaskResult ->
The `Analyze` functionality allows to choose which of the supported Text Analytics features to execute in the same
set of documents. Currently, the supported features are: `entity recognition`, `key phrase extraction`, and
`Personally Identifiable Information (PII) recognition`.
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L232-L280 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L244-L292 -->
```java
List<TextDocumentInput> documents = Arrays.asList(
new TextDocumentInput("0",
Expand Down Expand Up @@ -420,7 +428,7 @@ Text Analytics clients raise exceptions. For example, if you try to detect the l
document IDs, `400` error is return that indicating bad request. In the following code snippet, the error is handled
gracefully by catching the exception and display the additional information about the error.

<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L106-L115 -->
<!-- embedme ./src/samples/java/com/azure/ai/textanalytics/ReadmeSamples.java#L110-L119 -->
```java
List<DetectLanguageInput> documents = Arrays.asList(
new DetectLanguageInput("1", "This is written in English.", "us"),
Expand Down
Loading

0 comments on commit b507bd6

Please sign in to comment.