본문으로 바로가기

영업에서의 데이터 사이언스: 고객 감성 분석

데이터 사이언스를 활용해 고객의 감정을 분석하고 영업 최적화를 위한 유용한 인사이트를 도출하는 방법을 알아보세요.
업데이트됨 2026년 8월 31일  · 9분 읽다

AI로 탐색하기

ChatGPTClaudePerplexity

인공지능 개념 일러스트

데이터 사이언스의 활용 사례는 대량의 데이터가 축적되었거나 축적될 수 있는 거의 모든 산업과 연결됩니다.  오프라인 매장과 전자상거래 웹사이트는 마케팅 캠페인에 이끌린 사람들이 실제로 고객 경험을 하는 곳이며, 특정 브랜드나 회사의 귀중한 구매 데이터가 수집되는 장소입니다. 여기에서 사람들은 특정 상품을 정말로 살지, 계획에 없던 다른 것을 사볼지, 얼마를 지불할 의향이 있는지, 다시 이 가게를 찾을지, 그리고 자신의 고객 경험에 대해 어떤 후기를 남길지를 최종적으로 결정합니다. 

실제로 고객 후기는 전체 판매 과정에서 무엇을 바꾸거나 강화해야 하는지 분석하고 이해할 수 있는 탄탄한 데이터 원천입니다. 이런 방식으로 데이터를 분석하면 비용 절감, 운영 효율 향상, 고객 경험 개선, 새로운 기회 발굴, 비즈니스 성장, 궁극적으로는 매출 증대까지 기대할 수 있습니다. 이제 이 소중한 정보를 데이터 사이언스 알고리즘으로 어떻게 분석·모델링해 숨겨진 인사이트를 얻고, 각 개인 고객의 전반적인 메시지를 포착할 수 있는지 자세히 살펴보겠습니다.

영업에서의 데이터 사이언스 활용 사례: 고객 감성 분석 

고객 감성 분석은 특정 회사의 제품이나 서비스를 사용할 때 고객의 감정을 자동으로 식별하는 과정입니다. 보통 온라인 설문, 소셜 미디어, 지원 티켓, 피드백 양식, 상품 리뷰, 포럼, 전화 통화, 이메일, 챗봇 등에서 수집된 비정형 텍스트 데이터가 대상입니다. 머신러닝에서 고객 감성 분석은 자연어 처리(NLP)를 통해 수행되며, 통계적·언어학적 방법을 적용해 텍스트 데이터에서 긍정, 부정, 중립 감성을 직접 추출합니다. 본질적으로 두 가지 지표를 산출합니다:

  • 극성(Polarity): 감성이 긍정인지 부정인지를 나타냅니다.
  • 강도(Magnitude): 해당 감성의 강도를 나타냅니다.

고객 감성 분석은 실행 가능한 인사이트를 얻고, 고객을 불만족하게 만드는 반복적인 중대 이슈를 파악·해결하며, 긍정적 감정을 이끄는 제품/서비스 기능을 강화하고, 전반적으로 더 효율적인 데이터 기반 의사결정을 내리도록 돕는 현대 비즈니스의 핵심 도구입니다. 좀 더 세분화하면, 고객 감성 분석을 통해 다음을 할 수 있습니다:

  • 고객 서비스를 개선해 고객 경험을 향상하고,
  • 고객 충성도를 높이며,
  • 이탈률을 낮추고,
  • 제품과 서비스를 적시에 업그레이드하고,
  • 마케팅 캠페인을 최적화하고,
  • 새로운 트렌드와 시장을 예측하며,
  • 자사 평판을 높게 유지하고,
  • 수익을 증대합니다.

다른 텍스트 분석 과제와 마찬가지로, 고객 감성 분석을 수행하는 동안 몇 가지 함정을 만날 수 있습니다. 예를 들어, 일부 리뷰에 담긴 풍자를 NLP 알고리즘이 포착하지 못해 잘못 분류할 수 있습니다. 또한 매우 특이한 약어나 드물게 쓰이는 속어를 해석하지 못하는 경우도 있습니다.

데이터셋 준비

IMDB 영화 리뷰 데이터셋을 활용해 고객 감성 분석이 실제로 어떻게 작동하는지 살펴보겠습니다:

import pandas as pd

movies = pd.read_csv('movies.csv', index_col=0).reset_index(drop=True)
print(f'Number of reviews: {movies.shape[0]:,}\n')
print(movies.head())
Number of reviews: 7,501

                                              review  label
