├── Models ├── scaler.pkl ├── model_dt.pkl ├── model_rf.pkl ├── model_xgb.pkl └── countVectorizer.pkl ├── Sentiment-Analysis.zip ├── requirements.txt ├── README.md ├── Data ├── SentimentBulk.csv └── Predictions.csv ├── main.py ├── templates ├── index.html └── landing.html └── api.py /Models/scaler.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pik1989/Sentiment-Analysis/HEAD/Models/scaler.pkl -------------------------------------------------------------------------------- /Models/model_dt.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pik1989/Sentiment-Analysis/HEAD/Models/model_dt.pkl -------------------------------------------------------------------------------- /Models/model_rf.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pik1989/Sentiment-Analysis/HEAD/Models/model_rf.pkl -------------------------------------------------------------------------------- /Models/model_xgb.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pik1989/Sentiment-Analysis/HEAD/Models/model_xgb.pkl -------------------------------------------------------------------------------- /Sentiment-Analysis.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pik1989/Sentiment-Analysis/HEAD/Sentiment-Analysis.zip -------------------------------------------------------------------------------- /Models/countVectorizer.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pik1989/Sentiment-Analysis/HEAD/Models/countVectorizer.pkl -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | matplotlib 3 | seaborn 4 | scikit-learn 5 | wordcloud 6 | nltk 7 | xgboost 8 | streamlit 9 | flask -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Amazon-Alexa-Reviews 2 | 3 | ## Watch Video: https://www.youtube.com/watch?v=6A2w-KYG4Ko 4 | 5 | ## HOW TO RUN 6 | 7 | Step 1: Clone the repository 8 | ``` 9 | git clone https://github.com/Surbhit01/Amazon-Alexa-Reviews.git 10 | ``` 11 | 12 | Step 2: Open the cloned repository and create a conda environment. Activate the new environment 13 | ``` 14 | conda create -n amazonreview python=3.10 15 | ``` 16 | ``` 17 | conda activate amazonreview 18 | ``` 19 | 20 | Step 3: Install the requirements file 21 | ``` 22 | pip install -r requirements.txt 23 | ``` 24 | 25 | Step 4: Run the app 26 | ``` 27 | flask --app api.py run 28 | ``` 29 | 30 | Step 5: The app will run on port 5000. 31 | ``` 32 | localhost:5000 33 | ``` 34 | ## NOTE: The issue raised is fixed, please download the .zip folder and run it. 35 | -------------------------------------------------------------------------------- /Data/SentimentBulk.csv: -------------------------------------------------------------------------------- 1 | Sentence 2 | Love my Echo! 3 | Loved it! 4 | "Sometimes while playing a game, you can answer a question correctly but Alexa says you got it wrong and answers the same as you. I like being able to turn lights on and off while away from home." 5 | "I have had a lot of fun with this thing. My 4 yr old learns about dinosaurs, i control the lights and play games like categories. Has nice sound when playing music as well." 6 | "This item did not work. Certified refurbished should mean it works as advertised. Instead this item crashed as soon as I turned it on and plugged it in. When trying to connect from my phone to the echo dot, it crashed, over and over. Not only would it disconnect but the orange light would freeze and then the thing would reboot with the blue light. Alexa would tell me it’s ready to connect and freeze mid sentence. Tried holding the action button for 5 seconds and it didn’t do anything. Returning immediately and hope they actually fix this item when the next buyer purchases it." 7 | Does not work all the time 8 | I've already returned it. -------------------------------------------------------------------------------- /Data/Predictions.csv: -------------------------------------------------------------------------------- 1 | Sentence,Predicted sentiment 2 | Love my Echo!,Positive 3 | Loved it!,Positive 4 | "Sometimes while playing a game, you can answer a question correctly but Alexa says you got it wrong and answers the same as you. I like being able to turn lights on and off while away from home.",Negative 5 | "I have had a lot of fun with this thing. My 4 yr old learns about dinosaurs, i control the lights and play games like categories. Has nice sound when playing music as well.",Positive 6 | "This item did not work. Certified refurbished should mean it works as advertised. Instead this item crashed as soon as I turned it on and plugged it in. When trying to connect from my phone to the echo dot, it crashed, over and over. Not only would it disconnect but the orange light would freeze and then the thing would reboot with the blue light. Alexa would tell me it’s ready to connect and freeze mid sentence. Tried holding the action button for 5 seconds and it didn’t do anything. Returning immediately and hope they actually fix this item when the next buyer purchases it.",Positive 7 | Does not work all the time,Negative 8 | I've already returned it.,Negative 9 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import pandas as pd 3 | import requests 4 | from io import BytesIO 5 | 6 | # flask --app api.py run --port=5000 7 | prediction_endpoint = "http://127.0.0.1:5000/predict" 8 | 9 | st.title("Text Sentiment Predictor") 10 | 11 | uploaded_file = st.file_uploader( 12 | "Choose a CSV file for bulk prediction - Upload the file and click on Predict", 13 | type="csv", 14 | ) 15 | 16 | # Text input for sentiment prediction 17 | user_input = st.text_input("Enter text and click on Predict", "") 18 | 19 | # Prediction on single sentence 20 | if st.button("Predict"): 21 | if uploaded_file is not None: 22 | file = {"file": uploaded_file} 23 | response = requests.post(prediction_endpoint, files=file) 24 | response_bytes = BytesIO(response.content) 25 | response_df = pd.read_csv(response_bytes) 26 | 27 | st.download_button( 28 | label="Download Predictions", 29 | data=response_bytes, 30 | file_name="Predictions.csv", 31 | key="result_download_button", 32 | ) 33 | 34 | else: 35 | response = requests.post(prediction_endpoint, data={"text": user_input}) 36 | response = response.json() 37 | st.write(f"Predicted sentiment: {response['prediction']}") 38 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Text Sentiment Predictor 9 | 10 | 11 | 12 |

