kevinhug commited on
Commit
9bac96a
·
1 Parent(s): e79f773
Files changed (3) hide show
  1. app.py +126 -0
  2. classify.py +24 -16
  3. judge.py +1 -2
app.py CHANGED
@@ -478,6 +478,132 @@ Once created, knowledge graphs can be repurposed across multiple use cases (e.g.
478
  btn_recommend = gr.Button("Classify & Evaluation")
479
  btn_recommend.click(fn=judge, inputs=in_verbatim, outputs=out_product)
480
  gr.Markdown("""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  Benefits of Multi Class Classification
482
  ==================
483
  - Precision Decision-Making
 
478
  btn_recommend = gr.Button("Classify & Evaluation")
479
  btn_recommend.click(fn=judge, inputs=in_verbatim, outputs=out_product)
480
  gr.Markdown("""
481
+ Example Output
482
+ ===========
483
+ ```
484
+ {
485
+ "texts": [
486
+ "\"The online portal makes managing my mortgage payments so convenient.\"",
487
+ "\"RBC offer great mortgage for my home with competitive rate thank you\"",
488
+ "\"Low interest rate compared to other cards I’ve used. Highly recommend for responsible spenders.\"",
489
+ "\"The mobile check deposit feature saves me so much time. Banking made easy!\"",
490
+ "\"Affordable premiums with great coverage. Switched from my old provider and saved!\""
491
+ ],
492
+ "predictions": [
493
+ [
494
+ {
495
+ "chain_of_thought": [
496
+ "The customer mentions managing mortgage payments online, which directly relates to the 'online' tag.",
497
+ "There is no mention or implication of card, cars, insurance, or any other tags in the text."
498
+ ],
499
+ "name": "online",
500
+ "id": 0,
501
+ "confidence": 1.0
502
+ }
503
+ ],
504
+ [
505
+ {
506
+ "chain_of_thought": [
507
+ "The customer explicitly mentions 'mortgage for my home', which directly corresponds to the tag name 'mortgage'.",
508
+ "There is no mention of online, card, cars, or insurance in the text.",
509
+ "Therefore, we can confidently apply the mortgage tag."
510
+ ],
511
+ "name": "mortgage",
512
+ "id": 3,
513
+ "confidence": 1.0
514
+ }
515
+ ],
516
+ [
517
+ {
518
+ "chain_of_thought": [
519
+ "The customer mentions a low interest rate and compares it to other cards they have used. This indicates the text is related to a card product.",
520
+ "There is no mention of online services, cars, mortgage, or insurance in the text."
521
+ ],
522
+ "name": "card",
523
+ "id": 1,
524
+ "confidence": 0.9
525
+ }
526
+ ],
527
+ [
528
+ {
529
+ "chain_of_thought": [
530
+ "The customer explicitly mentions the mobile check deposit feature which is related to online banking services.",
531
+ "There is a Tag with id 0 named 'online' that matches the content of the text."
532
+ ],
533
+ "name": "online",
534
+ "id": 0,
535
+ "confidence": 1.0
536
+ }
537
+ ],
538
+ [
539
+ {
540
+ "chain_of_thought": [
541
+ "The customer mentions 'premiums' and 'coverage', which are related to insurance products. There is a tag named 'insurance' with id 4, so we can
542
+ tag this text with 'insurance'.",
543
+ "There's no mention of online services, cards, cars, or mortgages in the text."
544
+ ],
545
+ "name": "insurance",
546
+ "id": 4,
547
+ "confidence": 0.9
548
+ }
549
+ ]
550
+ ],
551
+ "judgment": [
552
+ [
553
+ {
554
+ "thought": "The reasoning states that the customer mentioned managing mortgage payments online. The answer provided is 'online'. Since the context
555
+ explicitly stated that the topic was about online management, it logically follows that 'online' would be the correct and relevant response.",
556
+ "justification": "The reasoning directly connects the mention of 'managing mortgage payments online' to the answer 'online', making the logic sound
557
+ . There are no other tags or concepts mentioned that could have influenced this answer, so the connection is clear and valid.",
558
+ "logical": true
559
+ }
560
+ ],
561
+ [
562
+ {
563
+ "thought": "<thought>Given that the reasoning explicitly states 'mortgage for my home' and directly corresponds to the tag name 'mortgage', and the
564
+ re's no mention of other financial products like online, card, cars, or insurance, it is logical to conclude that the answer 'mortgage' is correct. The con
565
+ text provided supports this by not contradicting the reasoning.</thought>",
566
+ "justification": "<justification>The reasoning clearly states a direct match between the customer's statement and the tag name 'mortgage'. There ar
567
+ e no conflicting elements in the text, making the connection sound and valid. Therefore, it is logical that the answer 'mortgage' is relevant to the given
568
+ context.</justification>",
569
+ "logical": true
570
+ }
571
+ ],
572
+ [
573
+ {
574
+ "thought": "<thought>Given that the reasoning states there's a low interest rate mentioned and comparison to other cards, it logically follows that
575
+ 'card' would be an appropriate answer. The context, although incomplete, aligns with the reasoning as it pertains to card products.</thought>",
576
+ "justification": "<justification>The reasoning correctly identifies the topic of discussion (cards) based on key phrases like 'low interest rate' a
577
+ nd 'comparison to other cards'. Since the answer provided is 'card', which directly corresponds to this context, the logical connection between the reasoni
578
+ ng and the answer is valid.</justification>",
579
+ "logical": true
580
+ }
581
+ ],
582
+ [
583
+ {
584
+ "thought": "The reasoning states that the customer mentioned the mobile check deposit feature, which is related to online banking services. The con
585
+ text provided a tag with id '0' named 'online', and the answer given is 'online'. This directly matches the content of the text, making it relevant.",
586
+ "justification": "Since the context provides a clear connection between the customer's mention of mobile check deposit (related to online banking)
587
+ and the tag 'online', the answer 'online' is logically derived from this reasoning. The direct match in terms of content makes the logical link valid and s
588
+ ound.",
589
+ "logical": true
590
+ }
591
+ ],
592
+ [
593
+ {
594
+ "thought": "<thought> The reasoning states that the context mentions 'premiums' and 'coverage', which are related to insurance. It also notes the p
595
+ resence of an 'insurance' tag with id 4, suggesting this should be tagged as such. The answer provided is 'insurance', directly matching the reasoning's co
596
+ nclusion. There is no mention in the text or reasoning that contradicts this.</thought>",
597
+ "justification": "<justification> The reasoning and the answer are logically consistent because they both point to the same key term, 'insurance'.
598
+ The presence of relevant terms like 'premiums' and 'coverage', along with the explicit tag reference, support a logical connection between the context and
599
+ the answer. There is no indication that any other services or products mentioned in the reasoning (like online services, cards, cars, or mortgages) are pre
600
+ sent in the text.</justification>",
601
+ "logical": true
602
+ }
603
+ ]
604
+ ]
605
+ }
606
+ ```
607
  Benefits of Multi Class Classification
608
  ==================
609
  - Precision Decision-Making
classify.py CHANGED
@@ -8,12 +8,11 @@ import os
8
 
9
 
10
  from groq import AsyncGroq
11
- # Initialize with API key
12
- client = AsyncGroq(api_key=os.getenv("GROQ_API_KEY"))
13
 
14
  # Enable instructor patches for Groq client
15
- client = instructor.from_groq(client)
16
- """
 
17
  import openai
18
  client = instructor.from_openai(
19
  openai.AsyncOpenAI(
@@ -22,7 +21,7 @@ client = instructor.from_openai(
22
  ),
23
  mode=instructor.Mode.JSON,
24
  )
25
- """
26
  llm = 'llama-3.1-8b-instant' if os.getenv("GROQ_API_KEY") else "qwen2.5" #"gemma3:12b" #"llama3.2" #"deepseek-r1"
27
 
28
 
@@ -35,9 +34,10 @@ class Tag(BaseModel):
35
  default=0.5,
36
  ge=0,
37
  le=1,
38
- description="The confidence of the prediction(id, name) for the text, 0 is low, 1 is high",examples=[0.5,0.1,0.9]
39
  )
40
 
 
41
  @field_validator('confidence', mode="after")
42
  @classmethod
43
  def high_confidence(cls, c:float):
@@ -45,6 +45,7 @@ class Tag(BaseModel):
45
  if c < 0.6:
46
  raise ValueError(f"low confidence `{c}` ")
47
  return c
 
48
 
49
  @model_validator(mode="after")
50
  def validate_ids(self, info: ValidationInfo):
@@ -109,16 +110,20 @@ async def tag_single_request(text: str, tags: List[Tag]) -> Iterable[Tag]:
109
  messages=[
110
  {
111
  "role": "system",
112
- "content": """You are a world-class text tagging system for customer feedback in the banking industry to classify banking product/services.
113
- """
114
  },
115
- {"role": "user", "content": f"""Create minimum multiple Tag according to instruction most appropriate for the following text: `{text}`
116
- ### Instruction:
 
 
 
 
117
  Here are the allowed Tag(id, name), do not use any other Tag than these: {allowed_tags_str}
118
  Tag the name based on fact stated and directly mention in the text. Do not guess the name, Do not tag if tag not mention in the text. Do not use implication.
119
  Calculate the newly created Tag's confidence that Tag fit to the text
120
 
121
  For each question, show your step-by-step thinking under 'chain_of_thought' in list of string, then clearly state your final answer under 'name'.
 
122
  """ },
123
 
124
  ],
@@ -134,19 +139,24 @@ async def tag_request(request: TagRequest) -> TagResponse:
134
  predictions = await asyncio.gather(
135
  *[tag_single_request(text, request.tags) for text in request.texts]
136
  )
 
137
  pred_dedup=[]
138
  for tags in predictions:
139
  if tags is not None:
140
  dedup=[]
141
- #filter(lambda x: x.confidence > 0.7, tags)
142
- tags_s=sorted(tags, key=lambda x: (x.name, x.confidence))
 
 
 
143
  if len(tags_s)>0:
144
  dedup.append(tags_s[0])
145
  for j in range(1,len(tags_s)):
146
  if tags_s[j-1].name!=tags_s[j].name:
147
  dedup.append(tags_s[j])
148
 
149
- pred_dedup.append(dedup)
 
150
  else:
151
  pred_dedup.append(None)
152
 
@@ -166,11 +176,9 @@ tags = [
166
 
167
 
168
  texts = """
169
- "The online portal makes managing my mortgage payments so convenient."
170
- ;"RBC offer great mortgage for my home with competitive rate thank you";
171
  "Low interest rate compared to other cards I’ve used. Highly recommend for responsible spenders.";
172
  "The mobile check deposit feature saves me so much time. Banking made easy!";
173
- "Affordable premiums with great coverage. Switched from my old provider and saved!"
174
  """
175
 
176
  def judge_response(response):
 
8
 
9
 
10
  from groq import AsyncGroq
 
 
11
 
12
  # Enable instructor patches for Groq client
13
+ #client = instructor.from_groq(AsyncGroq(api_key=os.getenv("GROQ_API_KEY")))
14
+ '''
15
+
16
  import openai
17
  client = instructor.from_openai(
18
  openai.AsyncOpenAI(
 
21
  ),
22
  mode=instructor.Mode.JSON,
23
  )
24
+ '''
25
  llm = 'llama-3.1-8b-instant' if os.getenv("GROQ_API_KEY") else "qwen2.5" #"gemma3:12b" #"llama3.2" #"deepseek-r1"
26
 
27
 
 
34
  default=0.5,
35
  ge=0,
36
  le=1,
37
+ description="The confidence of the prediction(id, name) for the text, 0 is low, 1 is high"
38
  )
39
 
40
+ """
41
  @field_validator('confidence', mode="after")
42
  @classmethod
43
  def high_confidence(cls, c:float):
 
45
  if c < 0.6:
46
  raise ValueError(f"low confidence `{c}` ")
47
  return c
48
+ """
49
 
50
  @model_validator(mode="after")
51
  def validate_ids(self, info: ValidationInfo):
 
110
  messages=[
111
  {
112
  "role": "system",
113
+ "content": """You are a world-class text tagging system for customer feedback in the banking industry to classify banking product/services. """
 
114
  },
115
+ {"role": "user", "content": f"""Create minimum multiple Tag according to instruction most appropriate for the following text:
116
+ < Text >
117
+ {text}
118
+ </ Text>
119
+
120
+ < Instruction >
121
  Here are the allowed Tag(id, name), do not use any other Tag than these: {allowed_tags_str}
122
  Tag the name based on fact stated and directly mention in the text. Do not guess the name, Do not tag if tag not mention in the text. Do not use implication.
123
  Calculate the newly created Tag's confidence that Tag fit to the text
124
 
125
  For each question, show your step-by-step thinking under 'chain_of_thought' in list of string, then clearly state your final answer under 'name'.
126
+ </ Instruction >
127
  """ },
128
 
129
  ],
 
139
  predictions = await asyncio.gather(
140
  *[tag_single_request(text, request.tags) for text in request.texts]
141
  )
142
+
143
  pred_dedup=[]
144
  for tags in predictions:
145
  if tags is not None:
146
  dedup=[]
147
+ #filter(lambda x: x>5, range(10))
148
+ t=list(filter(lambda x: x.confidence > 0.7, [tag async for tag in tags]))
149
+ #tags_s=set((n.name) for n in t) #sorted(t, key=lambda x: (x.name, x.confidence))
150
+ pred_dedup.append(t)
151
+ """
152
  if len(tags_s)>0:
153
  dedup.append(tags_s[0])
154
  for j in range(1,len(tags_s)):
155
  if tags_s[j-1].name!=tags_s[j].name:
156
  dedup.append(tags_s[j])
157
 
158
+
159
+ """
160
  else:
161
  pred_dedup.append(None)
162
 
 
176
 
177
 
178
  texts = """
179
+ "The online portal makes managing my mortgage payments so convenient.";
 
180
  "Low interest rate compared to other cards I’ve used. Highly recommend for responsible spenders.";
181
  "The mobile check deposit feature saves me so much time. Banking made easy!";
 
182
  """
183
 
184
  def judge_response(response):
judge.py CHANGED
@@ -8,10 +8,9 @@ import os
8
 
9
  from groq import AsyncGroq
10
  # Initialize with API key
11
- client = AsyncGroq(api_key=os.getenv("GROQ_API_KEY"))
12
 
13
  # Enable instructor patches for Groq client
14
- client = instructor.from_groq(client)
15
 
16
  """
17
  client = instructor.from_openai(
 
8
 
9
  from groq import AsyncGroq
10
  # Initialize with API key
 
11
 
12
  # Enable instructor patches for Groq client
13
+ client = instructor.from_groq(AsyncGroq(api_key=os.getenv("GROQ_API_KEY")))
14
 
15
  """
16
  client = instructor.from_openai(