본문 바로가기

Github & Streamlit

리뷰 긍정/부정 앱 만들기: 긍정/부정 판단하는 인공지능 삽입

반응형

리뷰긍정/부정 예측 앱 만들기

 

- 학습관련한 코드는 코랩/주피터 노트북에서 진행하고, 웹 대시보드에 옮기지 않는다. 

ㄴ 웹 대시보드는 가공 완료된 것을 보여주는 역할이므로, 데이터 가공은 하지 않는다. 

 

- 작업하고자 하는 파일을 코랩에서 연다.

- Github에서 새로운 레파지토리를 만든다. (이름: streamlit-review-app)

- 로컬 컴에 클론

 

- streamlit-review-app으로 이동

 

진입

 

웹 대시보드에서 보여지는 화면

 

서버에서 보여지는 모습

바로, nltk 모듈을 설치해준다.

$ pip install nltk

 

이하 colab

 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

from google.colab import drive
drive.mount('/content/drive')

import os
os.chdir('/content/drive/MyDrive/Colab Notebooks')

yelp_df =  pd.read_csv('yelp.csv')
yelp_df['length'] = yelp_df['text'].apply(len)

 

yelp_df_1_5 = yelp_df.loc[(yelp_df['stars'] ==1) | (yelp_df['stars'] ==5) ,]

 

 

import string
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
my_stopwords = stopwords.words('english')

def message_cleaning(sentence) : 
  #  1. 구두점 제거
  Test_punc_removed = [char for char in sentence if char not in string.punctuation]
  # 2. 각 글자들을 하나의 문자열로 합친다. 
  Test_punc_removed_join = ''.join(Test_punc_removed)
  # 3. 문자열에 불용어가 포함되어잇는지 확인해서, 불용어 제거한다.
  Test_punc_removed_join_clean = [word for word in Test_punc_removed_join.split() if word.lower() not in my_stopwords]
  # 4. 결과로 남은 단어들만 리턴한다. 
  return Test_punc_removed_join_clean

 

from sklearn.feature_extraction.text import CountVectorizer

vec = CountVectorizer(analyzer = message_cleaning)

X = vec.fit_transform(yelp_df_1_5['text'])

# transform 하기 전에 애널라이저를 먼저 시행한다. 

# transform 바꿔달라

# fit: 텍스트에 있는 내용을 몇개가 문자가 나왔는지, 구두점 제거하고 전체 리뷰에서 몇개가 쓰였는지, 컬럼으로 만든다.

# 바꿔서, 정렬해서, 일렬로 만들어가지고. 

# 글이 있어야한다. 그 글이 X

# 이 글을 주고, 이 글이 1점받은 글이야, 5점받은 글이야 판단하라

 

X = X.toarray()

y = yelp_df_1_5['stars']

# 실제 넘파이 어레이로 X가 되어있어야한다. 

# y는 별점, 정답지가 있어야한다. 

# 애매한 2,3,4점은 빼고, 확실한 1점과 5점으로만 판단하도록 하자.

-> 리뷰 분석 (별점 1~5점)

 

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y, test_size = 0.2,random_state=7)

from sklearn.naive_bayes import MultinomialNB,GaussianNB

classifier1 = MultinomialNB()
classifier1.fit(X_train, y_train)

 

가공한 데이터를 csv 파일로 저장해준다. 

yelp_df.to_csv('review2.csv')

 

학습이 다 끝난 인공지능을 웹 대시보드에 배포하기 위해서는 인공지능 파일과, 벡터라이저 파일 2개가 필요하다.

import joblib

joblib.dump(classifier1,'classifier.pkl')
joblib.dump(vec,'vec.pkl')

- 저장한 파일을 github에 data 폴더를 생성하여 넣어둔다.

 

이하 vscode

(이하 app.py)

 

from asyncio import run_coroutine_threadsafe
import streamlit as st

from app_home import run_home
from app_eda import run_eda
from app_ml import run_ml

import string
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
my_stopwords = stopwords.words('english')

def message_cleaning(sentence) :
  #  1. 구두점 제거
  Test_punc_removed = [char for char in sentence if char not in string.punctuation]
  # 2. 각 글자들을 하나의 문자열로 합친다.
  Test_punc_removed_join = ''.join(Test_punc_removed)
  # 3. 문자열에 불용어가 포함되어잇는지 확인해서, 불용어 제거한다.
  Test_punc_removed_join_clean = [word for word in Test_punc_removed_join.split() if word.lower() not in my_stopwords]
  # 4. 결과로 남은 단어들만 리턴한다.
  return Test_punc_removed_join_clean


def main():
    st.title('리뷰 긍정 부정 예측 앱')

    menu = ['Home',"EDA",'ML']
    choice = st.sidebar.selectbox('메뉴 선택',menu)
    if choice == menu[0]:
        run_home()
    elif choice == menu[1]:
        run_eda()
    elif choice == menu[2]:
        run_ml()

if __name__ == "__main__":
    main()

 

(이하 app_home.py)

 

import streamlit as st

def run_home():
    st.subheader('이 앱은 리뷰데이터를 분석하고, 어떤 문장이 들어오면, 긍정부정을 예측하는 앱이다')

 

(이하 app_home.py)

import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

 

def run_eda():
    df = pd.read_csv('data/review2.csv',index_col=0)
   
    st.dataframe(df)

    st.text('리뷰의 길이별 히스토그램')

    fig1=plt.figure()
    df['length'].hist()
    st.pyplot(fig1)

 

    st.text('리뷰의 길이가 가장 긴 데이터')

    st.dataframe(df.loc[df['length'] == df['length'].max(),])

    st.text('리뷰의 길이가 가장 짧은 데이터')
    st.dataframe(df.loc[df['length'] == df['length'].min(),])

    my_order = df['stars'].value_counts().index
    st.text('각 별점별 리뷰의 갯수')
   
    fig2 = plt.figure()
    sns.countplot(data = df, x = 'stars', order= my_order)
    st.pyplot(fig2)

    # 리뷰의 별점을 셀렉트박스로 만들어서 유저에게 보여준다.
    # 유저는, 4를 선택하면, 별점이 4인 데이터만 가져와서,  별점과 리뷰내용만 화면에 보여준다.

    start_menu = sorted(df['stars'].unique())

    star_selected = st.selectbox('별점 선택',start_menu)
    st.dataframe(df.loc[df['stars'] == star_selected,['stars','text']])

 

(이하 app_ml.py)

import streamlit as st

import string
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
my_stopwords = stopwords.words('english')

import joblib
import numpy as np

 

def run_ml():
    st.subheader('문장을 입력하면, 긍정 부정 예측해준다.')
   
    sentence = st.text_input('문장 입력')

    # 유저가 버튼을 누르면, 예측하도록 만든다.
    if st.button('예측 실행') :

        classifier = joblib.load('data/classifier.pkl')
        vec = joblib.load('data/vec.pkl')
        new_data = np.array([sentence])
        X_new = vec.transform(new_data)
        X_new = X_new.toarray()
        y_pred = classifier.predict(X_new)
       
        if y_pred[0] == 5:
            st.text('입력하신 문장은 긍정입니다.')
        else :
            st.text('입력하신 문장은 부정입니다.')


        st.write(y_pred)

 

 

반응형