Note |
---|
This specification might evolve based on the development constraints. |
Summary
Table of Contents |
---|
Claim AI-based Adjudication System
...
The AI input model is represented by a matrix having on each row one Medical Item/Service from a Claim. If the FHIR Claim Bundle contains multiple Claims then the AI input model will contain all Items/Services from all Claims. Each row contains the following informations (either FHIR Medical OR ActivityDefinition, representing an Item in FHIR Claim):
identifier (ItemUUID) | identifier (ServiceUUID) | identifier (ClaimUUID) | identifier (InsureeUUID, CHFID) | identifier (HfUUID) |
extension.unitPrice | unitPrice | billablePeriod (start, end) | birthDate (to calculate age) | location (HFLocationUUID) |
frequency | frequency | created | gender | category |
extension.useContext (ItemPatCat) | useContext (ServicePatCat) | type | extension.isHead | type |
type (always “Medication”) | type (always “ActivityDefinition”) | item.quantity | linkextension.typepovertyStatus | |
item.unitPrice | extension.povertyStatuslocationCode (LocationUUID) | |||
diagnosis.diagnosisReference (for icd_0 get ICDID) | extension.locationCode group (LocationUUIDFamilyUUID) | |||
diagnosis.diagnosisReference (for icd_1 get ICDID) | ||||
enterer (ClaimAdminUUID)extension.group (FamilyUUID) |
As in FHIR Claim each Item represents either Medication or ActivityDefinition, each row in the AI input model contains only a Medication or ActivityDefinition.
...
Note |
---|
In this project, the generated AI Model is only valid for Nepal openIMIS implementation. Any usage in other context/implementation will give wrong categorization responses. For other context/implementation, the retraining of the AI Model, based on already categorized Claims, is mandatory. |
Several data files are to be loaded and saved during the AI Model execution:
encoded fields data file
scalling file
AI model file
The AI Model file name with full path (or relative path) is configured in the modules configuration key ai_model_file
. Each time the model is executed, the model file is loaded, allowing to change the filename on execution in the configuration (hot-reload).
...
The following module configuration is defined:
Code Block | ||
---|---|---|
| ||
{ 'authentication': [string], // Authentication key list. String Default: [] ai'claim_modelresponse_fileurl': string'http://localhost:8000/claim_ai/ClaimResponse', // URL set AIin Modelthe fileClaimResponse. nameString with full path. Default: ./'ai_model.pkl_file': "joblib_Voting_Model.pkl", // AI Model file name, relative location to module folder. String claim'ai_responsescaler_organizationfile': string"scaler.pkl", // Value to build the insurer reference in the ClaimResponse. Default: openIMIS-Claim-AI } |
Note |
---|
The default AI Model filename will be defined after finalizing the AI Algorithm development. |
Each configuration key usage is explained in previous sections.
Claim-AI Quality Module
Claim-AI Quality Responsibilities
Contribute to Claim Review Search with Medical Item/Service and AI-categorized filters
Prepare the new checked claims for AI categorisation
Push Claims to Claim-AI module on scheduled task and/or event-based activation and update Claims based on the response
Reports Claim adjudication misclassifications
Claim-AI Adjudication Activation Methods
Two activation methods, allowing to start the Claim-AI module processing, are available in the Claim-AI Quality module.
Event-based activation
...
AI Scaler file name, relative location to module folder. String
'ai_encoder_file': "Encoder.obj", // AI Encoder file name, relative location to module folder. String
'claim_response_organization': 'openIMIS-Claim-AI', // Organisation name in ClaimResponse. String
'date_format': '%Y-%m-%d', // Date format to use. String
'first_date': '2016-01-01' // First date for date transformation. String
}
|
Note |
---|
The default AI Model filename will be defined after finalizing the AI Algorithm development. |
Each configuration key usage is explained in previous sections.
Claim-AI Quality Module
Claim-AI Quality Responsibilities
Contribute to Claim Review Search with Medical Item/Service and AI-categorized filters
Prepare the new checked claims for AI categorisation
Push Claims to Claim-AI module on scheduled task and/or event-based activation and update Claims based on the response
Reports Claim adjudication misclassifications
Claim-AI Adjudication Activation Methods
Two activation methods, allowing to start the Claim-AI module processing, are available in the Claim-AI Quality module.
Event-based activation
This activation is based on the openIMIS mutation signal signal_mutation_module_after_mutating
on SubmitClaimMutation
mutation (red AcceptSignalAction in AI-based Claim Adjudication Process). First, this event allows to prepare the Claims for the Claim-AI adjudication processing. Second, it would allow to push the Claims to Claim-AI module for the actual adjudication. Because we are interested to activate the processing using this event, we propose to define the module configuration variable event_based_activation
, allowing to push the checked Claims immediately after Rule Engine check.
...
FHIR Contained Resources feature allows to integrate the referred resourced. Because AI-model is requiring information from other resources referenced by the Claim, these resources must to be accessible from the Claim sent by Claim-AI Quality module. In case of FHIR Claim, these are Patient, Condition, Medication, HealthcareService, Practitioner, ActivityDefinition. The mechanism to build Claim resource with Contained Resources is developed in the openIMIS FHIR R4 module. In FHIR R4 module, the inclusion of Contained Resources should be possible based on the query variable contained=true/false
(default false
).
...
Claim.ReviewStatus: updated to “Selected for Review” (value 4) if the ClaimResponse contains rejected items
ClaimItem.Status/ClaimService.Status: updated to “rejected” (value 2) for each ClaimResponse.item where adjudication.category equal to 1
json_ext.claim_ai_quality.was_categorized: updated to True
json_ext.claimClaimItem.RejectionReason/ClaimService.RejectionReason: updated to “rejected by AI” (value -2) for each ClaimResponse.item where adjudication.category equal to 1
json_ext.claim_ai_quality.was_categorized: updated to True
json_ext.claim_ai_quality.ai_result: updated to ClaimResponse.item.adjudication.category + 1 (DB values 1-Accepted, 2-Rejected)
...
Plantumlcloud | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
Expand | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||
RejectedByRuleEngine --> [*] RuleEngineValidation --> CheckedIdle : Accept \n Some ItemsCheckedIdle : ClaimStatus=Checked (4) CheckedIdle : json
} state "AI Automatic Categorisation" as AICheck { state AIClaimCategorisation <<choice>> CheckedIdle --> AIClaimCategorisation AIClaimCategorisation --> CheckedAIAccepted : Accept\nAll ItemsCheckedAIAccepted :
CheckedAIAccepted :
CheckedAIFlagged : ReviewStatus=SelectedForReview (4) CheckedAIFlagged : ClaimItemStatus=Rejected (2) CheckedAIFlagged : RejectionReason=TBD CheckedAIFlagged :
CheckedAIFlagged :
note top of CheckedAIFlagged : Rejected Items values } state "Manual Review" as ManualReview { state SelectForReview <<choice>> CheckedAIAccepted --> SelectForReview SelectForReview --> CheckedNotSelected : Select manually\nnot to review SelectForReview --> CheckedSelected : Select manually\nto review state RequireManualReview <<choice>> CheckedSelected --> RequireManualReview CheckedAIFlagged --> RequireManualReview : Selected automatically\nfor review RequireManualReview --> CheckedRejected : Manual Review\nReject All Items CheckedRejected --> [*] RequireManualReview --> CheckedAccepted : Manual Review\nAccept Some Items CheckedAccepted --> CheckedReviewed : Deliver review } state "Processing" as Process { CheckedReviewed --> ValuatedAccepted : Process CheckedNotSelected --> ValuatedAccepted : Process CheckedAccepted --> ValuatedBypassed : Process \nwithout \ndelivering \nreview ValuatedBypassed --> [*] ValuatedAccepted --> [*] } @enduml |
Only the Claims which contains Items/Services rejected by Claim-AI module will have the fields updated. The json_ext fields are always updated, even for the totally accepted Claim.
To ease the conversion from FHIR ClaimResponse to openIMIS Claim and saving into the DB, we have implemented the HTTP PUT method for ClaimResponse resource into openIMIS FHIR R4 Module.
Models
The new Claim-AI adjudication process is executed between Rule-based engine and the manual adjudication (see Getting the ClaimResponse from Claim-AI Module section). Because we decided not to add additional statuses to Claim, requiring to modify the Claim module, we will to use the JSON extensions that can be added and updated from the Claim-AI Quality module.
The following JSON extensions will be created to support the Claim AI-based Categorisation:
to add information on Claim. The field
was_categorized
allow to filter automatically checked Claim that have not been categorized by AI and ‘hide’ them for manual adjudication.Code Block language json "json_ext": { "claim_ai_quality": { "was_categorized": "boolean", // whether the claim has been categorized by Claim-AI module or not "request_time": "datetime", // time when the claim has been sent to Claim-AI module "response_time": "datetime" // time when the claim adjudication response has been received from Claim-AI module } }
to add information on ClaimItem and ClaimService. This is used to store AI categorisation result to allow the misclassification report.
Code Block "json_ext": { "claim_ai_quality": { "ai_result": "integer" // claim adjudication value provided by Claim-AI module (for misclassification report) } }
...
Expand | ||
---|---|---|
| ||
@startuml class Claim as "openimis.claim.models.Claim" { -- claim_ai_quality extension -- +
|
Only the Claims which contains Items/Services rejected by Claim-AI module will have the fields updated. The json_ext fields are always updated, even for the totally accepted Claim.
To ease the conversion from FHIR ClaimResponse to openIMIS Claim and saving into the DB, we have implemented the HTTP PUT method for ClaimResponse resource into openIMIS FHIR R4 Module.
Models
The new Claim-AI adjudication process is executed between Rule-based engine and the manual adjudication (see Getting the ClaimResponse from Claim-AI Module section). Because we decided not to add additional statuses to Claim, requiring to modify the Claim module, we will to use the JSON extensions that can be added and updated from the Claim-AI Quality module.
The following JSON extensions will be created to support the Claim AI-based Categorisation:
to add information on Claim. The field
was_categorized
allow to filter automatically checked Claim that have not been categorized by AI and ‘hide’ them for manual adjudication.Code Block language json "json_ext": { "claim_ai_quality": { "was_categorized": "boolean", // whether the claim has been categorized by Claim-AI module or not "request_time": "datetime", // time when the claim has been sent to Claim-AI module "response_time": "datetime" // time when the claim adjudication response has been received from Claim-AI module } }
to add information on ClaimItem and ClaimService. This is used to store AI categorisation result to allow the misclassification report.
Code Block "json_ext": { "claim_ai_quality": { "ai_result": "integer" // claim adjudication value provided by Claim-AI module (for misclassification report) } }
Plantumlcloud | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
Expand | ||
---|---|---|
| ||
@startuml class Claim as "openimis.claim.models.Claim" { class ClaimItem as "openimis.claim.models.ClaimItem" { class ClaimService as "openimis.claim.models.ClaimService" { class Service as "openimis.medical.models.Service" { } class Item as "openimis.medical.models.Item " { } class openimis.core.models.ExtendableModel { class openimis.core.models.VersionedModel { openimis.core.models.BaseVersionedModel ^-- openimis.core.models.VersionedModel openimis.core.models.VersionedModel ^-- Claim Claim "0.." - "0.." Item Service "0.." - "0.." Claim @enduml |
Because currently ClaimItem
and ClaimService
doesn’t support custom fields, these classes will also extend the ExtendableModel
class.
Migrations
Because the Claim-AI modules are activated after Claims have been adjudicated (the data used for the training), a migration script needs to be created to insert the JSON fields into the available data. The following initializations will be used:
If Claim.ClaimStatus == Entered (Value 2) Then don’t add Claim.json_ext.claim_ai_quality
If Claim.ClaimStatus == Checked (Value 4) Then add
Code Block |
---|
Claim.json_ext.claim_ai_quality.ai_result: integer = 0 }class ClaimService as "openimis.claim.models.ClaimService" { -- was_categorized = false Claim.json_ext.claim_ai_qualityextension -- + .request_time = null Claim.json_ext.claim_ai_quality.ai_result: integer = 0 } class Service as "openimis.medical.models.Service" { } class Item as "openimis.medical.models.Item " { } class openimis.core.models.ExtendableModel { class openimis.core.models.VersionedModel { openimis.core.models.BaseVersionedModel ^-- openimis.core.models.VersionedModel openimis.core.models.VersionedModel ^-- Claim Claim "0.." - "0.." Item Service "0.." - "0.." Claim @enduml |
Because currently ClaimItem
and ClaimService
doesn’t support custom fields, these classes will also extend the ExtendableModel
class.
Migrations
...
response_time = null |
If Claim.ClaimStatus == Rejected (Value 1) Then add
Code Block |
---|
Claim.json_ext.claim_ai_quality.was_categorized = false
Claim.json_ext.claim_ai_quality.request_time = Claim.ValidityFrom
Claim.json_ext.claim_ai_quality.response_time = Claim.ValidityFrom
ClaimService.json_ext.claim_ai_quality.ai_result = ClaimService.ClaimServiceStatus
ClaimItem.json_ext.claim_ai_quality.ai_result = ClaimItem.ClaimItemStatus |
If Claim.ClaimStatus in [Reviewed/Processed (Value 8), Valuated (Value 16)] Then add
Code Block |
---|
Claim.json_ext.claim_ai_quality.was_categorized = true Claim.json_ext.claim_ai_quality.request_time = Claim.ValidityFromReview Claim.json_ext.claim_ai_quality.response_time = Claim.ValidityFromReview ClaimService.json_ext.claim_ai_quality.ai_result = ClaimService.ClaimServiceStatus ClaimItem.json_ext.claim_ai_quality.ai_result = ClaimItem.ClaimItemStatus |
...
ClaimFilterMedicalItem
allows Medical Officers to filter the Claims list based on a specific Medical Item (only one from autocomplete list)ClaimFilterMedicalService
allows Medical Officers to filter the Claims list based on a specific Medical Service (only one from autocomplete list)ClaimFilterAIProcessed
allows Medical Officers to display or hide the non AI-processed Claims (checkbox, decision if this is hidden or not )dropdown with options:Show all
,AI-Categorized Claim Only
,Not AI-Categorized Claims Only
, defaultAI-Categorized Claim Only
)
Custom Claim Review Search Results - Frontend
The following column will be added to the claim.Searcher
result list:
ClaimResultsAIProcessed
will display the value ofClaim.json_ext.claim_ai_quality.was_categorized
as True/False.
AI Categorisation Misclassification Report
A PDF report is generated that provides the following information (output based on manual reviewed Claims):
...
information (output based on manual reviewed Claims):
total number of Claims
accuracy score ( Accuracy = (TP+TN)/(TP+TN+FP+FN) )
number of True Positives results
number of True Negative results
number of False Positive results
number of False Negative results
Table with Claim that were fixed (
ClaimItem.json_ext.claim_ai_quality.ai_result != ClaimItem.ClaimItemStatus
- same for ClaimService)same format as Claim Overview report with Scope as ‘Claim and All Details’
For each Item and Service will be added:
json_ext.claim_ai_quality.ai_result
columnMedical Officer name from AuditUserIDReview (same as for ClaimAdmin)
To generate this report, the user will have have to filter through the Review Claims search form and trigger the report through a button (label is “AI Misclassification Report”). Only the filtered Claims will be considered for the reportwill be considered for the report.
The button should be hidden if ClaimStatus is Entered or Checked.
Deployment architecture
The two modules should be implemented as follow:
...
Plantumlcloud | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
Expand | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||
database openIMISDB node openIMISImplementation as
ClaimAIQualityModule --^ ClaimModule } openIMISImplementation
} ClaimAIModule
ClaimAIAlgorithm
ClaimAIAlgorithm
|
Testing
Testing the WebSocket from JavaScript console
...