Use Python+AWS Create Sentiment Analysis Application
Maverick Fung
Posted on January 10, 2022
Hi,Today I will share my experience to you,It's about Use Python And Amazon Comprehend ,and I also use Lambda,Api Gateway togather build the tool
- Python Stage(I will put my code in this stage) #### Notice:I use Qtdesigner and PYUIC
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '1.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
import sys
import openpyxl
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QWidget
from PyQt5.QtWidgets import QApplication
import requests
import json
import datetime
import ctypes
import images
#Change Task manager icon
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
filename = '1'#Waiting analysis file name
flag = 1 #analysis flag
class About_page(QWidget):
def __init__(self):
super(About_page, self).__init__()
self.resize(400,300)
self.setWindowTitle("About")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(':/Image-2.ico'), QtGui.QIcon.Normal)
self.setWindowIcon(icon)
self.label = QtWidgets.QLabel(self)
self.label.setGeometry(QtCore.QRect(30, 40, 161, 21))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self)
self.label_2.setGeometry(QtCore.QRect(30, 75, 161, 21))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self)
self.label_3.setGeometry(QtCore.QRect(30, 110, 91, 21))
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self)
self.label_4.setGeometry(QtCore.QRect(130, 110, 221, 21))
self.label_4.setObjectName("label_4")
self.retranslateUi(self)
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self,About_page):
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("Form", "About"))
self.label.setText(_translate("Form", "Copyright ownership:T-UniStar"))
self.label_2.setText(_translate("Form", "User:Lei Feng"))
self.label_3.setText(_translate("Form", "Powered by"))
self.label_4.setText(_translate("Form",
u'<a href="https://aws.amazon.com/cn/" style="color:#0000ff;"><b>Amazon Web Services, Inc.</b></a>'))
self.label_4.setOpenExternalLinks(True)
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(750, 548)
Form.setFixedSize(QtCore.QSize(780, 548))
Form.setMaximumSize(QtCore.QSize(750, 548))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(':/Image-1.ico'), QtGui.QIcon.Normal)
Form.setWindowIcon(icon)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(220, 10, 261, 61))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(26)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(250, 70, 211, 21))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(12)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(20, 140, 111, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.RealTime_analysis)
self.textEdit = QtWidgets.QTextEdit(Form)
self.textEdit.setGeometry(QtCore.QRect(160, 140, 291, 31))
self.textEdit.setObjectName("textEdit")
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setGeometry(QtCore.QRect(20, 100, 201, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(20)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(Form)
self.label_4.setGeometry(QtCore.QRect(20, 200, 481, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(18)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.pushButton_2 = QtWidgets.QPushButton(Form)
self.pushButton_2.setGeometry(QtCore.QRect(40, 420, 111, 28))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_2.clicked.connect(self.multWordsAy)
self.label_5 = QtWidgets.QLabel(Form)
self.label_5.setGeometry(QtCore.QRect(20, 250, 171, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.label_6 = QtWidgets.QLabel(Form)
self.label_6.setGeometry(QtCore.QRect(20, 330, 171, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.label_6.setFont(font)
self.label_6.setObjectName("label_6")
self.label_7 = QtWidgets.QLabel(Form)
self.label_7.setGeometry(QtCore.QRect(80, 280, 31, 51))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(20)
font.setBold(False)
font.setWeight(50)
self.label_7.setFont(font)
self.label_7.setObjectName("label_7")
self.label_8 = QtWidgets.QLabel(Form)
self.label_8.setGeometry(QtCore.QRect(80, 360, 31, 51))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(20)
font.setBold(False)
font.setWeight(50)
self.label_8.setFont(font)
self.label_8.setObjectName("label_8")
self.label_9 = QtWidgets.QLabel(Form)
self.label_9.setGeometry(QtCore.QRect(200, 250, 561, 31))
self.label_9.setObjectName("label_9")
self.textBrowser = QtWidgets.QTextBrowser(Form)
self.textBrowser.setGeometry(QtCore.QRect(190, 410, 351, 131))
self.textBrowser.setObjectName("textBrowser")
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(180, 330, 301, 31))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setEnabled(False)
self.pushButton_3 = QtWidgets.QPushButton(Form)
self.pushButton_3.setGeometry(QtCore.QRect(510, 330, 111, 31))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_3.clicked.connect(self.openFile)
self.label_10 = QtWidgets.QLabel(Form)
self.label_10.setGeometry(QtCore.QRect(470, 110, 72, 21))
self.label_10.setObjectName("label_10")
self.label_11 = QtWidgets.QLabel(Form)
self.label_11.setGeometry(QtCore.QRect(560, 110, 72, 21))
self.label_11.setObjectName("label_11")
self.label_12 = QtWidgets.QLabel(Form)
self.label_12.setGeometry(QtCore.QRect(650, 110, 72, 21))
self.label_12.setObjectName("label_12")
self.textEdit_2 = QtWidgets.QTextEdit(Form)
self.textEdit_2.setGeometry(QtCore.QRect(460, 140, 81, 31))
self.textEdit_2.setObjectName("textEdit_2")
self.textEdit_2.setEnabled(False)
self.textEdit_3 = QtWidgets.QTextEdit(Form)
self.textEdit_3.setGeometry(QtCore.QRect(550, 140, 81, 31))
self.textEdit_3.setObjectName("textEdit_3")
self.textEdit_3.setEnabled(False)
self.textEdit_4 = QtWidgets.QTextEdit(Form)
self.textEdit_4.setGeometry(QtCore.QRect(640, 140, 81, 31))
self.textEdit_4.setObjectName("textEdit_4")
self.textEdit_4.setEnabled(False)
self.pushButton_4 = QtWidgets.QPushButton(Form)
self.pushButton_4.setGeometry(QtCore.QRect(650, 500, 93, 28))
self.pushButton_4.setObjectName("pushButton_4")
self.pushButton_4.clicked.connect(self.open_About_page)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Sentiment Analysis System"))
self.label.setText(_translate("Form", "Sentiment Analysis System"))
self.label_2.setText(_translate("Form", "Please follow the stage work"))
self.pushButton.setText(_translate("Form", "Start Single words Analysis"))
self.textEdit.setHtml(_translate("Form", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-style:italic;\">Please Input Need Analysis words</span></p></body></html>"))
self.label_3.setText(_translate("Form", "Single Words Analysis"))
self.label_4.setText(_translate("Form", "More Words Analysis(Only support XLSX format)"))
self.pushButton_2.setText(_translate("Form", "Start More Words Analysis"))
self.label_5.setText(_translate("Form", "Stage 1、Format head"))
self.label_6.setText(_translate("Form", "Stage 2、Choose File"))
self.label_7.setText(_translate("Form", "↓"))
self.label_8.setText(_translate("Form", "↓"))
self.label_9.setText(_translate("Form", "The First head is:Text、Positive、Negative、Neutral、Emotion judgment、Language"))
self.pushButton_3.setText(_translate("Form", "Choose File"))
self.label_10.setText(_translate("Form", "Positive"))
self.label_11.setText(_translate("Form", "Negative"))
self.label_12.setText(_translate("Form", "Emotion Judgment"))
self.pushButton_4.setText(_translate("Form", "About"))
def RealTime_analysis(self):
stat_words = self.textEdit.toPlainText()
#print(stat_words)
#print(data)
url = "https://yuzcb6dtb3.execute-api.us-east-1.amazonaws.com/endpoint"
payload = json.dumps({
"Text": stat_words
})
headers = {
'Content-Type':'application/json'
}
RTResponse = requests.request('POST',url,headers=headers,data=payload)
RTRp_text = RTResponse.text
RT_Positive = json.loads(RTRp_text)['body']['SentimentScore']['Positive']
RT_Negative = json.loads(RTRp_text)['body']['SentimentScore']['Negative']
RT_Neutral = json.loads(RTRp_text)['body']['SentimentScore']['Neutral']
# print(float(str(json.loads(RTRp_text)['body']['SentimentScore']['Positive'])))
# self.textEdit_2.setText(RT_Positive)
# self.textEdit_3.setText(RT_Negative)
if RT_Positive > RT_Negative and RT_Positive > RT_Neutral:
self.textEdit_2.setText(str(float(RT_Positive) * 100)[:8])
self.textEdit_3.setText(str(float(RT_Negative)*10)[:8])
self.textEdit_4.setText('Postive')
elif RT_Positive < RT_Negative and RT_Neutral < RT_Negative:
self.textEdit_2.setText(str(float(RT_Positive)*10)[:8])
self.textEdit_3.setText(str(float(RT_Negative)*100)[:8])
self.textEdit_4.setText('Negative')
else:
self.textEdit_2.setText(str(float(RT_Positive) * 10)[:8])
self.textEdit_3.setText(str(RT_Negative)[:8])
self.textEdit_4.setText('Neutral')
print(RTRp_text)
def openFile(self):
openFileName = QFileDialog.getOpenFileName(None,'Choose File', '', 'Excel files(*.xlsx)')
print(openFileName)
openF = openFileName[0].split('/')
global filename;
filename = openFileName[0];
name = openF[len(openF) - 1];
self.lineEdit.setText(str(name))
def stopAnalysis(self):
self.pushButton_2.setText("Start More Words Analysis")
self.pushButton_2.clicked.disconnect(self.stopAnalysis)
self.pushButton_2.clicked.connect(self.multWordsAy)
self.textBrowser.append("Stopped by user:" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
global flag;
flag = -1;
return
def multWordsAy(self):
#Check file exist
global flag;
flag = 1
import os
if (not os.path.exists(filename)):
self.textBrowser.append('This file not exist!')
return;
self.pushButton_2.setText("Stop Analysis")
self.textBrowser.append("Start Analysis:" + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
self.pushButton_2.clicked.disconnect(self.multWordsAy)
self.pushButton_2.clicked.connect(self.stopAnalysis)
def getMultResult(text):
senment_words = text
# print(stat_words)
# print(data)
url = "https://yuzcb6dtb3.execute-api.us-east-1.amazonaws.com/endpoint"
mult_payload = json.dumps({
"Text": senment_words
})
headers = {
'Content-Type': 'application/json'
}
multResponse = requests.request('POST', url, headers=headers, data=mult_payload)
mult_resp_text = multResponse.text
mu_Positive = json.loads(mult_resp_text)['body']['SentimentScore']['Positive']
mu_Negative = json.loads(mult_resp_text)['body']['SentimentScore']['Negative']
mu_Neutral = json.loads(mult_resp_text)['body']['SentimentScore']['Neutral']
LanguageCode = json.loads(mult_resp_text)['LanguageCode']
return [mu_Positive,mu_Negative,mu_Neutral,LanguageCode]
book = openpyxl.load_workbook(filename)
sheet = book.get_sheet_by_name(book.get_sheet_names()[0])
rows = sheet.max_row
showText = "Read file successful,amount"+str(rows-1)+"records waiting analysis。。。\nCurrent Time:"+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self.textBrowser.append(showText)
if (sheet.cell(1, 1).value != 'Text' or sheet.cell(1, 2).value != 'Positive' or sheet.cell(1,3).value != 'Negative' or sheet.cell(1, 4).value != 'Negative' or sheet.cell(1, 5).value != 'Emotion judgment' or sheet.cell(1,6).value != 'Language'):
self.textBrowser.append('The execl not stand format!')
return;
for i in range(2,rows+1):
detectWords = sheet.cell(i,1).value
detectResult = getMultResult(detectWords)
self.textBrowser.append(f'Analysising {i-1}Record,Current Time:{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
print(f'Analysising{i-1}Record,Current Time:{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}')
sheet.cell(i,2,detectResult[0])
sheet.cell(i,3,detectResult[1])
sheet.cell(i,4,detectResult[2])
sheet.cell(i,6,detectResult[3])
if detectResult[0] > detectResult[1] and detectResult[0] > detectResult[2]:
sheet.cell(i,5,"Positive")
elif detectResult[1] > detectResult[0] and detectResult[1] > detectResult[2]:
sheet.cell(i,5,"Negative")
else:
sheet.cell(i,5,"Neutral")
QApplication.processEvents()
book.save(filename)
self.textBrowser.append('Analysis ended')
self.textBrowser.append(str(rows - 1) + "Records analysis done!")
self.pushButton_2.setText("Strat Analysis")
self.pushButton_2.clicked.disconnect(self.stopAnalysis)
self.pushButton_2.clicked.connect(self.multWordsAy)
def open_About_page(self):
self.about_form = About_page()
self.about_form.show()
if __name__=="__main__":
app=QtWidgets.QApplication(sys.argv)
widget=QtWidgets.QMainWindow()
# widget.setFixedSize(widget.width(), widget.height()-80) #ban max
ui=Ui_Form()
ui.setupUi(widget)
widget.showMaximized()
sys.exit(app.exec_())
- Lambda And Api Gateway Stage #### Notice You need give right IAM
Here is the Lambda Code
import json
import boto3
comprehend = boto3.client(service_name='comprehend', region_name='ap')
def lambda_handler(event, context):
# TODO implement
LanguageCode = comprehend.detect_dominant_language(Text=event['Text'])
comprehend_sentiment = comprehend.detect_sentiment(Text = event['Text'],LanguageCode=LanguageCode['Languages'][0]['LanguageCode'])
print(LanguageCode)
return {
'statusCode': 200,
'body': comprehend_sentiment,
'LanguageCode':LanguageCode['Languages'][0]['LanguageCode']
}
This is Apigateway(When you finished,You need deploy it and use postman to test)
- The Final display
💖 💪 🙅 🚩
Maverick Fung
Posted on January 10, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.