Skip to content

Commit 96b880e

Browse files
committed
Adding banking classification benchmark and twitter emotion detection benchmark
1 parent 86e6bf5 commit 96b880e

8 files changed

Lines changed: 3980 additions & 43 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from langroid.agent.chat_agent import ChatAgent, ChatAgentConfig
2+
from langroid.utils.logging import setup_colored_logging
3+
from langroid.vector_store.qdrantdb import QdrantDBConfig
4+
from langroid.agent.special.retriever_agent import (
5+
RecordDoc,
6+
RecordMetadata,
7+
RetrieverAgent,
8+
RetrieverAgentConfig,
9+
)
10+
from langroid.parsing.parser import ParsingConfig
11+
12+
import pandas as pd
13+
from typing import Any, Dict, List, Sequence
14+
15+
from sklearn.metrics import accuracy_score
16+
17+
18+
# TODO: Generalize for any single-label classification task and fetch constants from user
19+
class BankingTextRetrieverAgentConfig(RetrieverAgentConfig):
20+
system_message: str = "You are an expert at understanding bank customer support queries."
21+
user_message: str = """
22+
Your task is to match a bank statement to a list of examples in a table based on semantic similarity between the given statement and the examples in the table.
23+
"""
24+
data: List[Dict[str, Any]]
25+
n_matches: int = 10
26+
vecdb: QdrantDBConfig = QdrantDBConfig(
27+
collection_name="banking-classification",
28+
storage_path=":memory:",
29+
)
30+
parsing: ParsingConfig = ParsingConfig(
31+
n_similar_docs=10,
32+
)
33+
cross_encoder_reranking_model = "" # turn off cross-encoder reranking
34+
35+
36+
# TODO: Logic for get_records can come from user
37+
class BankingTextRetrieverAgent(RetrieverAgent):
38+
def __init__(self, config: BankingTextRetrieverAgentConfig):
39+
super().__init__(config)
40+
self.config = config
41+
42+
def get_records(self) -> Sequence[RecordDoc]:
43+
return [
44+
RecordDoc(
45+
content=", ".join(f"{k}={v}" for k, v in d.items()),
46+
metadata=RecordMetadata(id=i),
47+
)
48+
for i, d in enumerate(self.config.data)
49+
]
50+
51+
52+
def compute_acc(llm_labels, gt_labels):
53+
return accuracy_score(gt_labels, llm_labels)
54+
55+
56+
class BankingTextClassifier:
57+
def __int__(
58+
self,
59+
chat_agent_config: ChatAgentConfig,
60+
rag_seed_file: str,
61+
banking_test_file: str,
62+
base_prompt: str
63+
):
64+
setup_colored_logging()
65+
66+
self.chat_agent_config = chat_agent_config
67+
self.banking_classifier_agent = ChatAgent(chat_agent_config)
68+
self.base_prompt = base_prompt
69+
70+
rag_seed_data = pd.read_csv(rag_seed_file).to_dict('records')
71+
self.banking_text_retriever_agent = BankingTextRetrieverAgent(BankingTextRetrieverAgentConfig(data=rag_seed_data))
72+
self.banking_text_retriever_agent.ingest()
73+
74+
self.test_df = pd.read_csv(banking_test_file)
75+
self.test_df['ID'] = range(1, len(self.test_df) + 1)
76+
77+
self.results_file = "./test_llm_responses.csv"
78+
self.results = {}
79+
80+
# TODO: for debug purposes only, must be removed
81+
self.test_df = self.test_df[self.test_df['ID'] < 25]
82+
self.llm_responses = None
83+
84+
def run_tweet_emotion_detect(self):
85+
agent = ChatAgent(self.chat_agent_config)
86+
87+
llm_responses = {}
88+
for idx, row in self.test_df.iterrows():
89+
prompt = self.base_prompt
90+
nearest_examples = self.banking_text_retriever_agent.get_relevant_chunks(query=row['text'])
91+
for index in range(len(nearest_examples)):
92+
example = nearest_examples[index].content
93+
text = example.split("text=")[1].split(", label=")[0]
94+
label = example.split(", label=")[1]
95+
prompt = prompt + f"Text: {text}\n"
96+
prompt = prompt + f"Label: {label}\n"
97+
prompt = prompt + "\n" + f"Text: {row['text']}\n Label: "
98+
llm_responses[row['ID']] = agent.llm_response_forget(prompt).content
99+
100+
result_dict_list = [{'ID': int(key), 'llm_label': value} for key, value in llm_responses.items()]
101+
result_df = pd.DataFrame(result_dict_list)
102+
result_df.to_csv(self.results_file, index=False)
103+
104+
self.llm_responses = result_df
105+
106+
self.compute_results(self.llm_responses)
107+
108+
def run_tweet_emotion_detect_async_batch(self):
109+
pass
110+
111+
def compute_results(self, llm_responses):
112+
combined_labels_df = self.test_df.merge(llm_responses, on="ID", how="inner")
113+
self.results['Accuracy'] = compute_acc(combined_labels_df['llm_label'], combined_labels_df['label'])

0 commit comments

Comments
 (0)