Updated Lesser Of methodology
This commit is contained in:
committed by
Michael McGuinness
parent
484c943386
commit
7ac8f5a1ba
@@ -452,3 +452,4 @@ def clean_dates(df):
|
||||
df.loc[idx, 'LOB_PRICING_TERMS_TERMINATION_DATE'] = 'N/A'
|
||||
|
||||
return df
|
||||
|
||||
|
||||
+48
-2
@@ -1,5 +1,6 @@
|
||||
|
||||
import json
|
||||
import difflib
|
||||
|
||||
import config
|
||||
import prompts
|
||||
@@ -8,8 +9,44 @@ import dict_operations
|
||||
import utils
|
||||
import postprocessingfuncs
|
||||
|
||||
def get_least_similar(dict_list, original_dict, field):
|
||||
print(f"Running similarity for {field}")
|
||||
|
||||
min_similarity = float('inf')
|
||||
least_similar_dict = None
|
||||
for dictionary in dict_list:
|
||||
# Extract the methodology text
|
||||
field_text = dictionary[field]
|
||||
print(f"Field text: {field_text}")
|
||||
|
||||
# Compute similarity using difflib
|
||||
similarity = difflib.SequenceMatcher(None, field_text, original_dict[field]).ratio()
|
||||
print(f"Simlarity: {similarity}")
|
||||
|
||||
# If the similarity is less than the current minimum, update the minimum and the corresponding dictionary
|
||||
if similarity < min_similarity:
|
||||
min_similarity = similarity
|
||||
least_similar_dict = dictionary
|
||||
|
||||
return least_similar_dict
|
||||
|
||||
def run_bottom_up_lesser(d, text_dict, tokens=8000):
|
||||
def get_lesser_of_dict(dict_list, original_dict):
|
||||
|
||||
unique_rates = list({d['REIMBURSEMENT_RATE'] for d in dict_list})
|
||||
unique_fees = list({d['REIMBURSEMENT_FLAT_FEE'] for d in dict_list})
|
||||
|
||||
# If the rates are different, return the lesser of dict with a different rate than original
|
||||
if len(unique_rates) > 1:
|
||||
least_similar_dict = get_least_similar(dict_list, original_dict, 'REIMBURSEMENT_RATE')
|
||||
elif len(unique_fees) > 1:
|
||||
least_similar_dict = get_least_similar(dict_list, original_dict, 'REIMBURSEMENT_FLAT_FEE')
|
||||
else:
|
||||
least_similar_dict = get_least_similar(dict_list, original_dict, 'FULL_METHODOLOGY')
|
||||
|
||||
return least_similar_dict
|
||||
|
||||
|
||||
def run_bottom_up_lesser(d, text_dict, tokens=4000):
|
||||
"""
|
||||
Processes specific clauses or conditions within the document text, such as 'lesser of' or 'greater of',
|
||||
using a language model to analyze and extract relevant data from the identified text segment.
|
||||
@@ -31,7 +68,16 @@ def run_bottom_up_lesser(d, text_dict, tokens=8000):
|
||||
|
||||
prompt = prompts.BOTTOM_UP_LESSER(d, text_dict[d['page_num']])
|
||||
lesser_of_answer = claude_funcs.invoke_claude_3(prompt, max_tokens=tokens)
|
||||
lesser_of_dict = dict_operations.secondary_string_to_dict(lesser_of_answer)
|
||||
lesser_of_dict_list = dict_operations.primary_string_to_dict({d['page_num'] : lesser_of_answer}, d['Filename'])
|
||||
print(lesser_of_dict_list)
|
||||
# If lesser of is Y
|
||||
if len(lesser_of_dict_list) > 1:
|
||||
lesser_of_dict = get_lesser_of_dict(lesser_of_dict_list, d)
|
||||
else:
|
||||
d['LESSER_OF_LANGUAGE_IND'] = 'N'
|
||||
d['GREATER_OF_LANGUAGE_IND'] = 'N'
|
||||
return ({}, d)
|
||||
|
||||
lesser_of_dict['page_num'] = d['page_num']
|
||||
if lesser_of_dict['LESSER_OF_LANGUAGE_IND'] == 'Y' or lesser_of_dict['GREATER_OF_LANGUAGE_IND'] == 'Y':
|
||||
lesser_of_dict['SERVICE'] = d['SERVICE']
|
||||
|
||||
+11
-7
@@ -78,25 +78,29 @@ def BOTTOM_UP_LESSER(d, page):
|
||||
### PAGE START ### {page} ### PAGE END
|
||||
|
||||
The above text contains a number of reimbursement terms. For the rest of this request, focus only on the specific term listed below:
|
||||
Service: {d['SERVICE']}
|
||||
Original_Methodology: {d['FULL_METHODOLOGY']}
|
||||
Original_Dictionary:
|
||||
- Original_Service: {d['SERVICE']}
|
||||
- Original_Rate: {d['REIMBURSEMENT_RATE']}
|
||||
- Original_Flat_Fee: {d['REIMBURSEMENT_FLAT_FEE']}
|
||||
- Original_Methodology: {d['FULL_METHODOLOGY']}
|
||||
|
||||
Your job is to identify if there is any 'lesser of' language or 'greater of' language that pertains to the specific service and methodology above.
|
||||
|
||||
Note that a 'lesser of'/'greater of' statement may not be directly written for a given Service, but that does not necessarily mean that it doesn't apply.
|
||||
|
||||
Read and analyze the page, then populate a JSON dictionary with the following fields (descriptions provided):
|
||||
Read and analyze the page, then populate two JSON dictionaries with the following fields (descriptions provided):
|
||||
'LESSER_OF_LANGUAGE_IND' : Write 'Y' if there is 'lesser of' language somewhere on the page that applies to the Service and Original_Methodology. Write 'N' if not.
|
||||
'GREATER_OF_LANGUAGE_IND' : Write 'Y' if there is 'greater of' language somewhere on the page that applies to the Service and Original_Methodology. Write 'N' if not.
|
||||
'FULL_METHODOLOGY' : If either of the above are 'Y', what is the reimbursement the lesser or greater of? Do not write the full sentence - only include the half of the lesser/greater of statement that is NOT Original_Methodology. For example, if the reimbursement is the lesser of X or Original_Methodology, return only X.
|
||||
'FULL_METHODOLOGY' : If either of the above are 'Y', what is the reimbursement the lesser or greater of? Do not write the full sentence.
|
||||
'REIMBURSEMENT_RATE' : If the Lesser/Greater Of Methodology is a percent of something, write just the numeric percent value here. Only include percentages. If not, write N/A.
|
||||
'REIMBURSEMENT_FLAT_FEE' : If the Lesser/Greater Of Methodology is a dollar value, write just the numeric value here. Only include dollar values. If not, write N/A.
|
||||
|
||||
For REIMBURSEMENT_RATE and REIMBURSEMENT_FLAT_FEE, do NOT include the Rate or Flat Fee from Original_Methodology.
|
||||
If either LESSER_OF_LANGUAGE_IND or GREATER_OF_LANGUAGE_IND is 'Y', then both dictionaries must be populated. One of the dictionaries will have REIMBURSEMENT_RATE, REIMBURSEMENT_FLAT_FEE, and FULL_METHODOLOGY values equal to the Original term.
|
||||
Fill the first dictionary with the values corresponding to the LEFT half of the Lesser/Greater Of Statement, and the second dictionary with the RIGHT half of the Lesser/Greater Of Statement.
|
||||
|
||||
Note that in some cases, the REIMBURSEMENT_RATE will not be explicitly written. It may say something like "Provider's billed charges", which is essentially equivalent to "100% of Provider's billed charges". In these cases, assign REIMBURSEMENT_RATE a value of 100%.
|
||||
If both LESSER_OF_LANGUAGE_IND and GREATER_OF_LANGUAGE_IND are 'N', return a list with just the original dictionary.
|
||||
|
||||
Only return the dictionary, with no other commentary or explanation. Ensure you abide by proper JSON formatting.
|
||||
Only return the list of dictionaries, with no other commentary or explanation. Ensure you abide by proper JSON formatting.
|
||||
"""
|
||||
|
||||
def BOTTOM_UP_EXCEPT_ESC(d, page):
|
||||
|
||||
+62
-20
@@ -17,34 +17,76 @@ import prompts
|
||||
import prompt_funcs
|
||||
import claude_funcs
|
||||
import merge_funcs
|
||||
import dict_operations
|
||||
|
||||
|
||||
# input_dict = utils.read_input()
|
||||
input_dict = utils.read_input()
|
||||
|
||||
# (filename, contract_text) = list(input_dict.items())[0]
|
||||
(filename, contract_text) = list(input_dict.items())[0]
|
||||
|
||||
# contract_text = preprocess.clean_newlines(contract_text)
|
||||
# contract_text = preprocess.clean_billed_charges(contract_text)
|
||||
# text_dict = preprocess.split_text(contract_text)
|
||||
# text_dict = table_funcs.align_and_format_tables(text_dict)
|
||||
# text_dict = preprocess.highlight_rates(text_dict)
|
||||
|
||||
# for page_num, page_text in text_dict.items():
|
||||
# if page_num == '31':
|
||||
# prompt = prompts.TOP_DOWN_PRIMARY(page_text)
|
||||
# answer = claude_funcs.invoke_claude_3(prompt, max_tokens=4000)
|
||||
# answer_dict = json.loads(answer)
|
||||
|
||||
# print(answer_dict)
|
||||
contract_text = preprocess.clean_newlines(contract_text)
|
||||
contract_text = preprocess.clean_billed_charges(contract_text)
|
||||
text_dict = preprocess.split_text(contract_text)
|
||||
text_dict = table_funcs.align_and_format_tables(text_dict)
|
||||
text_dict = preprocess.highlight_rates(text_dict)
|
||||
|
||||
|
||||
# bu_results = prompt_funcs.run_bottom_up(filename, text_dict) # Returns list of dictionaries
|
||||
# print(bu_results)
|
||||
def BOTTOM_UP_LESSER(d, page):
|
||||
return f"""
|
||||
### PAGE START ### {page} ### PAGE END
|
||||
|
||||
The above text contains a number of reimbursement terms. For the rest of this request, focus only on the specific term listed below:
|
||||
Original_Dictionary:
|
||||
- Original_Service: {d['SERVICE']}
|
||||
- Original_Rate: {d['REIMBURSEMENT_RATE']}
|
||||
- Original_Flat_Fee: {d['REIMBURSEMENT_FLAT_FEE']}
|
||||
- Original_Methodology: {d['FULL_METHODOLOGY']}
|
||||
|
||||
Your job is to identify if there is any 'lesser of' language or 'greater of' language that pertains to the specific service and methodology above.
|
||||
|
||||
Note that a 'lesser of'/'greater of' statement may not be directly written for a given Service, but that does not necessarily mean that it doesn't apply.
|
||||
|
||||
Read and analyze the page, then populate two JSON dictionaries with the following fields (descriptions provided):
|
||||
'LESSER_OF_LANGUAGE_IND' : Write 'Y' if there is 'lesser of' language somewhere on the page that applies to the Service and Original_Methodology. Write 'N' if not.
|
||||
'GREATER_OF_LANGUAGE_IND' : Write 'Y' if there is 'greater of' language somewhere on the page that applies to the Service and Original_Methodology. Write 'N' if not.
|
||||
'FULL_METHODOLOGY' : If either of the above are 'Y', what is the reimbursement the lesser or greater of? Do not write the full sentence.
|
||||
'REIMBURSEMENT_RATE' : If the Lesser/Greater Of Methodology is a percent of something, write just the numeric percent value here. Only include percentages. If not, write N/A.
|
||||
'REIMBURSEMENT_FLAT_FEE' : If the Lesser/Greater Of Methodology is a dollar value, write just the numeric value here. Only include dollar values. If not, write N/A.
|
||||
|
||||
If either LESSER_OF_LANGUAGE_IND or GREATER_OF_LANGUAGE_IND is 'Y', then both dictionaries must be populated. One of the dictionaries will have REIMBURSEMENT_RATE, REIMBURSEMENT_FLAT_FEE, and FULL_METHODOLOGY values equal to the Original term.
|
||||
Fill the first dictionary with the values corresponding to the LEFT half of the Lesser/Greater Of Statement, and the second dictionary with the RIGHT half of the Lesser/Greater Of Statement.
|
||||
|
||||
If both LESSER_OF_LANGUAGE_IND and GREATER_OF_LANGUAGE_IND are 'N', return a list with just the original dictionary.
|
||||
|
||||
Only return the list of dictionaries, with no other commentary or explanation. Ensure you abide by proper JSON formatting.
|
||||
"""
|
||||
|
||||
|
||||
d = {'SERVICE': 'Inpatient Services',
|
||||
'REIMBURSEMENT_FLAT_FEE': 'N/A',
|
||||
'REIMBURSEMENT_RATE': '105%',
|
||||
'FULL_METHODOLOGY': "The lesser of 105% of the West Virginia Medicaid DRG (based on Hospital's current DHHR payment rate) or 100% of Hospital's allowable billed charges.",
|
||||
'page_num': '26',
|
||||
'Filename': 'App Regional Healthcare_Hospital Agreement_20160414_Dually Executed WV MCD-C13439125AA.txt'}
|
||||
|
||||
answer = prompt_funcs.run_bottom_up_lesser(d, text_dict)
|
||||
print(answer)
|
||||
|
||||
|
||||
# answer_strings = prompt_funcs.run_bottom_up_primary({'3' : text_dict['3']}, 8000)
|
||||
# answer_dicts = dict_operations.primary_string_to_dict(answer_strings, filename)
|
||||
# answer_dicts_filtered = postprocessingfuncs.filter_service_column(answer_dicts)
|
||||
|
||||
# print(answer_dicts_filtered)
|
||||
|
||||
# for d in answer_dicts_filtered:
|
||||
# print(f"Original dictionary: {d}")
|
||||
# # Bottom Up Lesser
|
||||
# if config.RUN_LESSER:
|
||||
# lesser_object = prompt_funcs.run_bottom_up_lesser(d.copy(), text_dict.copy(), tokens=4000)
|
||||
# print(f"Lesser dictionary: {lesser_object}")
|
||||
|
||||
|
||||
sample_results = pd.read_csv('output/ASMG MU/combined_results_post_processed.csv')
|
||||
|
||||
df = postprocessingfuncs.clean_dates(sample_results)
|
||||
print(df)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user