Text Sentiment Prediction

13 | 14 |
15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 |
23 | 24 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /api.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify, send_file, render_template 2 | import re 3 | from io import BytesIO 4 | 5 | # nltk.download('stopwords') 6 | from nltk.corpus import stopwords 7 | from nltk.stem.porter import PorterStemmer 8 | import matplotlib.pyplot as plt 9 | import pandas as pd 10 | import pickle 11 | import base64 12 | 13 | STOPWORDS = set(stopwords.words("english")) 14 | 15 | app = Flask(__name__) 16 | 17 | 18 | @app.route("/test", methods=["GET"]) 19 | def test(): 20 | return "Test request received successfully. Service is running." 21 | 22 | 23 | @app.route("/", methods=["GET", "POST"]) 24 | def home(): 25 | return render_template("landing.html") 26 | 27 | 28 | @app.route("/predict", methods=["POST"]) 29 | def predict(): 30 | # Select the predictor to be loaded from Models folder 31 | predictor = pickle.load(open(r"Models/model_xgb.pkl", "rb")) 32 | scaler = pickle.load(open(r"Models/scaler.pkl", "rb")) 33 | cv = pickle.load(open(r"Models/countVectorizer.pkl", "rb")) 34 | try: 35 | # Check if the request contains a file (for bulk prediction) or text input 36 | if "file" in request.files: 37 | # Bulk prediction from CSV file 38 | file = request.files["file"] 39 | data = pd.read_csv(file) 40 | 41 | predictions, graph = bulk_prediction(predictor, scaler, cv, data) 42 | 43 | response = send_file( 44 | predictions, 45 | mimetype="text/csv", 46 | as_attachment=True, 47 | download_name="Predictions.csv", 48 | ) 49 | 50 | response.headers["X-Graph-Exists"] = "true" 51 | 52 | response.headers["X-Graph-Data"] = base64.b64encode( 53 | graph.getbuffer() 54 | ).decode("ascii") 55 | 56 | return response 57 | 58 | elif "text" in request.json: 59 | # Single string prediction 60 | text_input = request.json["text"] 61 | predicted_sentiment = single_prediction(predictor, scaler, cv, text_input) 62 | 63 | return jsonify({"prediction": predicted_sentiment}) 64 | 65 | except Exception as e: 66 | return jsonify({"error": str(e)}) 67 | 68 | 69 | def single_prediction(predictor, scaler, cv, text_input): 70 | corpus = [] 71 | stemmer = PorterStemmer() 72 | review = re.sub("[^a-zA-Z]", " ", text_input) 73 | review = review.lower().split() 74 | review = [stemmer.stem(word) for word in review if not word in STOPWORDS] 75 | review = " ".join(review) 76 | corpus.append(review) 77 | X_prediction = cv.transform(corpus).toarray() 78 | X_prediction_scl = scaler.transform(X_prediction) 79 | y_predictions = predictor.predict_proba(X_prediction_scl) 80 | y_predictions = y_predictions.argmax(axis=1)[0] 81 | 82 | return "Positive" if y_predictions == 1 else "Negative" 83 | 84 | 85 | def bulk_prediction(predictor, scaler, cv, data): 86 | corpus = [] 87 | stemmer = PorterStemmer() 88 | for i in range(0, data.shape[0]): 89 | review = re.sub("[^a-zA-Z]", " ", data.iloc[i]["Sentence"]) 90 | review = review.lower().split() 91 | review = [stemmer.stem(word) for word in review if not word in STOPWORDS] 92 | review = " ".join(review) 93 | corpus.append(review) 94 | 95 | X_prediction = cv.transform(corpus).toarray() 96 | X_prediction_scl = scaler.transform(X_prediction) 97 | y_predictions = predictor.predict_proba(X_prediction_scl) 98 | y_predictions = y_predictions.argmax(axis=1) 99 | y_predictions = list(map(sentiment_mapping, y_predictions)) 100 | 101 | data["Predicted sentiment"] = y_predictions 102 | predictions_csv = BytesIO() 103 | 104 | data.to_csv(predictions_csv, index=False) 105 | predictions_csv.seek(0) 106 | 107 | graph = get_distribution_graph(data) 108 | 109 | return predictions_csv, graph 110 | 111 | 112 | def get_distribution_graph(data): 113 | fig = plt.figure(figsize=(5, 5)) 114 | colors = ("green", "red") 115 | wp = {"linewidth": 1, "edgecolor": "black"} 116 | tags = data["Predicted sentiment"].value_counts() 117 | explode = (0.01, 0.01) 118 | 119 | tags.plot( 120 | kind="pie", 121 | autopct="%1.1f%%", 122 | shadow=True, 123 | colors=colors, 124 | startangle=90, 125 | wedgeprops=wp, 126 | explode=explode, 127 | title="Sentiment Distribution", 128 | xlabel="", 129 | ylabel="", 130 | ) 131 | 132 | graph = BytesIO() 133 | plt.savefig(graph, format="png") 134 | plt.close() 135 | 136 | return graph 137 | 138 | 139 | def sentiment_mapping(x): 140 | if x == 1: 141 | return "Positive" 142 | else: 143 | return "Negative" 144 | 145 | 146 | if __name__ == "__main__": 147 | app.run(port=5000, debug=True) 148 | -------------------------------------------------------------------------------- /templates/landing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | Amazon Alexa Reviews Analysis 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
23 | 24 |
25 |
26 |
27 |
28 |
29 |

30 | Understand the emotions behind the words.😊 31 |

32 |

33 | Text sentiment prediction is a powerful tool that can help you to understand the emotions and opinions 34 | expressed in your text data. 35 | This information can be used to improve your business in a number of ways 36 |

37 |
38 |
39 |
40 |
41 |
43 | 45 | 46 | 47 |
48 |
49 | 50 |
51 |
53 | 55 | 56 | 57 |
58 |
59 |

Text Sentiment Prediction

60 |
61 |
62 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 |
71 |
72 |
73 |
74 |
75 | 76 |
77 |
78 | Upload your CSV file 79 | 82 |
83 | 84 |
85 | Text for Prediction 86 | 90 | 91 |
92 | 93 | 98 | 99 |
100 | 101 | 102 | 103 | 104 |
105 |
106 |
107 |
108 |
109 | 110 |
111 |
112 |
113 |

Prediction Result

114 |
115 |
116 | 117 |
118 |
119 |
120 |

graph Result

121 |
122 |
123 |
124 |
125 | 130 |
131 | 132 |
133 |
134 |
135 | 136 | 137 | 138 |
139 | 160 | 161 | 237 | 238 | --------------------------------------------------------------------------------