dynamic-learning-model 1.1__tar.gz → 1.2__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.1/dynamic_learning_model.egg-info → dynamic_learning_model-1.2}/PKG-INFO +1 -1
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/dlm/DLM.py +108 -90
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2/dynamic_learning_model.egg-info}/PKG-INFO +1 -1
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/setup.py +1 -1
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/LICENSE +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/README.md +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/dlm/__init__.py +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/dynamic_learning_model.egg-info/SOURCES.txt +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/dynamic_learning_model.egg-info/dependency_links.txt +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/dynamic_learning_model.egg-info/requires.txt +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/dynamic_learning_model.egg-info/top_level.txt +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/pyproject.toml +0 -0
- {dynamic_learning_model-1.1 → dynamic_learning_model-1.2}/setup.cfg +0 -0
{dynamic_learning_model-1.1/dynamic_learning_model.egg-info → dynamic_learning_model-1.2}/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.2
|
|
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
|
|
@@ -264,9 +264,9 @@ class DLM:
|
|
|
264
264
|
|
|
265
265
|
Parameters:
|
|
266
266
|
mode (str): The access mode. Options:
|
|
267
|
-
't' for Training mode,
|
|
268
|
-
'c' for Commercial mode,
|
|
269
|
-
'e' for Experimental mode.
|
|
267
|
+
't' for Training mode (to train the bot with queries),
|
|
268
|
+
'c' for Commercial mode (to use it in your deployment/production program),
|
|
269
|
+
'e' for Experimental mode (for arithmetic or conversion queries).
|
|
270
270
|
db_filename (str): The SQLite database file used to train and retrieve
|
|
271
271
|
question-answer-category triples.
|
|
272
272
|
|
|
@@ -308,8 +308,6 @@ class DLM:
|
|
|
308
308
|
if password.lower() == "stop":
|
|
309
309
|
self.__mode = "commercial"
|
|
310
310
|
print("\n")
|
|
311
|
-
self.__loadingAnimation("Logging in as Commercial User", 0.6)
|
|
312
|
-
print("\n")
|
|
313
311
|
break
|
|
314
312
|
if password == self.__trainingPwd:
|
|
315
313
|
# trainers must understand these rules as DLM can generate bad responses if these instructions are neglected
|
|
@@ -337,12 +335,8 @@ class DLM:
|
|
|
337
335
|
print("\n")
|
|
338
336
|
elif mode.lower() == "c":
|
|
339
337
|
self.__mode = "commercial"
|
|
340
|
-
self.__loadingAnimation("Logging in as Commercial User", 0.6)
|
|
341
|
-
print("Ask Non-Computational Queries (switch to experimental for computational queries)")
|
|
342
338
|
else:
|
|
343
339
|
self.__mode = "experimental"
|
|
344
|
-
self.__loadingAnimation("Logging in as Experimental", 0.6)
|
|
345
|
-
print("Ask Computational Problems (Arithmetics or Conversions)")
|
|
346
340
|
|
|
347
341
|
def __create_table_if_missing(self): # no return, void
|
|
348
342
|
"""
|
|
@@ -538,12 +532,13 @@ class DLM:
|
|
|
538
532
|
else:
|
|
539
533
|
self.__tone = ""
|
|
540
534
|
|
|
541
|
-
def __perform_advanced_CoT(self, filtered_query): # no return, void
|
|
535
|
+
def __perform_advanced_CoT(self, filtered_query, display_thought): # no return, void
|
|
542
536
|
"""
|
|
543
537
|
Perform advanced Chain-of-Thought (CoT) reasoning to solve arithmetic or unit conversion problems.
|
|
544
538
|
|
|
545
539
|
Parameters:
|
|
546
540
|
filtered_query (str): The cleaned user input, expected to be a math- or logic-based question.
|
|
541
|
+
display_thought (bool): Indicates whether the user wants to have the bot display its thought process or just give the answer
|
|
547
542
|
|
|
548
543
|
Behavior:
|
|
549
544
|
- Simulates step-by-step reasoning to solve arithmetic word problems without relying on memorized answers.
|
|
@@ -551,14 +546,9 @@ class DLM:
|
|
|
551
546
|
- Detects arithmetic operations via lexical and semantic matching with predefined keyword sets.
|
|
552
547
|
- Handles both numeric digits and text-based numbers (e.g., "three", "double").
|
|
553
548
|
- Supports simple arithmetic expressions and unit conversions (e.g., inches to cm).
|
|
554
|
-
- Prints the interpreted steps, logical inferences, and the final computed result with contextual explanations.
|
|
549
|
+
- Prints the interpreted steps, logical inferences (if display_thought is True), and the final computed result with contextual explanations.
|
|
555
550
|
- Displays fallback messages if the query is incomplete or too ambiguous to solve.
|
|
556
551
|
"""
|
|
557
|
-
print(
|
|
558
|
-
f"{'\033[33m'}I am presented with a more involved query asking me to do some form of computation{'\033[0m'}")
|
|
559
|
-
self.__loadingAnimation("Let me think about this carefully and break it down so that I can solve it", 0.8)
|
|
560
|
-
self.__loadingAnimation(
|
|
561
|
-
f"I’ve trimmed away any extra words so I’m focusing on \"{filtered_query.title()}\" now", 0.8)
|
|
562
552
|
persons_mentioned = []
|
|
563
553
|
items_mentioned = []
|
|
564
554
|
keywords_mentioned = []
|
|
@@ -574,6 +564,13 @@ class DLM:
|
|
|
574
564
|
filtered_query = filtered_query.title()
|
|
575
565
|
doc = self.__nlp(filtered_query)
|
|
576
566
|
|
|
567
|
+
if display_thought:
|
|
568
|
+
print(
|
|
569
|
+
f"{'\033[33m'}I am presented with a more involved query asking me to do some form of computation{'\033[0m'}")
|
|
570
|
+
self.__loadingAnimation("Let me think about this carefully and break it down so that I can solve it", 0.8)
|
|
571
|
+
self.__loadingAnimation(f"I’ve trimmed away any extra words so I’m focusing on \"{filtered_query}\" now",
|
|
572
|
+
0.8)
|
|
573
|
+
|
|
577
574
|
# Have the bot pick out names mentioned (in order) using SpaCy and NLTK (for maximum coverage)
|
|
578
575
|
for ent in doc.ents:
|
|
579
576
|
if ent.label_ == "PERSON":
|
|
@@ -755,21 +752,23 @@ class DLM:
|
|
|
755
752
|
print(
|
|
756
753
|
f"{self.__loadingAnimation('Hmm', 0.8) or ''}{'\033[34m'}It looks like some essential details are missing, so I can’t complete this calculation right now.{'\033[0m'}")
|
|
757
754
|
else: # else, the bot needs to explain what it has tokenized
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
755
|
+
if display_thought:
|
|
756
|
+
self.__loadingAnimation(
|
|
757
|
+
f"1.) I see {', '.join(persons_mentioned) if persons_mentioned.__len__() >= 1 else 'no one'} mentioned as a person name; "
|
|
758
|
+
f"{'they’re likely key to this problem' if persons_mentioned.__len__() >= 1 else 'moving on'}", 0.2)
|
|
759
|
+
self.__loadingAnimation(
|
|
760
|
+
f"2.) Moreover, I see {', '.join(items_mentioned) if items_mentioned.__len__() >= 1 else 'no items'} mentioned as proper nouns; "
|
|
761
|
+
f"{'this might be a key thing to this problem' if items_mentioned.__len__() >= 1 else 'moving on'}",
|
|
762
|
+
0.2)
|
|
763
|
+
self.__loadingAnimation(
|
|
764
|
+
f"3.) I’ve also identified the numbers {' and '.join(num_mentioned)} that I need to compute with",
|
|
765
|
+
0.2)
|
|
766
|
+
self.__loadingAnimation(
|
|
767
|
+
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",
|
|
768
|
+
0.2)
|
|
769
|
+
self.__loadingAnimation("Now I have the parts, so let me put it all together and solve", 0.3)
|
|
772
770
|
|
|
771
|
+
# Finally compute it and then give the response (if there is any)
|
|
773
772
|
# move "originally" numbers to the front
|
|
774
773
|
indicators = {"original", "originally", "initial", "initially", "at first", "to begin with", "had",
|
|
775
774
|
"savings", "saving", "of"}
|
|
@@ -873,9 +872,10 @@ class DLM:
|
|
|
873
872
|
# 4) Compute only if we have both source_key and target_key
|
|
874
873
|
if source_key and target_key:
|
|
875
874
|
result = (num0 * self.__units[source_key]) / self.__units[target_key]
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
875
|
+
if display_thought:
|
|
876
|
+
self.__loadingAnimation(
|
|
877
|
+
f"I need to take {num0} and multiply it by {self.__units[source_key]}. Finally, I divide by {self.__units[target_key]} and I got my answer",
|
|
878
|
+
0.2)
|
|
879
879
|
expr = f"{num_mentioned[0]} {source_key}(s) ==> {round(result, 2)} {target_key}(s)"
|
|
880
880
|
print(f"{'\033[34m'}Conversion Answer: {expr} {'\033[0m'}")
|
|
881
881
|
else:
|
|
@@ -913,8 +913,8 @@ class DLM:
|
|
|
913
913
|
print(
|
|
914
914
|
f"{'\033[34m'}That might've confused me a bit, maybe try leaving one of those out or rephrase it to make it clearer?{'\033[0m'}")
|
|
915
915
|
|
|
916
|
-
def __generate_thought(self, filtered_query, best_match_question, best_match_answer,
|
|
917
|
-
|
|
916
|
+
def __generate_thought(self, filtered_query, best_match_question, best_match_answer, highest_similarity,
|
|
917
|
+
display_thought): # no return, void
|
|
918
918
|
"""
|
|
919
919
|
Simulate a Chain-of-Thought (CoT) reasoning process by printing the bot's internal analysis.
|
|
920
920
|
|
|
@@ -923,6 +923,7 @@ class DLM:
|
|
|
923
923
|
best_match_question (str): The closest matching question found in the knowledge base.
|
|
924
924
|
best_match_answer (str): The corresponding answer to the matched question.
|
|
925
925
|
highest_similarity (float): The calculated string similarity score (0 to 1) for the match.
|
|
926
|
+
display_thought (bool): "True" if the bot is allowed to print its thought or else "False"
|
|
926
927
|
|
|
927
928
|
Behavior:
|
|
928
929
|
- Outputs step-by-step reasoning in a conversational format (e.g., interpreting the question's structure and tone).
|
|
@@ -931,63 +932,74 @@ class DLM:
|
|
|
931
932
|
- Displays confidence based on similarity metrics and sets flags for uncertain answers.
|
|
932
933
|
- Uses colorized terminal output and a loading animation to simulate reflective thought.
|
|
933
934
|
"""
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
f"{'\033[33m'}I couldn't pick out any context or clear topic. If I see a match in my database I will respond with that, or else I have no clue!{'\033[0m'}")
|
|
938
|
-
else:
|
|
939
|
-
sentiment_tone = self.__tone.split()
|
|
940
|
-
|
|
941
|
-
if self.__tone != "":
|
|
935
|
+
if display_thought:
|
|
936
|
+
print("\nThought Process (Yellow):")
|
|
937
|
+
if filtered_query is None or filtered_query == "":
|
|
942
938
|
print(
|
|
943
|
-
f"{'\033[33m'}
|
|
944
|
-
if self.__mode == "experimental":
|
|
945
|
-
self.__perform_advanced_CoT(filtered_query)
|
|
939
|
+
f"{'\033[33m'}I couldn't pick out any context or clear topic. If I see a match in my database I will respond with that, or else I have no clue!{'\033[0m'}")
|
|
946
940
|
else:
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
"meaning"] # special word in different form
|
|
951
|
-
for word in special_start:
|
|
952
|
-
identifier = identifier.replace(word, "")
|
|
953
|
-
# collapse any extra spaces
|
|
954
|
-
identifier = " ".join(identifier.split())
|
|
955
|
-
identifier = identifier.split()
|
|
956
|
-
|
|
957
|
-
if " ".join(identifier) == "":
|
|
941
|
+
sentiment_tone = self.__tone.split()
|
|
942
|
+
|
|
943
|
+
if self.__tone != "":
|
|
958
944
|
print(
|
|
959
|
-
f"{'\033[33m'}
|
|
945
|
+
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'}")
|
|
946
|
+
if self.__mode == "experimental":
|
|
947
|
+
self.__perform_advanced_CoT(filtered_query, display_thought)
|
|
960
948
|
else:
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
for
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
949
|
+
interrogative_start = filtered_query.split()[0]
|
|
950
|
+
identifier = filtered_query
|
|
951
|
+
special_start = ["definition", "explanation", "description", "comparison", "calculation",
|
|
952
|
+
"translation",
|
|
953
|
+
"meaning"] # special word in different form
|
|
954
|
+
for word in special_start:
|
|
955
|
+
identifier = identifier.replace(word, "")
|
|
956
|
+
# collapse any extra spaces
|
|
957
|
+
identifier = " ".join(identifier.split())
|
|
958
|
+
identifier = identifier.split()
|
|
959
|
+
|
|
960
|
+
if " ".join(identifier) == "":
|
|
961
|
+
print(
|
|
962
|
+
f"{'\033[33m'}The user starts their query with \"{interrogative_start.title()}\", but I couldn't pick out a clear topic or context.{'\033[0m'}")
|
|
963
|
+
else:
|
|
964
|
+
print(
|
|
965
|
+
f"{'\033[33m'}The user starts their query with \"{interrogative_start.title()}\" and they are asking about \"{" ".join(identifier).title()}\".{'\033[0m'}")
|
|
966
|
+
self.__loadingAnimation("Let me think about this carefully", 0.8)
|
|
967
|
+
|
|
968
|
+
for s in special_start:
|
|
969
|
+
for u in filtered_query.split():
|
|
970
|
+
s_input = self.__nlp(s)
|
|
971
|
+
u_input = self.__nlp(u)
|
|
972
|
+
if (s_input.vector_norm != 0 and u_input.vector_norm != 0) and (
|
|
973
|
+
s_input.similarity(u_input) > 0.60):
|
|
974
|
+
print(
|
|
975
|
+
f"{'\033[33m'}It seems like they want a {s} of \"{" ".join(identifier).title()}\".{'\033[0m'}")
|
|
976
|
+
|
|
977
|
+
self.__semantic_similarity(self.__special_stripped_query, best_match_question)
|
|
978
|
+
spacy_proceed = self.__nlp_similarity_value is not None
|
|
979
|
+
if (best_match_answer is None) or (
|
|
980
|
+
highest_similarity < 0.65 and (spacy_proceed and self.__nlp_similarity_value < 0.85)):
|
|
981
|
+
print(
|
|
982
|
+
f"{'\033[33m'}The closest match is only {int(highest_similarity * 100)}% similar when I used sequence matching.{'\033[0m'}")
|
|
983
|
+
if spacy_proceed:
|
|
971
984
|
print(
|
|
972
|
-
f"{'\033[33m'}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
print(
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
print("\n")
|
|
985
|
+
f"{'\033[33m'}Furthermore, an in-depth vector analysis revealed a similarity percentage of {int(self.__nlp_similarity_value * 100)}%.{'\033[0m'}")
|
|
986
|
+
print(
|
|
987
|
+
f"{self.__loadingAnimation("Hmm", 0.8) or ''}{'\033[33m'}I don't think I know the answer, so I am going to let the user know that.{'\033[0m'}")
|
|
988
|
+
self.__unsure_while_thinking = True
|
|
989
|
+
else:
|
|
990
|
+
self.__unsure_while_thinking = False
|
|
991
|
+
DB_identifier = self.__get_specific_question(best_match_answer)
|
|
992
|
+
print(
|
|
993
|
+
f"{'\033[33m'}Yes! I do remember learning about \"{DB_identifier}\" and I might have the right answer!")
|
|
994
|
+
print(
|
|
995
|
+
f"This is because when I did a sequence similarity calculation to one of the closest match in my database, I found it to be {int(highest_similarity * 100)}% similar.")
|
|
996
|
+
if spacy_proceed:
|
|
997
|
+
print(
|
|
998
|
+
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'}")
|
|
999
|
+
self.__loadingAnimation("Let me recall that answer", 0.8)
|
|
1000
|
+
print("\n")
|
|
1001
|
+
elif self.__mode == "experimental":
|
|
1002
|
+
self.__perform_advanced_CoT(filtered_query, display_thought)
|
|
991
1003
|
|
|
992
1004
|
def __generate_response(self, best_match_answer, best_match_question): # no return, void
|
|
993
1005
|
"""
|
|
@@ -1254,10 +1266,15 @@ class DLM:
|
|
|
1254
1266
|
conn.commit()
|
|
1255
1267
|
conn.close()
|
|
1256
1268
|
|
|
1257
|
-
def ask(self, query): # no return, void
|
|
1269
|
+
def ask(self, query, display_thought): # no return, void
|
|
1258
1270
|
"""
|
|
1259
1271
|
Handle a full user interaction loop with the DLM bot.
|
|
1260
|
-
|
|
1272
|
+
|
|
1273
|
+
NOTICE: To make the bot run continuously, implement a loop in your program.
|
|
1274
|
+
|
|
1275
|
+
Parameters:
|
|
1276
|
+
query (str): Question the bot would answer, compute, or learn
|
|
1277
|
+
display_thought (bool): "True" for allowing bot to print its thought and CoT or "False"
|
|
1261
1278
|
|
|
1262
1279
|
Behavior:
|
|
1263
1280
|
- Prompts the user for input.
|
|
@@ -1318,7 +1335,8 @@ class DLM:
|
|
|
1318
1335
|
best_match_answer = stored_answer
|
|
1319
1336
|
|
|
1320
1337
|
# "Chain of Thought" (CoT) Feature
|
|
1321
|
-
self.__generate_thought(filtered_query, best_match_question, best_match_answer, highest_similarity
|
|
1338
|
+
self.__generate_thought(filtered_query, best_match_question, best_match_answer, highest_similarity,
|
|
1339
|
+
display_thought)
|
|
1322
1340
|
|
|
1323
1341
|
# accept a match if highest_similarity is 65% or more, or if semantic similarity is recognized
|
|
1324
1342
|
if self.__mode != "experimental":
|
{dynamic_learning_model-1.1 → dynamic_learning_model-1.2/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.2
|
|
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.2',
|
|
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
|