앞서 배달어플 리뷰 데이터를 활용하여 LSTM모델로 긍,부정을 분류하는
딥러닝 모델을 만든적 있었다.
이번에는 "허깅페이스" 에서 LLM모델을 활용하여 Chatbot을 개발 하였다.
## 배달어플 리뷰 긍/부정 분류 영상
https://www.youtube.com/watch?v=wHwbz0MO8Rc
VIDEO
< Work Flow >
* 구현순서
1) Google Scraper 로 "쿠팡이츠", "배달의민족", "요기요" 어플의 리뷰데이터 수집
2) 각각의 어플을 별점 5점과 4점은 1로 라벨링 => 긍정 리뷰데이터
각각의 어플을 별점 1점과 2점은 0으로 라벨링 => 부정 리뷰데이터
3) 영어 및 긍/부정에 필요없는 특수문자 제거
4) 특정한 문장을 넣으면 잘못 분류되어 긍/부정에 필요한 데이터 추가함
긍정 : 15,000건 , 부정 : 16,498건 => 총 31,489건
5) Hugging Face에서 한국어로 사전학습된 RoBERTa 로드
6) EarlyStoping , 학습률지정 등 파인튜닝
7) 훈련한 모델을 Hugging Face에 모델 로드
8) React로 프론트 엔드 개발
9) FastAPI를 사용해서 벡엔드와 프론트엔드 연결
(1) AI agent를 활용해서 특정 단어가 있으면 긍정/부정
(2) "맛", "배달","위생" 세개의 카테고리로 나눔
(3) 세개의 카테고리중 두개 이상이 긍정이면 최종판정 "긍정" 표시
(4) 애매한 표현이면 최종판정 "애매" 표시
10) 개발한 벡엔드와 프론트 엔드를 GitHub에 저장
11) AWS EC2를 활용해서 웹 배포
- LLM모델 구현 순서
1. 준비 : 원본데이터 -> 토큰나이저 -> 임베딩 -> LLM정의 및 학습(하이퍼파라미터: 학습률, 에포크, 가중치, earlystoping) -> 모델저장 2. 실행 : 쿼리 -> 토큰나이저 -> 임베딩 -> 에측
- RAG 와 벡터db를 활용한 LLM모델 구현 순서
1. 준비: 원본데이터 -> 청킹-> 토큰나이저 -> 임베딩 -> 벡터db저장 및 색인 -> LLM정의 및 학습 -> 모델저장 2. 실행 : 쿼리 -> 토큰나이저 -> 임베딩 ->벡터db검색 ->검색증강 -> 최종답변생성
1. 프로젝트 기간 : 2025/06/17~ 2025/10/152. 주제 : 배달어플 리뷰를 긍,부정 분류하는 챗봇
1) 문제정의
(1) 기존 단순 분류 모델로는 배달 앱 리뷰에서 발생하는 복합적인 사용자 의도 파악과 다양한 맥락의 질문에 대한 만족스러운 응대가 불가능했다.
따라서 허깅페이스의 사전 학습된 한국어 LLM과 임베딩 모델을 활용하여, 사용자 의도를 정확히 파악하고, 광범위한 고객 데이터를 기반으로 일관성 있고 유연한 답변을 생성하는 고도화된 대화형 고객 응대 챗봇을 개발했다.
3. LLM 개념 1) LLM특징
(0) 문장입력 -> 트랜스포머(인코더,디코더) -> 출력
(1) LLM 순서 : 데이터입력 -> 토크나이저 -> 임베딩 -> 인코더 -> LLM모델 정의 및 전이학습 -> 파인튜닝(미세튜닝) -> 최종 LLM모델
(2) 전이학습 : LLM모델로 학습한것 이다.
2) 인코더 기반 모델 vs 디코더 기반 모델
(1) 인코더 기반 모델: 언어표현생성, 텍스트생성x ,텍스트 분류 , ex) BERT, KLUE/RoBERTa-base 등
(2) 디코더 기반 모델 : 텍스트 생성하는데 초점, 임베딩생성x. 시퀀스 투 시퀀스 모델, 대화생성 ex) GPT
3) 토큰 : 텍스트를 단어로 쪼갠다 (1) 단어토큰 : 단어별로 쪼갠다 (2) 부분토큰 : ex) bards를 bard, s 로 단어에서 부분별로 또 쪼갠다 (3) 문자토큰 : 알파벳 별로 쪼갠다 (4) 바이트토큰 : 바이트별로 쪼갠다
4) 토큰나이저 ( 문장-> 숫자 )
(1) 텍스트 분리 - 문장을 토큰(단어)으로 쪼갠다.
(2) 숫자로 변환 - 토큰으로 쪼갠것을 숫자로 변환한다
(3) 유형 - 단어기반(띄어쓰기 단위로 분리) , 문자기반(모든글자 하나하나를 분리 ), 서브워드기반(단어를 자주 등징하는 의미있는 단위로 분리)
5) 임베딩 : 토큰을 수치(숫자)로 표현한다(word2vec) (1) 스킵그램 : 윈도크기가 2명 중심단어의 앞뒤로 이어질 2개의 단어고려 ( 신경망이 두개의 단어를 입력받고 동일한 문맥이 등장하면1, 그렇지 않으면 0) -> 두개의 단어: 중심단어, 예측한단어 (2) 음성샘플링 : 데이터셋에서 랜덤하게 샘플링하여 음성샘플링 만듦
(3) 벡터는 방향을 가지고 있음, 임베딩은 벡터화함(방향과 숫자를 가짐)
(4) 토큰나이저에서 숫자로 변환한것을 의미있는 것으로 벡터화 시킨다
(5) 유형 : 토큰임베딩(토큰나이저가 변환한 토큰ID를 의미벡터로 변환)
위치임베딩(단어가 나타나는 순서 정보를 벡터로 만들어 토큰 임베딩에 더한다)
세그먼트 임베딩(입력 토큰이 첫번째 문장에 속하는지, 두번째 문장에 속하는지 구분하는 정보를 베터로 나타내어 추가한다)
=> 3가지 유형을 합쳐서 하나의 임베딩을 가지게 된다.
6) 인코더
(1) 문장 맥락이해
(2) 멀티헤드 셀프 어텐션 + 피드 포워드 네트워크 로 이루어져 있다.
(3) 멀티헤드 셀프 어텐션 : 입력된 모든 단어들이 문장 내의 다른 모든 단어들과 얼마나 관련이 있는지 계산
(4) 피드 포워드 네트워크 : 어텐션 레이어에서 생성된 새로운 맥락 벡터를 입력받아, 비선형 변환을 통해 표현력을 더욱 높이고 정보를 복잡하게 가공한다.( 모델이 학습한 복잡한 패턴 추출)
(5) 두 레이어 사이에는 "잔차연결"과 "정규화"가 적용되어 학습이 안정적으로 이루어지도록 돕는다.
(6) 임베딩 벡터 -> 티헤드 셀프 어텐션 -> 피드 포워드 네트워크 -> 출력(다음 인코더 블록의 입력)
=> LLM모델이 base인경우 보통12층, large인경우 24층으로 이루어져있다.
7) 파인튜닝
(1) 허깅페이스에서 모델을 가져와 하이퍼파라미터(학습률, 배치크기,에포크수,가중치정의) 를 설정하여 다시 훈련하는것 이다.
4. 프로세스 1) 데이터 수집
pip install google_play_scraper
import pandas as pd
import numpy as np
from google_play_scraper import app , Sort , reviews_all
# 배달어플 순위
# 1. 배달의민족 => df.bm
# 2. 쿠팡이츠 => df_co
# 3. 요기요 => df_yo
url = "com.fineapp.yogiyo"
# com.coupang.mobile.eats-> 쿠팡이츠
# com.fineapp.yogiyo --> 요기요
# com.sampleapp --> 배달의민족
# 앱 정보 크롤링
app = app ( url , lang = "ko" , #언어 한국어
country = "kr" ) #나라 한국으로 설정
# 앱 리뷰 크롤링
review = reviews_all ( url ,
sleep_milliseconds = 500 , # 0.5초 대기시간
lang = "ko" , # default = "en"
country = "kr" , # default = "US"
sort = Sort.MOST_RELEVANT , # Sort.NEWEST , 관련성 높은순으로 정렬
filter_score_with = None # None means All score
)
# 데이터프레임 변환
df_yo= pd.DataFrame ( review )
2) 데이터 전처리
### 특수문자 제거 함수정의
import re
def clean_review_text ( text ) :
# 입력 텍스트가 None인 경우 처리
if text is None :
return ""
# 4. 허용할 문자 정의
text = re.sub ( r '([ㄱ-ㅎㅏ-ㅣ]|[^\w\s])\1+' , r '\1' , text ) # 반복되는 자음/모음 및 특수문자 단순화
# 5. 연속된 공백을 하나의 공백으로 치환하고 양쪽 공백 제거
text = re.sub ( r '\s+' , ' ' , text ) .strip ()
return text
### 데이터 전처리 함수
def Preprocessing ( data ) :
# 별점 5점과 4점을 1로 라벨링
best= data [[ 'content' , 'score' ]][( data [ 'score' ] == 5 ) | ( data [ 'score' ] == 4 )] # score 값이 1점인 리뷰만 추출
best [ 'score' ] = 1 # 1로 라벨링
best.drop_duplicates ( subset= [ 'content' ], inplace= True )
best = best.dropna ()
best= best [: 5000 ]
### 리뷰1점과 2점을 0으로 라벨링 해보기
worst_all= data [[ 'content' , 'score' ]] [( data [ 'score' ] == 1 ) | ( data [ 'score' ] == 2 )]
worst_all [ 'score' ] = 0 # 0으로 라벨링
worst_all.drop_duplicates ( subset= [ 'content' ], inplace= True )
worst_all = worst_all.dropna ()
worst_all= worst_all [: 5000 ]
## 특수문자 제거 함수활용
# 특수문자 제거함으로써 모델 입력 데이터의 품질을 높이기
best [ 'content' ] = best [ 'content' ] .apply ( clean_review_text )
# 2. 부정 리뷰 데이터프레임 정제
worst_all [ 'content' ] = worst_all [ 'content' ] .apply ( clean_review_text )
# 3. 라벨 (score) 재설정 (만약 평점 외의 다른 라벨링이 필요하다면)
# 긍정 라벨은 1, 부정 라벨은 0으로 통일 (이진 분류 기준)
best [ 'label' ] = 1
worst_all [ 'label' ] = 0
best = best.drop ( columns= [ 'score' ])
worst_all = worst_all.drop ( columns= [ 'score' ])
# 데이터 정규화
best [ 'content' ] = best [ 'content' ] . str .replace ( "[^ㄱ-ㅎㅏ-ㅣ가-힣 ]" , "" )
worst_all [ 'content' ] = worst_all [ 'content' ] . str .replace ( "[^ㄱ-ㅎㅏ-ㅣ가-힣 ]" , "" )
# 데이터 묶기
df= pd.concat ([ best , worst_all ])
df.columns= [ 'content' , 'label' ]
df.isnull () . sum () # 결측치 확인
# 각 라벨값이 유일한지 확인
print ( df [ 'content' ] .nunique (), df [ 'label' ] .nunique ())
df= df.drop_duplicates ( subset= [ 'content' ])
df= df.reset_index ( drop= True )
return df
df_yo_p= Preprocessing ( df_yo )
df_bm_p= Preprocessing ( df_bm )
df_cp_p= Preprocessing ( df_cp )
## 배달의민족, 요기요, 쿠팡이츠 리뷰 데이터 합치기
## 긍정 : 15,000건 부정 : 14998건 => 총 29,998건
data= pd.concat ([ df_bm_p , df_cp_p , df_yo_p ])
data.to_csv ( 'data1.csv' , index= False )
### 배달의민족, 요기요, 쿠팡이츠 리뷰 데이터 합쳤지만 특정 문장을 인식못해서 긍정리뷰와 부정리뷰에
### 각각 500건식 데이터 추가하기
### 500
import pandas as pd
import random
# 1. 기초 데이터 정의
positives = [ "맛은 최고예요" , "정말 맛있어요" , "음식은 괜찮네요" , "맛있어서 놀랐어요" , "간은 딱 맞아요" ]
connectors = [ "그런데" , "하지만" , "그렇지만" , "문제는" , "다만" ]
negatives = [ "머리카락이 나왔어요" , "이물질이 씹혔어요" , "위생 상태가 별로예요" , "날파리가 날아다녀요" , "식기가 너무 더러워요" ]
results = [ "다시는 안 갈래요" , "기분 잡쳤네요ㅠㅠ" , "너무 실망했어요" , "재방문 의사 제로입니다" , "환불받고 싶어요" ]
generated_reviews = []
# 2. 750개의 문장 생성
for _ in range (75 0 ):
p = random.choice ( positives )
c = random.choice ( connectors )
n = random.choice ( negatives )
r = random.choice ( results )
sentence = f " { p } !! { c } { n } { r } "
generated_reviews.append ( sentence )
# 3. 데이터프레임 생성 (content, label 열 설정)
df = pd.DataFrame ({
'content' : generated_reviews ,
'label' : 0 # 모든 값을 0으로 설정
})
df [ 'content' ] = df [ 'content' ] .apply ( clean_review_text )
# 4. 결과 확인 및 저장
df.to_csv ( 'generated_reviews.csv' , index= False , encoding= 'utf-8-sig' )
# 1. 리스트 정의 (질문자님 구성 그대로)
positive_st = [ "정말 맛있었지만" , "직원분들은 친절하셨는데" , "분위기는 좋았으나" , "양도 많고 괜찮았지만" , "가격은 저렴한 편이지만" ]
negative_is = [ "음식에서 머리카락이 나와서" , "식기류가 너무 지저분해서" , "주문한 음식이 너무 늦게 나와서" , "불친절한 태도 때문에" , "테이블이 끈적거려서" ]
negative_en = [ "다신 안 가요ㅠㅠ" , "기분이 너무 나빴네요." , "정말 실망했습니다." , "재방문 의사 절대 없어요." , "돈 아까워요." ]
# 2. 문장 생성 함수
def generate_mixed_reviews ( count =750 ) :
results = []
for _ in range ( count ):
a = random.choice ( positive_st )
b = random.choice ( negative_is )
c = random.choice ( negative_en )
results.append ( f " { a } { b } { c } " )
return results
# 3. 실행 및 데이터프레임 생성
new_reviews_list = generate_mixed_reviews (750 )
df1 = pd.DataFrame ({
'content' : new_reviews_list , # 정확히 새로 만든 리스트 삽입
'label' : 0
})
# 4. 확인
df1 [ 'content' ] = df1 [ 'content' ] .apply ( clean_review_text )
print ( df1 )
df1.to_csv ( 'generated_re.csv' , index= False , encoding= 'utf-8-sig' )
# 5. 이전 데이터와 현재 데이터 합치기
data1 = pd . concat ([df1,df])
data2 = pd . concat ([ data , data1 ], ignore_index = True )
data = pd .coant([ data2 , positive_reviews_500])
data = data .sort_values( by = 'label' , ascending = False )
# 6. 최종확인
# 긍정 : 15,500건 부정 : 16,498건 => 총 31,998
data .to_csv( 'data.csv' , index = False )
3) 모델 생성
pip install langchain-community langchain-core
import pandas as pd
from datasets import Dataset
data = pd . read_csv ( 'data.csv' ) # 약 3만건
if data . isnull (). sum (). any ():
data = data . dropna ()
# 데이터셋을 Hugging Face의 Dataset 형식으로 변환
dataset = Dataset . from_pandas ( data )
# # 학습용과 평가용으로 데이터셋 분할
dataset = dataset . train_test_split ( test_size = 0.2 ) # 0.3
from transformers import AutoTokenizer , AutoModelForSequenceClassification
model_name = "KLUE/RoBERTa-base" ### 모델 바꿔보기
# 모델에 맞는 토크나이저 불러오기
tokenizer = AutoTokenizer . from_pretrained ( model_name ) # 문장을 단어, 형태소 같은 작은 단위(토큰)로 쪼개고 이를 숫자로 변환
# num_labels=2는 긍정/부정 2가지 클래스를 예측한다는 의미
model = AutoModelForSequenceClassification . from_pretrained ( model_name , num_labels = 2 )
def tokenize_function ( examples ):
# padding='max_length': 모든 문장의 길이를 통일
# truncation=True: 최대 길이를 초과하는 문장을 자름
return tokenizer ( examples [ 'content' ], padding = "max_length" , truncation = True )
# 데이터셋의 각 문장을 토큰화
tokenized_datasets = dataset . map ( tokenize_function , batched = True ) # true: map함수가 여러샘을 배치형태로 묶어 한꺼번에 처리-> 속도향상
# 학습 및 평가 데이터셋 정의
# 데이터 셔플
train_dataset = tokenized_datasets [ "train" ]. shuffle ( seed = 42 )
eval_dataset = tokenized_datasets [ "test" ]. shuffle ( seed = 42 )
4) 파인튜닝(미세튜닝)
import torch
import numpy as np
import torch . nn as nn
from sklearn . metrics import accuracy_score
from transformers import TrainingArguments , Trainer , EarlyStoppingCallback
def compute_metrics ( p ):
preds = np . argmax ( p .predictions, axis = 1 )
acc = accuracy_score ( p .label_ids, preds )
return { 'accuracy' : acc }
# 학습에 사용할 하이퍼파라미터 설정
training_args = TrainingArguments (
output_dir = "./results" ,
report_to = "none" ,
num_train_epochs = 3 , # 에포크 10으로 설정하였더니 정확도가 떨어짐, 에포크2로하니 정확도가 95%까지 올라감
per_device_train_batch_size = 8 , # 4,8,16 으로 설정해보기
per_device_eval_batch_size = 8 , # 4,8,16 으로 설정해보기
learning_rate = 2e-5 , # 0.00002, 기본값인 5e-5(0.00005)
eval_strategy = "epoch" ,
save_strategy = "epoch" , # 저장: 에포크마다
logging_dir = "./logs" ,
# 조기 종료를 위한 설정 (가장 중요)
load_best_model_at_end = True , # 학습 종료 후 최적 모델 가중치를 로드합니다.
metric_for_best_model = "eval_loss" , # Validation Loss 기준으로 최적 모델을 선택합니다.
greater_is_better = False # Loss는 낮을수록 좋으므로 False로 설정합니다.
)
# Validation Loss가 3번 연속 증가하면 학습을 멈춥니다.
early_stopping = EarlyStoppingCallback (
early_stopping_patience = 2 # 3으로 했더니 정확도가 떨어짐
)
class CustomTrainer ( Trainer ):
def compute_loss ( self , model , inputs , return_outputs = False , ** kwargs ):
labels = inputs .pop( "labels" )
outputs = model ( ** inputs )
logits = outputs .get( 'logits' )
# 가중치 없이 표준 CrossEntropyLoss 사용
loss_fct = nn . CrossEntropyLoss ()
# Loss 계산
loss = loss_fct ( logits .view( - 1 , self . model . config . num_labels ), labels .view( - 1 ))
return ( loss , outputs ) if return_outputs else loss
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding ( tokenizer = tokenizer )
# Trainer 인스턴스 생성
trainer = CustomTrainer (
model = model ,
args = training_args ,
train_dataset = train_dataset ,
eval_dataset = eval_dataset ,
data_collator = data_collator ,
compute_metrics = compute_metrics ,
callbacks = [ early_stopping ]
)
trainer . train ()
from transformers import pipeline
trainer . save_model ( "./my_emotional_classifier" )
## 모델 평가방법
1) sklearn에서 accuracy_score 지표로 실제값과 예측값의 정확도 판단
### 비슷한 모델과 나만의 차별점 1. 배달어플의 점유율이 높은 '배달의민족', '쿠팡이츠', 요기요' 의 데이터를 모두 활용하였다. 총 약3만건의 데이터를 활용해 중복된 값은 제거하고, 긍정과 부정을 분류하는거기 때문에 활성화함수인 시그모이드 함수(0~1사이의 확률출력)를 사용하여 검증손실과 훈련손실을 안정적으로 계산한다. 2. earlystoping 을 2번 주어, 검증손실이 2번이상 증가하면 , 학습은 중단된다.
배치사이즈: 2, 학습률x, 배달민족 데이터만 사용, earlystopig : 3
배치사이즈 : 8, 학습률 : 3e-5, 쿠팡이츠+요기요+배달의민족 데이터 사용, 가중치 사용, earlystoping :2
배치사이즈 : 8, 학습률 : 2e-5, 쿠팡이츠+요기요+배달의민족 데이터 사용, 부정리뷰에 가중치 2.0사용, earlystoping :2
5) 테스트
from transformers import pipeline
classifier = pipeline ( "text-classification" , model = "./my_emotional_classifier" , tokenizer = "./my_emotional_classifier" )
####### 예시
new_review1 = "이 카페 분위기 정말 좋고 커피도 맛있네요!"
new_review2 = "직원들이 너무 불친절해서 다시는 안 갈 거예요."
new_review3 = '맛이 없어요'
new_review4 = '맛은 있는데 두번 다시 안갈거 같아요'
new_review5 = '정말 맛있었지만 음식에 머리카락이 나와서 다신 안가요ㅠㅠ'
new_review6 = '정말 맛있었습니다. 하지만 음식에 머리카락이 나와서 다신 안가요ㅠㅠ'
new_review7 = '맛있어요.하지만 머리카락 하나가 나와서 두번 다시 안가요ㅠㅠㅠ'
new_review8 = '맛있어요!! 하지만 머리카락 하나가 나와서 두번 다시 안가요ㅠㅠㅠ'
new_review9 = '맛있어요 하지만 머리카락 하나가 나와서 두번 다시 안가요ㅠㅠㅠ'
new_review10 = '미친 거 아닌가요? 이 맛 실화입니까? 사장님 적게 일하고 많이 버세요'
new_review11 = '음식의 양이 없어요'
# 예측 수행
result1 = classifier ( new_review1 )
result2 = classifier ( new_review2 )
result3 = classifier ( new_review3 )
result4 = classifier ( new_review4 )
result5 = classifier ( new_review5 )
result6 = classifier ( new_review6 )
result7 = classifier ( new_review7 )
result8 = classifier ( new_review8 )
result9 = classifier ( new_review9 )
result10 = classifier ( new_review10 )
result11 = classifier ( new_review11 )
print ( f "리뷰: ' { new_review1 } ' -> 예측: { result1 } " )
print ( f "리뷰: ' { new_review2 } ' -> 예측: { result2 } " )
print ( f "리뷰: ' { new_review3 } ' -> 예측: { result3 } " )
print ( f "리뷰: ' { new_review4 } ' -> 예측: { result4 } " )
print ( f "리뷰: ' { new_review5 } ' -> 예측: { result5 } " )
print ( f "리뷰: ' { new_review6 } ' -> 예측: { result6 } " )
print ( f "리뷰: ' { new_review7 } ' -> 예측: { result7 } " )
print ( f "리뷰: ' { new_review8 } ' -> 예측: { result8 } " )
print ( f "리뷰: ' { new_review9 } ' -> 예측: { result9 } " )
print ( f "리뷰: ' { new_review10 } ' -> 예측: { result10 } " )
print ( f "리뷰: ' { new_review11 } ' -> 예측: { result11 } " )
6) 웹 제작
(1) AI agent 를 활용해서 "맛", "배달", "위생"을 중점적으로 체크함
(2) "맛", "배달", "위생" 중 사용자가 입력한 단어가 없다면 카테고리를 "기타"로 출력됨
(3) 세개의 카테고리중 2개 이상이 긍정이면 최종 판정은 "긍정"으로 판단
세개의 카테고리중 2개 이상이 부정이면 최종 판정은 "부정"으로 판단
사용자가 긍정적인 측면과 부정적인 측면을 각각 한개씩 혹은 두개씩 비슷한 양상으로 질문하면 최종 판정은 "애매"로 판단
7) 웹 배포
(1) Git Hub 에 코드 로드
(2) AWS EC2를 인스턴스 생성 및 인바운드 규칙 생성
(3) Nginx 웹 서버 및 리버스 프록시 설정
(4) HTTPS 보안 및 도메인 연결 - SSL 인증서 발급(Certbot을 사용하여 무료 인증서 발급) , 구매한 도메인을 EC2 서버의 IP와 연결
(5) 무중단 서비스 및 보안 최적화 - nohup 대신 PM2을 사용하여 벡엔드 서버에 등록, 메모리관리( 8GB의 RAM과 2GB의 Swap 메모리)
< 정량적 성능 지표 >
* 딥러닝 모델 대신 허깅페이스를 이용한 이점
1) 높은 성능 및 정확도 - 문맥이해 능력
2) 전이 학습의 이점 - 파인튜닝하면 작은 양의 데이터로도 LSTM 모델 보다 빠르고 효율적이다 , 데이터 부족문제를 완화할수있다.
3) 학습속도 - 병렬처리로 인해 매우빠르다 (딥러닝모델은 순차적 처리)
4) 소비자 입장 (1) 정확한 감정이해 - 왜곡없이 정확하게 전달된다. (2) 개인화된 응대 - 나의 불편함을 공감해줄 수 있다.
5) 기업입장 (1) 혁신적인 분석품질 - 제품/서비스 개선 전략을 빠르고 정확하게 수립할 수 있다. (2) 운영효율성 및 자동화 - 고객 대응 속도를 획기적으로 향상 (3) 개발 및 유지보수 용이 - 시장 변화(유행어, 신조어)에 대한 시스템 업데이트 용이 (4) 마케팅 및 영업활용 - 고객이 실제로 좋아하는 요소에 집중 투자하고 홍보함으로써 고객 유치 및 재구매율을 높일 수 있다.
< 향후 개선사항 >
## 사용된 모델
https://huggingface.co/klue/roberta-base
klue/roberta-base · Hugging Face
KLUE RoBERTa base Pretrained RoBERTa Model on Korean Language. See Github and Paper for more details. How to use NOTE: Use BertTokenizer instead of RobertaTokenizer. (AutoTokenizer will load BertTokenizer) from transformers import AutoModel, AutoTokenizer
huggingface.co
## 내 허깅페이스
https://huggingface.co/ju03/Chatbot_Emotion-classification
ju03/Chatbot_Emotion-classification · Hugging Face
language: ko 배달 앱 리뷰 감정 분류(긍,부정) 모델: "KLUE/RoBERTa-base" 모델 소개 (Model Description) 이 모델은 배달 애플리케이션의 사용자 리뷰를 긍정(1) 또는 부정(0)으로 분류하기 위해 파인 튜닝된 텍
huggingface.co
# 참고사항
* LLM과 sLLM의 차이
* github에 .gitignore 적용하기
https://velog.io/@psk84/.gitignore-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0
.gitignore 적용하기
프로젝트 생성후 git을 연동하면서 가장먼저 하게되는 gitignore처리 간략정리
velog.io
* Rag 설명
Rag 파이프라인 설명
사용자 질문 → 임베딩 모델 (질문을 벡터화) → 유사도 함수 (벡터 DB 검색) → 관련 정보 추출 → RAG 체인 (프롬프트 결합) → LLM 모델 (답변 생성)
## 웹 도메인 구매
https://kr.godaddy.com/offers/godaddy?isc=sem3year¤cyType=KRW&countryview=1&cdtl=c_17604520935.g_192960882408.k_kwd-88659201.a_780104385798.d_c.ctv_g&bnb=b&gad_source=1&gad_campaignid=17604520935&gbraid=0AAAAAD_AGdwdY67Tc0oD2bsJ091AvBoo6&gclid=Cj0KCQiA7fbLBhDJARIsAOAqhsdChHq398xbuued4zLy_OkLH6YCyuN8vJeisDO1yvNdFjtcyzWc0h0aAghoEALw_wcB
GoDaddy
온라인에서 성장하는 데 필요한 모든 지원 수단 및 도구인 웹사이트, 도메인, 디지털 및 소셜 마케팅 외에 GoDaddy 가이드를 통해 모든 단계 안내
kr.godaddy.com