-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9ee8025
Showing
10 changed files
with
1,246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
|
||
# E-Commerce Chatbot README | ||
|
||
This repository contains code for a simple chatbot implemented in Python using TensorFlow and NLTK. | ||
|
||
## Overview | ||
|
||
The chatbot is trained to understand and respond to user queries based on predefined intents. It uses a bag-of-words approach to encode input sentences and a neural network for classification. | ||
|
||
## Requirements | ||
|
||
- Python 3.9.7 | ||
- TensorFlow | ||
- NLTK (Natural Language Toolkit) | ||
|
||
|
||
2. Install dependencies: | ||
|
||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
|
||
## Usage | ||
|
||
1. Train the model: | ||
|
||
```bash | ||
python ecomChatbot.py | ||
``` | ||
|
||
2. Run with the chatbot: | ||
|
||
```bash | ||
streamlit run chatbotApp.py | ||
``` | ||
|
||
## Files | ||
|
||
- `intents.json`: Contains predefined intents and responses. | ||
- `ecomChatbot.py`: Script to train the chatbot model. | ||
- `chatbotApp.py`: Script to interact with the trained chatbot. with streamlit GUI. | ||
- `chatbot_model.h5`: Trained model file. | ||
- `words.pkl` and `classes.pkl`: Pickled files containing words and classes used for training. | ||
|
||
## How it Works | ||
|
||
1. **Data Preprocessing**: Intents are loaded from `intents.json`, tokenized, lemmatized, and converted into a bag-of-words format. | ||
2. **Model Training**: A neural network model is defined and trained on the processed data. | ||
3. **Prediction**: Input sentences are tokenized and converted into bag-of-words vectors, and the model predicts the intent. | ||
4. **Response Generation**: Based on the predicted intent, a response is randomly chosen from the predefined responses in `intents.json`. | ||
|
||
## Customization | ||
|
||
- Modify `intents.json` to add or edit intents and responses. | ||
- Tweak model architecture and parameters in `train_chatbot.py` for better performance. | ||
- Extend functionalities by adding more functions in `chatbot.py`. | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import streamlit as st | ||
import nltk | ||
from nltk.stem import WordNetLemmatizer | ||
import json | ||
import pickle | ||
import numpy as np | ||
from keras.models import load_model | ||
|
||
# Load necessary resources | ||
lemmatizer = WordNetLemmatizer() | ||
nltk.download('punkt') | ||
nltk.download('wordnet') | ||
model = load_model('chatbot_model.h5') | ||
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) | ||
|
||
words = pickle.load(open('words.pkl', 'rb')) | ||
classes = pickle.load(open('classes.pkl', 'rb')) | ||
intents = json.loads(open('intents.json').read()) | ||
|
||
# Initialize chat history | ||
if "chat_history" not in st.session_state: | ||
st.session_state.chat_history = [] | ||
|
||
# Chatbot functions | ||
def clean_up_sentence(sentence): | ||
sentence_words = nltk.word_tokenize(sentence) | ||
sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words] | ||
return sentence_words | ||
|
||
def bow(sentence, words, show_details=True): | ||
sentence_words = clean_up_sentence(sentence) | ||
bag = [0] * len(words) | ||
for s in sentence_words: | ||
for i, w in enumerate(words): | ||
if w == s: | ||
bag[i] = 1 | ||
if show_details: | ||
print ("found in bag: %s" % w) | ||
return(np.array(bag)) | ||
|
||
def predict_class(sentence, model): | ||
p = bow(sentence, words, show_details=False) | ||
res = model.predict(np.array([p]))[0] | ||
ERROR_THRESHOLD = 0.25 | ||
results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD] | ||
results.sort(key=lambda x: x[1], reverse=True) | ||
return [{"intent": classes[r[0]], "probability": str(r[1])} for r in results] | ||
|
||
def getResponse(ints, intents_json): | ||
tag = ints[0]['intent'] | ||
list_of_intents = intents_json['intents'] | ||
for i in list_of_intents: | ||
if i['tag'] == tag: | ||
result = np.random.choice(i['responses']) | ||
break | ||
return result | ||
|
||
# Streamlit GUI | ||
|
||
st.title("E-Commerce Store Assistant") | ||
|
||
def main(): | ||
# Container for chat history | ||
chat_container = st.container() | ||
|
||
# Form to handle user input | ||
with st.form("user_input_form"): | ||
# Text input for user | ||
user_input = st.text_input("Prompt:") | ||
# Submit button | ||
submit_button = st.form_submit_button("Send") | ||
|
||
# Handle form submission | ||
if submit_button and user_input.strip() != "": | ||
st.session_state.chat_history.append({"user": user_input}) | ||
response = chatbot_response(user_input) | ||
st.session_state.chat_history.append({"bot": response}) | ||
|
||
# Display entire chat history | ||
with chat_container: | ||
for item in st.session_state.chat_history: | ||
if "user" in item: | ||
st.image("user.png", width=32) | ||
st.markdown(f"{item['user']}") | ||
elif "bot" in item: | ||
st.image("aiChatbot.png", width=32) | ||
st.markdown(f"{item['bot']}") | ||
|
||
def chatbot_response(text): | ||
ints = predict_class(text, model) | ||
if ints: | ||
res = getResponse(ints, intents) | ||
return res | ||
else: | ||
return "I'm sorry, I didn't understand that." | ||
|
||
|
||
if __name__ == "__main__": | ||
main() | ||
|
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import random # Importing the random module | ||
|
||
import nltk | ||
from nltk.stem import WordNetLemmatizer | ||
import json | ||
import pickle | ||
import numpy as np | ||
from tensorflow.keras.models import Sequential, load_model | ||
from tensorflow.keras.layers import Dense, Dropout | ||
|
||
lemmatizer = WordNetLemmatizer() | ||
nltk.download('punkt') | ||
nltk.download('wordnet') | ||
|
||
# Load intents from JSON (correcting the path) | ||
intents = json.loads(open('intents.json').read()) | ||
|
||
# Initialize lists | ||
words = [] | ||
classes = [] | ||
documents = [] | ||
ignore_words = ['?', '!'] | ||
|
||
# Process intents | ||
for intent in intents['intents']: | ||
for pattern in intent['patterns']: | ||
# Tokenize each word | ||
w = nltk.word_tokenize(pattern) | ||
words.extend(w) | ||
# Add documents in the corpus | ||
documents.append((w, intent['tag'])) | ||
# Add to classes list | ||
if intent['tag'] not in classes: | ||
classes.append(intent['tag']) | ||
|
||
# Lemmatize, lowercase, and remove duplicates | ||
words = [lemmatizer.lemmatize(w.lower()) for w in words if w not in ignore_words] | ||
words = sorted(list(set(words))) | ||
classes = sorted(list(set(classes))) | ||
|
||
# Save words and classes to pickle files | ||
pickle.dump(words, open('words.pkl', 'wb')) | ||
pickle.dump(classes, open('classes.pkl', 'wb')) | ||
|
||
random.shuffle(documents) | ||
|
||
# Initialize lists for training | ||
train_x = [] | ||
train_y = [] | ||
|
||
# Generate training data | ||
for doc in documents: | ||
bag = [0] * len(words) | ||
pattern_words = doc[0] | ||
intent = doc[1] | ||
for word in pattern_words: | ||
if word in words: | ||
bag[words.index(word)] = 1 | ||
train_x.append(bag) | ||
label = [0] * len(classes) | ||
label[classes.index(intent)] = 1 | ||
train_y.append(label) | ||
|
||
# Convert lists to numpy arrays | ||
train_x = np.array(train_x) | ||
train_y = np.array(train_y) | ||
|
||
# Define and compile the model | ||
model = Sequential() | ||
model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu')) | ||
model.add(Dropout(0.5)) | ||
model.add(Dense(64, activation='relu')) | ||
model.add(Dropout(0.5)) | ||
model.add(Dense(len(train_y[0]), activation='softmax')) | ||
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) | ||
|
||
# Fit the model to the data | ||
history = model.fit(train_x, train_y, epochs=200, batch_size=8, verbose=1) | ||
|
||
# Save the model | ||
model.save('chatbot_model.h5') | ||
|
||
print("Model training completed. Model saved as 'chatbot_model.h5'.") | ||
|
||
# Load the model and necessary files | ||
model = load_model('chatbot_model.h5') | ||
words = pickle.load(open('words.pkl', 'rb')) | ||
classes = pickle.load(open('classes.pkl', 'rb')) | ||
|
Oops, something went wrong.