0  This short spoof can be found on Elite's Mille...      0
1  A singularly unfunny musical comedy that artif...      0
2  An excellent series, masterfully acted and dir...      1
3  The master of movie spectacle Cecil B. De Mill...      1
4  I was gifted with this movie as it had such a ...      0

열은 두 개입니다. 각 리뷰의 텍스트가 담긴 열과 전체 감성의 평가값이 담긴 열로, 긍정(1) 또는 부정(0)입니다.

긍정 및 부정 리뷰의 비율을 계산해 보겠습니다:

round(movies['label'].value_counts()*100/len(movies['label'])).convert_dtypes()
0    50
1    50
Name: label, dtype: Int64

따라서 긍정과 부정 리뷰의 비중이 거의 같습니다.

BOW 방법 적용 

다음 단계는 텍스트 데이터를 수치형으로 변환하는 것입니다. 머신러닝 모델은 수치형 특성만 처리할 수 있기 때문입니다. 특히 각 리뷰에서 각 단어가 몇 번 등장하는지 세는 특성을 만들 것입니다. 이를 위한 가장 기본적이고 직관적인 방법은 단어 주머니(BOW, bag-of-words)로, 문서에 등장하는 모든 단어의 어휘집을 구축하고 각 리뷰에서 단어별 빈도를 계산합니다. 그 결과 각 단어마다 해당 빈도를 담은 새로운 특성이 만들어집니다.

우리 데이터셋에 BOW 방법을 적용해 보겠습니다:

from sklearn.feature_extraction.text import CountVectorizer

# Creating new features
vect = CountVectorizer(max_features=200)
vect.fit(movies.review)
X_review = vect.transform(movies.review)
X_df = pd.DataFrame(X_review.toarray(), columns=vect.get_feature_names())

# Combining the new features with the label
movies_bow = pd.concat([movies['label'], X_df], axis=1)
print(movies_bow.head())
  label  10  about  acting  action  actors  actually  after  again  all  ...  \
0      0   0      0       0       0       0         0      0      0    0  ...  
1      0   1      0       1       0       1         0      0      0    3  ...  
2      1   0      0       0       0       0         0      1      0    0  ...  
3      1   0      0       0       1       0         0      0      0    0  ...  
4      0   1      0       0       1       0         0      0      0    3  ...  

  will  with  without  work  world  would  years  you  young  your 
0     0     1        0     0      0      1      0    0      0     0 
1     2     7        1     0      0      2      0    3      0     2 
2     0     2        0     0      0      0      0    0      1     0 
3     0     0        0     0      0      0      0    1      1     0 
4     0     2        0     1      0      0      0    0      0     0 

[5 rows x 201 columns]

위 코드에서는 선택적 매개변수인 max_features를 적용해 가장 자주 쓰이는 200개 단어만 고려하여 잠재적 과적합을 피했습니다.

감성 예측을 위한 지도학습 모델 사용

이제 지도학습 모델을 사용해 감성을 예측해 보겠습니다. 이미 레이블이 붙은 리뷰를 바탕으로 새 리뷰의 감성이 긍정 또는 부정 범주에 속하는지 추정하려 하므로, 다시 한 번 분류 문제를 다루게 됩니다. 여기서도 로지스틱 회귀 알고리즘을 사용해 모델 정확도를 측정해 보겠습니다:

Accuracy score: 0.754

Confusion matrix:
[[37.62772101 13.23856064]
[11.32829853 37.80541981]]

모델은 전체 리뷰 중 긍정이었던 것을 11%는 부정으로, 부정이었던 것을 13%는 긍정으로 표시했습니다. 정확도를 높이기 위한 방안으로는 불용어(예: "about", "will", "you" 등처럼 너무 자주 등장해 정보량이 낮은 단어)를 제외하거나, 어휘집의 크기를 늘리는 방법을 고려할 수 있습니다.

BOW 방법을 적용하면 데이터프레임에 수백 혹은 수천 개의 새 특성이 생길 수 있습니다. 그 결과 불필요한 특성과 매개변수가 너무 많아 지나치게 복잡하고 과적합된 모델이 될 수 있습니다. 이를 해결하는 한 가지 방법은 정규화로, 모델의 함수를 제한합니다. 여기서 조정할 매개변수는 C로, 정규화의 강도를 나타냅니다. 이 매개변수의 값 100과 0.1을 시험해 보고, 어떤 값이 테스트 데이터에서 더 나은 성능을 보이는지 확인해 보겠습니다:

