dynamic-learning-model 1.3.1__tar.gz → 1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dynamic_learning_model-1.3.1/dynamic_learning_model.egg-info → dynamic_learning_model-1.5}/PKG-INFO +1 -1
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/dlm/DLM.py +158 -71
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5/dynamic_learning_model.egg-info}/PKG-INFO +1 -1
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/setup.py +1 -1
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/LICENSE +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/README.md +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/dlm/__init__.py +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/dynamic_learning_model.egg-info/SOURCES.txt +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/dynamic_learning_model.egg-info/dependency_links.txt +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/dynamic_learning_model.egg-info/requires.txt +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/dynamic_learning_model.egg-info/top_level.txt +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/pyproject.toml +0 -0
- {dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5}/setup.cfg +0 -0
{dynamic_learning_model-1.3.1/dynamic_learning_model.egg-info → dynamic_learning_model-1.5}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dynamic-learning-model
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5
|
|
4
4
|
Summary: A Dynamic Learning Model for processing NLP queries using hybrid AI and reasoning.
|
|
5
5
|
Home-page: https://github.com/VigneshT24/Dynamic_Learning_Model
|
|
6
6
|
Author: Vignesh Thondikulam
|
|
@@ -12,7 +12,6 @@ from better_profanity import profanity
|
|
|
12
12
|
from nltk.corpus import names
|
|
13
13
|
from word2number import w2n
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
class DLM:
|
|
17
16
|
__filename = None # knowledge-base (SQL)
|
|
18
17
|
__query = None # user-inputted query
|
|
@@ -21,7 +20,7 @@ class DLM:
|
|
|
21
20
|
__nlp = None # Spacy NLP analysis
|
|
22
21
|
__tone = None # sentimental tone of user query
|
|
23
22
|
__trainingPwd = "371507" # password to enter training mode
|
|
24
|
-
__mode = None # either "
|
|
23
|
+
__mode = None # either "learn", "recall", or "compute"
|
|
25
24
|
__unsure_while_thinking = False # if uncertain while thinking, then it will let the user know that
|
|
26
25
|
__nlp_similarity_value = None # saves the similarity value by doing SpaCy calculation (for debugging)
|
|
27
26
|
__special_stripped_query = None # saves query without any special words for reduced interference while vector calculating
|
|
@@ -216,10 +215,11 @@ class DLM:
|
|
|
216
215
|
|
|
217
216
|
# to solve geometric problems (advanced CoT)
|
|
218
217
|
__geometric_calculation_identifiers = {
|
|
218
|
+
# 2D Shapes – Area
|
|
219
219
|
"triangle": {
|
|
220
|
-
"keywords": ["area", "triangle"],
|
|
221
|
-
"params": ["base", "height"],
|
|
222
|
-
"formula": lambda d: 0.5 * d["base"] * d["height"]
|
|
220
|
+
"keywords": ["area", "triangle"],
|
|
221
|
+
"params": ["base", "height"],
|
|
222
|
+
"formula": lambda d: 0.5 * d["base"] * d["height"]
|
|
223
223
|
},
|
|
224
224
|
"rectangle": {
|
|
225
225
|
"keywords": ["area", "rectangle"],
|
|
@@ -244,7 +244,49 @@ class DLM:
|
|
|
244
244
|
"circle": {
|
|
245
245
|
"keywords": ["area", "circle"],
|
|
246
246
|
"params": ["radius"],
|
|
247
|
-
"formula": lambda d:
|
|
247
|
+
"formula": lambda d: math.pi * math.pow(d["radius"], 2)
|
|
248
|
+
},
|
|
249
|
+
"ellipse": {
|
|
250
|
+
"keywords": ["area", "ellipse"],
|
|
251
|
+
"params": ["a", "b"],
|
|
252
|
+
"formula": lambda d: math.pi * d["a"] * d["b"]
|
|
253
|
+
},
|
|
254
|
+
"pentagon": {
|
|
255
|
+
"keywords": ["area", "pentagon"],
|
|
256
|
+
"params": ["side"],
|
|
257
|
+
"formula": lambda d: (1 / 4) * math.sqrt(5 * (5 + 2 * math.sqrt(5))) * math.pow(d["side"], 2)
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
# 3D Shapes – Volume
|
|
261
|
+
"cube": {
|
|
262
|
+
"keywords": ["volume", "cube"],
|
|
263
|
+
"params": ["side"],
|
|
264
|
+
"formula": lambda d: math.pow(d["side"], 3)
|
|
265
|
+
},
|
|
266
|
+
"rectangular prism": {
|
|
267
|
+
"keywords": ["volume", "rectangular prism"],
|
|
268
|
+
"params": ["length", "width", "height"],
|
|
269
|
+
"formula": lambda d: d["length"] * d["width"] * d["height"]
|
|
270
|
+
},
|
|
271
|
+
"cylinder": {
|
|
272
|
+
"keywords": ["volume", "cylinder"],
|
|
273
|
+
"params": ["radius", "height"],
|
|
274
|
+
"formula": lambda d: math.pi * math.pow(d["radius"], 2) * d["height"]
|
|
275
|
+
},
|
|
276
|
+
"cone": {
|
|
277
|
+
"keywords": ["volume", "cone"],
|
|
278
|
+
"params": ["radius", "height"],
|
|
279
|
+
"formula": lambda d: (1 / 3) * math.pi * math.pow(d["radius"], 2) * d["height"]
|
|
280
|
+
},
|
|
281
|
+
"sphere": {
|
|
282
|
+
"keywords": ["volume", "sphere"],
|
|
283
|
+
"params": ["radius"],
|
|
284
|
+
"formula": lambda d: (4 / 3) * math.pi * math.pow(d["radius"], 3)
|
|
285
|
+
},
|
|
286
|
+
"pyramid": {
|
|
287
|
+
"keywords": ["volume", "pyramid"],
|
|
288
|
+
"params": ["base_area", "height"],
|
|
289
|
+
"formula": lambda d: (1 / 3) * d["base_area"] * d["height"]
|
|
248
290
|
}
|
|
249
291
|
}
|
|
250
292
|
|
|
@@ -299,9 +341,9 @@ class DLM:
|
|
|
299
341
|
|
|
300
342
|
Parameters:
|
|
301
343
|
mode (str): The access mode. Options:
|
|
302
|
-
'
|
|
303
|
-
'
|
|
304
|
-
'
|
|
344
|
+
'learn' for training mode (to train the bot with queries),
|
|
345
|
+
'recall' for recalling learned queries (to use it in your deployment/production program),
|
|
346
|
+
'compute' for mathematical queries (for arithmetic or conversion queries).
|
|
305
347
|
db_filename (str): The SQLite database file used to train and retrieve
|
|
306
348
|
question-answer-category triples.
|
|
307
349
|
|
|
@@ -322,26 +364,25 @@ class DLM:
|
|
|
322
364
|
|
|
323
365
|
def __login_verification(self, mode): # no return, void
|
|
324
366
|
"""
|
|
325
|
-
Verify and initialize the selected access mode (
|
|
367
|
+
Verify and initialize the selected access mode (Learn, Recall, or Compute).
|
|
326
368
|
|
|
327
369
|
Parameters:
|
|
328
|
-
mode (str): The access mode. Options
|
|
329
|
-
'
|
|
330
|
-
'
|
|
331
|
-
'
|
|
332
|
-
|
|
370
|
+
mode (str): The access mode. Options:
|
|
371
|
+
'learn' for training mode (to train the bot with queries),
|
|
372
|
+
'recall' for recalling learned queries (to use it in your deployment/production program),
|
|
373
|
+
'compute' for mathematical queries (for arithmetic or conversion queries).
|
|
333
374
|
Behavior:
|
|
334
|
-
- If mode is '
|
|
335
|
-
- If mode is '
|
|
336
|
-
- If mode is '
|
|
375
|
+
- If mode is 'learn', prompts for a password and displays mandatory training instructions.
|
|
376
|
+
- If mode is 'recall', enters deployment mode without training privileges.
|
|
377
|
+
- If mode is 'compute', proceeds with computation model with reasoning capabilities.
|
|
337
378
|
"""
|
|
338
|
-
if mode.lower() == "
|
|
339
|
-
password = input("Enter the password to enter
|
|
379
|
+
if mode.lower() == "learn":
|
|
380
|
+
password = input("Enter the password to enter Learn Mode: ")
|
|
340
381
|
while password != self.__trainingPwd:
|
|
341
382
|
password = input(
|
|
342
|
-
"Password is incorrect, try again or type 'stop' to enter in
|
|
383
|
+
"Password is incorrect, try again or type 'stop' to enter in recall mode instead: ")
|
|
343
384
|
if password.lower() == "stop":
|
|
344
|
-
self.__mode = "
|
|
385
|
+
self.__mode = "recall"
|
|
345
386
|
print("\n")
|
|
346
387
|
break
|
|
347
388
|
if password == self.__trainingPwd:
|
|
@@ -364,14 +405,14 @@ class DLM:
|
|
|
364
405
|
while confirmation.lower() != "y": # trainers must understand the instructions above
|
|
365
406
|
confirmation = input(
|
|
366
407
|
"You cannot proceed to train without understanding the instructions aforementioned. Type 'Y' to continue: ")
|
|
367
|
-
self.__mode = "
|
|
408
|
+
self.__mode = "learn"
|
|
368
409
|
print("\n")
|
|
369
410
|
self.__loadingAnimation("Logging in as Trainer", 0.6)
|
|
370
411
|
print("\n")
|
|
371
|
-
elif mode.lower() == "
|
|
372
|
-
self.__mode = "
|
|
412
|
+
elif mode.lower() == "recall":
|
|
413
|
+
self.__mode = "recall"
|
|
373
414
|
else:
|
|
374
|
-
self.__mode = "
|
|
415
|
+
self.__mode = "compute"
|
|
375
416
|
|
|
376
417
|
def __create_table_if_missing(self): # no return, void
|
|
377
418
|
"""
|
|
@@ -492,7 +533,7 @@ class DLM:
|
|
|
492
533
|
- Tokenizes the input into words.
|
|
493
534
|
- Removes filler words unless:
|
|
494
535
|
- It's the first word and part of the exception list.
|
|
495
|
-
- The current mode is '
|
|
536
|
+
- The current mode is 'compute' and the word is a computation keyword.
|
|
496
537
|
- Preserves word order while removing duplicates.
|
|
497
538
|
- Joins the remaining words back into a single filtered string.
|
|
498
539
|
"""
|
|
@@ -510,12 +551,12 @@ class DLM:
|
|
|
510
551
|
|
|
511
552
|
# otherwise, only keep non-fillers
|
|
512
553
|
else:
|
|
513
|
-
# In
|
|
554
|
+
# In compute mode, keep any computation keyword even if it's also a filler
|
|
514
555
|
is_computation_kw = any(word_lowered == kw.lower()
|
|
515
556
|
for kws in self.__computation_identifiers.values()
|
|
516
557
|
for kw in kws)
|
|
517
558
|
|
|
518
|
-
if word_lowered not in self.__filler_words or (self.__mode == "
|
|
559
|
+
if word_lowered not in self.__filler_words or (self.__mode == "compute" and is_computation_kw):
|
|
519
560
|
filtered_words.append(word)
|
|
520
561
|
|
|
521
562
|
# remove duplicates while preserving order (numbers excluded)
|
|
@@ -571,14 +612,14 @@ class DLM:
|
|
|
571
612
|
|
|
572
613
|
def __geometric_calculation(self, filtered_query, display_thought):
|
|
573
614
|
"""
|
|
574
|
-
Perform
|
|
615
|
+
Perform geometric problems that will be called inside perform_advanced_CoT
|
|
575
616
|
|
|
576
617
|
Parameters:
|
|
577
618
|
filtered_query (str): user query that has been filtered to have mostly computational details
|
|
578
619
|
display_thought (bool): Indicates whether the user wants to have the bot display its thought process or just give the answer
|
|
579
620
|
|
|
580
621
|
Returns:
|
|
581
|
-
float: The result after computing the
|
|
622
|
+
float: The result after computing the geometric calculation
|
|
582
623
|
|
|
583
624
|
Behavior:
|
|
584
625
|
- Search through query to find specific keywords like 'area' or 'volume'
|
|
@@ -591,7 +632,7 @@ class DLM:
|
|
|
591
632
|
height_value_index = None
|
|
592
633
|
other_values = []
|
|
593
634
|
object_intel = []
|
|
594
|
-
common_endings = ["ular", "ish", "al"]
|
|
635
|
+
common_endings = ["ular", "ish", "al"] # some people might say "squarish" or "rectangular" etc
|
|
595
636
|
|
|
596
637
|
tokens = filtered_query.split()
|
|
597
638
|
lower_tokens = [t.lower() for t in tokens]
|
|
@@ -638,47 +679,78 @@ class DLM:
|
|
|
638
679
|
other_values.append(float(token))
|
|
639
680
|
|
|
640
681
|
# find the object name and what to compute about the object
|
|
641
|
-
for
|
|
682
|
+
bigrams = [" ".join([lower_tokens[i], lower_tokens[i + 1]]) for i in range(len(lower_tokens) - 1)]
|
|
683
|
+
end_check = False
|
|
684
|
+
|
|
685
|
+
# first check bi-grams
|
|
686
|
+
for phrase in bigrams:
|
|
642
687
|
for obj in self.__geometric_calculation_identifiers:
|
|
643
|
-
# remove common endings for better matching
|
|
644
688
|
for ending in common_endings:
|
|
645
|
-
if
|
|
646
|
-
|
|
689
|
+
if phrase[0].endswith(ending):
|
|
690
|
+
phrase = phrase[: -len(ending)]
|
|
647
691
|
break
|
|
648
|
-
is_similar = difflib.get_close_matches(
|
|
692
|
+
is_similar = difflib.get_close_matches(phrase, [obj], n=1, cutoff=0.70)
|
|
649
693
|
if is_similar and is_similar[0] == obj:
|
|
650
694
|
object_intel.extend(self.__geometric_calculation_identifiers[obj]["keywords"])
|
|
695
|
+
end_check = True
|
|
696
|
+
break
|
|
697
|
+
if end_check:
|
|
698
|
+
break
|
|
699
|
+
|
|
700
|
+
# if no bi-gram match, check single words
|
|
701
|
+
if not end_check and not lower_tokens.__contains__("prism"):
|
|
702
|
+
for token in lower_tokens:
|
|
703
|
+
for obj in self.__geometric_calculation_identifiers:
|
|
704
|
+
for ending in common_endings:
|
|
705
|
+
if token.endswith(ending):
|
|
706
|
+
token = token[: -len(ending)]
|
|
707
|
+
break
|
|
708
|
+
is_similar = difflib.get_close_matches(token, [obj], n=1, cutoff=0.80)
|
|
709
|
+
if is_similar and is_similar[0] == obj:
|
|
710
|
+
object_intel.extend(self.__geometric_calculation_identifiers[obj]["keywords"])
|
|
711
|
+
end_check = True
|
|
712
|
+
break
|
|
713
|
+
if end_check:
|
|
714
|
+
break
|
|
651
715
|
|
|
716
|
+
# if allowed, display the inner thought process
|
|
652
717
|
obj_name = object_intel[1]
|
|
653
718
|
if display_thought:
|
|
654
719
|
self.__loadingAnimation(f"It seems that the user wants to compute the {' of a '.join(object_intel)}", 0.5)
|
|
655
720
|
if height_value is not None:
|
|
656
|
-
self.__loadingAnimation(
|
|
721
|
+
self.__loadingAnimation(
|
|
722
|
+
f"* The user has mentioned that the height of the {obj_name} object is {height_value}", 0.4)
|
|
657
723
|
else:
|
|
658
|
-
self.__loadingAnimation(
|
|
724
|
+
self.__loadingAnimation(
|
|
725
|
+
f"* The {object_intel[1]} object has no height associated with it, so moving on", 0.4)
|
|
659
726
|
if len(other_values) > 0:
|
|
660
|
-
self.__loadingAnimation(
|
|
727
|
+
self.__loadingAnimation(
|
|
728
|
+
f"* Additional numerical values associated with the dimensions of the {obj_name} object is {' and '.join(str(v) for v in other_values)}",
|
|
729
|
+
0.4)
|
|
661
730
|
else:
|
|
662
|
-
self.__loadingAnimation(
|
|
731
|
+
self.__loadingAnimation(
|
|
732
|
+
f"* No additional numerical values associated with the dimensions of the {obj_name} were given",
|
|
733
|
+
0.4)
|
|
663
734
|
|
|
664
735
|
# Now iterate through the geometric identifier list, find the correct object, and then find its formula, then plug compute
|
|
665
736
|
formula = self.__geometric_calculation_identifiers[obj_name]["formula"]
|
|
666
737
|
params = self.__geometric_calculation_identifiers[obj_name]["params"]
|
|
667
738
|
|
|
668
|
-
formula_inputs = {}
|
|
739
|
+
formula_inputs = {} # all data gathered to compute geometry
|
|
669
740
|
|
|
741
|
+
# gather and plug in values into the formula
|
|
670
742
|
try:
|
|
671
743
|
if "height" in params:
|
|
672
744
|
formula_inputs["height"] = height_value
|
|
673
745
|
|
|
674
|
-
value_idx = 0
|
|
746
|
+
value_idx = 0 # count how many values to be added in formula_inputs
|
|
675
747
|
for param in params:
|
|
676
748
|
if param == "height":
|
|
677
749
|
continue # already added
|
|
678
|
-
elif param == "other":
|
|
750
|
+
elif param == "other": # two consecutive numbers to append
|
|
679
751
|
formula_inputs["other"] = other_values[value_idx:value_idx + 2]
|
|
680
752
|
value_idx += 2
|
|
681
|
-
else:
|
|
753
|
+
else: # only one number to append
|
|
682
754
|
formula_inputs[param] = other_values[value_idx]
|
|
683
755
|
value_idx += 1
|
|
684
756
|
|
|
@@ -688,12 +760,13 @@ class DLM:
|
|
|
688
760
|
|
|
689
761
|
except Exception as e:
|
|
690
762
|
if display_thought:
|
|
691
|
-
print(
|
|
763
|
+
print(
|
|
764
|
+
f"{'\033[33m'}Unable to compute the {object_intel[0]} of the {obj_name} due to missing or mismatched values{'\033[0m'}")
|
|
692
765
|
else:
|
|
693
|
-
print(
|
|
766
|
+
print(
|
|
767
|
+
f"{'\033[34m'}Unable to compute the {object_intel[0]} of the {obj_name} due to missing or mismatched values{'\033[0m'}")
|
|
694
768
|
return None
|
|
695
769
|
|
|
696
|
-
|
|
697
770
|
def __perform_advanced_CoT(self, filtered_query, display_thought): # no return, void
|
|
698
771
|
"""
|
|
699
772
|
Perform advanced Chain-of-Thought (CoT) reasoning to solve arithmetic or unit conversion problems.
|
|
@@ -730,7 +803,8 @@ class DLM:
|
|
|
730
803
|
print(
|
|
731
804
|
f"{'\033[33m'}I am presented with a more involved query asking me to do some form of computation{'\033[0m'}")
|
|
732
805
|
self.__loadingAnimation("Let me think about this carefully and break it down so that I can solve it", 0.8)
|
|
733
|
-
self.__loadingAnimation(f"I’ve trimmed away any extra words so I’m focusing on \"{filtered_query}\" now",
|
|
806
|
+
self.__loadingAnimation(f"I’ve trimmed away any extra words so I’m focusing on \"{filtered_query}\" now",
|
|
807
|
+
0.8)
|
|
734
808
|
|
|
735
809
|
# Have the bot pick out names mentioned (in order) using SpaCy and NLTK (for maximum coverage)
|
|
736
810
|
for ent in doc.ents:
|
|
@@ -762,10 +836,12 @@ class DLM:
|
|
|
762
836
|
words = filtered_query.lower().split()
|
|
763
837
|
geometric_ans = None
|
|
764
838
|
# checks if the query contains shapes or object to perform possibly formula calculation
|
|
765
|
-
geometric_calc = any(
|
|
839
|
+
geometric_calc = any(
|
|
840
|
+
difflib.get_close_matches(word, self.__geometric_calculation_identifiers.keys(), n=1, cutoff=0.70) for word
|
|
841
|
+
in words)
|
|
766
842
|
is_geometric_query = False
|
|
767
843
|
|
|
768
|
-
geo_types = set()
|
|
844
|
+
geo_types = set() # currently supported types of geometric calculations
|
|
769
845
|
|
|
770
846
|
for t in self.__geometric_calculation_identifiers:
|
|
771
847
|
shape = self.__geometric_calculation_identifiers[t]["keywords"]
|
|
@@ -774,7 +850,7 @@ class DLM:
|
|
|
774
850
|
geometric_ans = self.__geometric_calculation(filtered_query, display_thought)
|
|
775
851
|
if geometric_ans is not None:
|
|
776
852
|
is_geometric_query = True
|
|
777
|
-
else:
|
|
853
|
+
else: # Not geometric, so have the bot find all operand indicating keywords
|
|
778
854
|
found_operand = False
|
|
779
855
|
for fq in filtered_query.split():
|
|
780
856
|
fq_l = fq.lower()
|
|
@@ -924,22 +1000,33 @@ class DLM:
|
|
|
924
1000
|
operands_mentioned = [op for op in operands_mentioned if op != '=']
|
|
925
1001
|
|
|
926
1002
|
# verify and possibly print thoughts
|
|
927
|
-
if (not is_geometric_query) and (any(not lst for lst in (num_mentioned, operands_mentioned)) or (
|
|
928
|
-
|
|
929
|
-
print(
|
|
930
|
-
|
|
1003
|
+
if (not is_geometric_query) and (any(not lst for lst in (num_mentioned, operands_mentioned)) or (
|
|
1004
|
+
'=' not in operands_mentioned and num_mentioned.__len__() < 2)): # don't compute if parts are missing
|
|
1005
|
+
print(
|
|
1006
|
+
f"{self.__loadingAnimation('Hmm', 0.8) or '' if display_thought else ''}{'\033[34m'}It looks like some essential details are missing, so I can’t complete this calculation right now.{'\033[0m'}")
|
|
1007
|
+
print(
|
|
1008
|
+
f"\033[34mIf you are asking a geometric query, try including geometric identifiers like \"{'\", \"'.join(geo_types)}\" in your query.\033[0m")
|
|
1009
|
+
print(
|
|
1010
|
+
f"\033[34mCurrently, I can only compute those identifiers aforementioned, but more geometric features are coming soon!\033[0m")
|
|
931
1011
|
else: # else, the bot needs to explain what it has tokenized
|
|
932
1012
|
if display_thought:
|
|
933
|
-
self.__loadingAnimation(
|
|
1013
|
+
self.__loadingAnimation(
|
|
1014
|
+
f"1.) I see {', '.join(persons_mentioned) if persons_mentioned.__len__() >= 1 else 'no one'} mentioned as a person name; "
|
|
934
1015
|
f"{'they’re likely key to this problem' if persons_mentioned.__len__() >= 1 else 'moving on'}", 0.2)
|
|
935
|
-
self.__loadingAnimation(
|
|
1016
|
+
self.__loadingAnimation(
|
|
1017
|
+
f"2.) Moreover, I see {', '.join(items_mentioned) if items_mentioned.__len__() >= 1 else 'no items'} mentioned as proper nouns; "
|
|
936
1018
|
f"{'this might be a key thing to this problem' if items_mentioned.__len__() >= 1 else 'moving on'}",
|
|
937
1019
|
0.2)
|
|
938
1020
|
if is_geometric_query:
|
|
939
|
-
self.__loadingAnimation(f"3.) This is a geometric problem and I have already computed the answer",
|
|
1021
|
+
self.__loadingAnimation(f"3.) This is a geometric problem and I have already computed the answer",
|
|
1022
|
+
0.2)
|
|
940
1023
|
else:
|
|
941
|
-
self.__loadingAnimation(
|
|
942
|
-
|
|
1024
|
+
self.__loadingAnimation(
|
|
1025
|
+
f"3.) I’ve also identified the numbers {' and '.join(num_mentioned)} that I need to compute with",
|
|
1026
|
+
0.2)
|
|
1027
|
+
self.__loadingAnimation(
|
|
1028
|
+
f"4.) I see the keywords \"{'\" and \"'.join(keywords_mentioned)}\", meaning I need to perform a \"{'\" and \"'.join(operands_mentioned)}\" operation for this query; I’ll use that to guide my calculation",
|
|
1029
|
+
0.2)
|
|
943
1030
|
self.__loadingAnimation("Now I have the parts, so let me put it all together and solve", 0.3)
|
|
944
1031
|
|
|
945
1032
|
# Finally compute it and then give the response (if there is any)
|
|
@@ -1104,7 +1191,7 @@ class DLM:
|
|
|
1104
1191
|
|
|
1105
1192
|
Behavior:
|
|
1106
1193
|
- Outputs step-by-step reasoning in a conversational format (e.g., interpreting the question's structure and tone).
|
|
1107
|
-
- In
|
|
1194
|
+
- In compute mode, calls advanced reasoning (e.g., math parsing or CoT decomposition).
|
|
1108
1195
|
- Identifies the question's tone, topic, and potential intent based on interrogative words and SpaCy similarity.
|
|
1109
1196
|
- Displays confidence based on similarity metrics and sets flags for uncertain answers.
|
|
1110
1197
|
- Uses colorized terminal output and a loading animation to simulate reflective thought.
|
|
@@ -1120,7 +1207,7 @@ class DLM:
|
|
|
1120
1207
|
if self.__tone != "":
|
|
1121
1208
|
print(
|
|
1122
1209
|
f"{'\033[33m'}Right off the bat, the user seems quite {sentiment_tone[0]} or {sentiment_tone[1]} by their query tone. Hopefully I won't disappoint!{'\033[0m'}")
|
|
1123
|
-
if self.__mode == "
|
|
1210
|
+
if self.__mode == "compute":
|
|
1124
1211
|
self.__perform_advanced_CoT(filtered_query, display_thought)
|
|
1125
1212
|
else:
|
|
1126
1213
|
interrogative_start = filtered_query.split()[0]
|
|
@@ -1175,7 +1262,7 @@ class DLM:
|
|
|
1175
1262
|
f"Additionally, doing a more in-depth vector NLP analysis resulted in {int(self.__nlp_similarity_value * 100)}% similarity. Although there are room for error, we will see.{'\033[0m'}")
|
|
1176
1263
|
self.__loadingAnimation("Let me recall that answer", 0.8)
|
|
1177
1264
|
print("\n")
|
|
1178
|
-
elif self.__mode == "
|
|
1265
|
+
elif self.__mode == "compute":
|
|
1179
1266
|
self.__perform_advanced_CoT(filtered_query, display_thought)
|
|
1180
1267
|
|
|
1181
1268
|
def __generate_response(self, best_match_answer, best_match_question): # no return, void
|
|
@@ -1458,8 +1545,8 @@ class DLM:
|
|
|
1458
1545
|
- Detects tone, filters input, searches knowledge base.
|
|
1459
1546
|
- Performs Chain-of-Thought (CoT) while recalling learnt answer.
|
|
1460
1547
|
- If match is found, generates a response.
|
|
1461
|
-
- If in
|
|
1462
|
-
- In
|
|
1548
|
+
- If in learning mode and answer is incorrect or not found, prompts user to teach the bot.
|
|
1549
|
+
- In compute mode, performs reasoning or arithmetic without using database.
|
|
1463
1550
|
"""
|
|
1464
1551
|
self.__query = query
|
|
1465
1552
|
while self.__query is None or self.__query == "":
|
|
@@ -1468,7 +1555,7 @@ class DLM:
|
|
|
1468
1555
|
self.__set_sentiment_tone(self.__query) # sets global variable sentiment tone
|
|
1469
1556
|
|
|
1470
1557
|
# storing the user-query (filtered, lower-case, no punctuation)
|
|
1471
|
-
if self.__mode == "
|
|
1558
|
+
if self.__mode == "compute":
|
|
1472
1559
|
# We want to keep the following
|
|
1473
1560
|
keep = {".", "+", "-", "*", "/", "="}
|
|
1474
1561
|
to_remove = "".join(ch for ch in string.punctuation if ch not in keep)
|
|
@@ -1516,13 +1603,13 @@ class DLM:
|
|
|
1516
1603
|
display_thought)
|
|
1517
1604
|
|
|
1518
1605
|
# accept a match if highest_similarity is 65% or more, or if semantic similarity is recognized
|
|
1519
|
-
if self.__mode != "
|
|
1606
|
+
if self.__mode != "compute":
|
|
1520
1607
|
if (not self.__unsure_while_thinking) and ((highest_similarity >= 0.65) or (
|
|
1521
1608
|
best_match_answer and self.__semantic_similarity(self.__special_stripped_query,
|
|
1522
1609
|
best_match_question))):
|
|
1523
1610
|
self.__unsure_while_thinking = False # reset this back to default for next iteration
|
|
1524
1611
|
self.__generate_response(best_match_answer, best_match_question)
|
|
1525
|
-
if self.__mode == "
|
|
1612
|
+
if self.__mode == "learn":
|
|
1526
1613
|
self.__expectation = input("Is this what you expected (Y/N): ")
|
|
1527
1614
|
|
|
1528
1615
|
while not self.__expectation: # if nothing entered, ask until question answered
|
|
@@ -1535,7 +1622,7 @@ class DLM:
|
|
|
1535
1622
|
return
|
|
1536
1623
|
|
|
1537
1624
|
# only executes if training option is TRUE
|
|
1538
|
-
if self.__mode == "
|
|
1625
|
+
if self.__mode == "learn":
|
|
1539
1626
|
self.__expectation = input(
|
|
1540
1627
|
"I'm not sure. Train me with the expected response: ") # train DLM with answer
|
|
1541
1628
|
while not self.__expectation:
|
|
@@ -1553,5 +1640,5 @@ class DLM:
|
|
|
1553
1640
|
self.__learn(self.__expectation,
|
|
1554
1641
|
self.__category) # learn this new question and answer pair and add to knowledgebase
|
|
1555
1642
|
print("I learned something new!") # confirmation that it went through the whole process
|
|
1556
|
-
else: # only executes when in
|
|
1643
|
+
else: # only executes when in recall mode and bot cannot find the answer
|
|
1557
1644
|
print(f"{'\033[34m'}{random.choice(self.__fallback_responses)}{'\033[0m'}")
|
{dynamic_learning_model-1.3.1 → dynamic_learning_model-1.5/dynamic_learning_model.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dynamic-learning-model
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5
|
|
4
4
|
Summary: A Dynamic Learning Model for processing NLP queries using hybrid AI and reasoning.
|
|
5
5
|
Home-page: https://github.com/VigneshT24/Dynamic_Learning_Model
|
|
6
6
|
Author: Vignesh Thondikulam
|
|
@@ -5,7 +5,7 @@ with open('README.md', 'r', encoding='utf-8') as f:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name='dynamic-learning-model',
|
|
8
|
-
version='1.
|
|
8
|
+
version='1.5',
|
|
9
9
|
author='Vignesh Thondikulam',
|
|
10
10
|
author_email='vignesh.tho2006@gmail.com',
|
|
11
11
|
description='A Dynamic Learning Model for processing NLP queries using hybrid AI and reasoning.',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|