lr_1 = LogisticRegression(C=100)
lr_1.fit(X_train, y_train)
predictions_1 = lr_1.predict(X_test)

lr_2 = LogisticRegression(C=0.1)
lr_2.fit(X_train, y_train)
predictions_2 = lr_2.predict(X_test)

print(f'Accuracy score, lr_1 model: {round(accuracy_score(y_test, predictions_1), 3)}\n'
      f'Accuracy score, lr_2 model: {round(accuracy_score(y_test, predictions_2), 3)}\n\n'
      f'Confusion matrix for lr_1 model, %:\n{confusion_matrix(y_test, predictions_1)/len(y_test)*100}\n\n'
      f'Confusion matrix for lr_2 model, %:\n{confusion_matrix(y_test, predictions_2)/len(y_test)*100}')
Accuracy score, lr_1 model: 0.753
Accuracy score, lr_2 model: 0.756

Confusion matrix for lr_1 model, %:
[[37.53887161 13.32741004]
[11.32829853 37.80541981]]

Confusion matrix for lr_2 model, %:
[[37.67214571 13.19413594]
[11.19502443 37.93869391]]

선택한 C 값들 사이에서 모델 정확도의 차이는 미미합니다. 더 많은 값을 실험하면 성능을 더 개선할 수 있는 매개변수를 찾을 수도 있겠습니다. 다만 여기서는 새 특성이 200개뿐이므로 모델이 그리 복잡하지 않아, 정규화 단계가 필수적이진 않습니다.

predict 함수를 사용해 0 또는 1의 레이블을 예측하는 대신, predict_proba로 감성의 확률을 예측할 수도 있습니다. 이때 예측 확률에는 정확도나 혼동 행렬을 직접 적용할 수 없다는 점을 유의해야 합니다. 이런 지표는 클래스에만 적용되므로, 확률을 다시 클래스 형태로 인코딩해야 합니다. 기본적으로 0.5 이상인 확률은 클래스 1, 그 미만은 클래스 0으로 변환됩니다.

lr = LogisticRegression()
lr.fit(X_train, y_train)

# Predicting the probability of the 0 class
predictions_prob_0 = lr.predict_proba(X_test)[:, 0]

# Predicting the probability of the 1 class
predictions_prob_1 = lr.predict_proba(X_test)[:, 1]

print(f'First 10 predicted probabilities of class 0: {predictions_prob_0[:10].round(3)}\n'
      f'First 10 predicted probabilities of class 1: {predictions_prob_1[:10].round(3)}')
First 10 predicted probabilities of class 0: [0.246 0.143 0.123 0.708 0.001 0.828 0.204 0.531 0.121 0.515]
First 10 predicted probabilities of class 1: [0.754 0.857 0.877 0.292 0.999 0.172 0.796 0.469 0.879 0.485]

결론 

보다 세밀한 감성 분석을 위해 데이터셋에 적용할 수 있는 다른 유용한 접근법도 많습니다:

  • 문맥을 보존하기 위해 개별 단어 대신 n그램(단어의 조합) 사용,
  • 불용어 제외,
  • 상한·하한 빈도 기준으로 어휘집 크기 제한,
  • 각 리뷰의 길이 또는 문장부호의 개수와 같은 수치형 추가 특성 생성(후자는 때때로 감성의 강도와 상관 관계가 있을 수 있음),
  • 숫자, 일부 문자, 특정 길이의 단어를 제외하거나 더 복잡한 단어 패턴 고려,
  • 어간 추출과 표제어 추출 적용, 즉 단어를 어근으로 축소,
  • BOW보다 정교한 어휘집 생성 방식 사용. 예를 들어 TfIdf(역문서 빈도 가중치)는 특정 단어가 다른 리뷰 대비 해당 리뷰에서 얼마나 자주 등장하는지를 반영합니다.
  • TextBlob, SentiWordNet, VADER(Valence Aware Dictionary and Sentiment Reasoner) 등 감성 분석을 위해 설계된 특화 라이브러리 활용.

이러한 기법과 그 외 유용한 방법을 통해 통찰력 있는 감성 분석을 더 깊이 탐구하고 싶다면 Sentiment Analysis in Python 과정을 확인해 보세요.

주제
데이터 사이언스
Machine Learning