데이터 분석 part

차원축소, 계층적 군집 분석, 시계열데이터 예측 (회귀분석, 이동평균(MA), 지수 가중 이동 평균 (EMA)) / 마케팅 보고서 작성 연습

bleufonce 2025. 3. 14. 18:17

 

※ 데이터에서의 '차원' 표현

데이터에서의 차원은 데이터를 표현하거나 구조화하는 방식과 관련이 있다.

 

  • 스칼라(0D): 하나의 숫자 값(단일 데이터 포인트)으로 차원이 없다. (예 : 3)
  • 1차원(1D): 값들이 한 줄로 나열된 형태 (예 : [3, 4, 5])
  • 2차원(2D): 값들이 행과 열 형태로 정렬된 구조. (예 : 행렬(Matrix), 표(Table, DataFrame), 흑백이미지) 이때, 변수의 개수에 따라 차원이 결정됨. 행과 열이 있는 데이터 구조는 2차원으로 이해하고, 이때 열(변수)의 개수에 따라 차원이 달라진다. - 데이터 분석 관점에서 볼 때

수학에서의 행렬
엑셀 시트, SQL 테이블, 판다스 데이터프레임

 

배열로 표현하면 :

 

  • 3차원(3D): 여러 개의 2D 행렬이 쌓인 형태로, 더 높은 차원 데이터 구조를 형성. (예 : 컬러 이미지 데이터)

가로픽셀(너비) : 한 행에 있는 리스트의 개수 → 3개 // 세로픽셀(높이) : 행(가로줄)의 개수 → 3개 // RGB 채널 : [ ] 안에 있는 값들 [R, G, B] → 3개

 

  • 4차원(4D): 3D 배열들을 추가적으로 묶은 형태. (예 : 비디오 데이터)

프레임(시간)이 추가됨.

 

 

 

※ 데이터에서 차원변수의 개수를 의미한다. 차원 축소변수의 개수(차원)를 줄이는 방법이다. 데이터를 더 간단하게 만드는 과정이다.

 

 

 

※ 데이터의 중요한 공통된 특징들을 압축하고 시각적으로 단순화 (차원축소)

 

 

고차원 데이터의 각 차원간의 공통적으로 중요한 특징들만 추출한다.

공통된 특징들을 한곳으로 투영(projection)하면 위에서 봤을때 각 층의 공통적인 부분이 겹쳐서 하나의 층으로 보인다.

차원축소의 핵심은 고차원 데이터의 중요한 공통 특징만을 추출하여 저차원으로 표현하는 것이다. (PCA)

 

 

 

< 차원축소 >

차원 축소(Dimensionality Reduction)란?

차원 축소는 데이터의 특성(변수) 개수를 줄이면서도 중요한 정보를 최대한 유지하는 기법이다. 데이터의 차원이 너무 많으면 연산 비용이 증가하고, 불필요한 변수(노이즈)로 인해 모델의 성능이 떨어질 수 있다. 고차원 데이터를 더 적은 수의 차원으로 변환하는 차원 축소를 하면 데이터 분석이 더 효율적이고 직관적으로 가능해진다.

 

※ 단순히 변수 몇개를 버리는 게 아니라, 정보를 최대한 유지하면서 줄이는 방법을 찾는 게 핵심

PCA로 2차원을 1차원으로 투영

 

→ 데이터의 분산(변화량)을 가장 잘 설명할 수 있는 축(주성분)을 찾고, 이 과정에서 덜 중요한 부분은 제거.

 

PCA를 이용해 3차원 데이터(왼쪽그림)을 2차원 데이터로 투영하여 주요 정보를 유지하면서 더 단순화했다. (오른쪽그림)

 

→ 3차원 데이터를 위에서 보면, 차원의 공통적인 특징이 겹쳐 보일 수 있다. PCA를 통해 공통적인 특징을 추출하고, 덜 중요한 부분을 제거하면, 저차원의 평면(오른쪽 그림)으로 투영된다. 이때, 공통적인 특징들은 PCA 값으로 저장된다.

 

차원 축소 방법

차원 축소 방법은 크게 두 가지로 나뉜다 :

  1. 특징 선택(Feature Selection): 기존 변수 중에서 중요한 것만 선택
  2. 특징 추출(Feature Extraction): 기존 변수를 조합해서 새로운 변수 생성

PCA(주성분 분석)"특징 추출(Feature Extraction)" 방법을 사용하는 차원 축소 기법이다. ( PCA, LDA, t-SNE 등)

 

대표적인 차원 축소 기법

  1. 주성분 분석(PCA, Principal Component Analysis) - 압도적으로 많이 쓰는 방법 ☆
    • 고차원 데이터를 저차원으로 변환하면서 분산(데이터의 정보량)을 최대한 유지하는 방법
    • 선형 변환을 사용해 원래 변수들을 새로운 축(주성분)으로 정렬 (선형 차원 축소 방법)
    • 새로운 축을 따라 데이터를 투영함으로써 차원을 축소
    • 속도와 효율성, 정보보존 측면에서 강력. (시각화와 노이즈 제거에서 적절한 균형)
  2. 선형판별분석(LDA, Linear Discriminant Analysis)
    • PCA와 유사하지만, 클래스 간 분산을 최대화하는 방향으로 차원을 축소하는 방법
    • 지도 학습(supervised learning)에서 사용되며, 주로 분류 문제에 적용
  3. t-SNE(t-Distributed Stochastic Neighbor Embedding)
    • 고차원 데이터를 2D 또는 3D로 변환해 시각화하는 데 유용
    • 데이터의 지역적 구조(유사한 데이터끼리 가까이 있도록 유지)를 보존하는 것이 특징
    • PCA와 달리 비선형 차원축소 방법
  4. UMAP (Uniform Manifold Approximation and Projection)
    • t-SNE와 유사하지만 더 빠르고 시각적으로 해석 가능한 결과를 제공하는 비선형 차원 축소 기법.

 

차원 축소의 장점

  • 데이터의 이해와 해석을 용이하게 한다.
  • 시각화를 통해 고차원 데이터의 패턴을 파악할 수 있다.
  • 모델의 계산 복잡도를 줄이고, 과적합을 방지할 수 있다.

 

차원 축소의 응용 분야

  1. 데이터 시각화: 고차원 데이터를 2D 또는 3D로 축소하여 시각화할 수 있다. 이는 데이터의 패턴이나 클러스터를 시각적으로 탐색하는 데 유용하다.
  2. 노이즈 제거: 데이터에서 노이즈를 제거하고 중요한 특징만을 남겨 분석 성능을 개선할 수 있다.
  3. 컴퓨터 비전: 이미지 데이터의 차원을 축소하여 분석하거나, 고차원 피처를 줄여 처리 속도를 향상시킬 수 있다.
  4. 자연어 처리: 텍스트 데이터의 차원을 축소하여 텍스트 간의 유사성을 비교하거나, 주제를 분석하는 데 사용된다. (임베딩할 때 많이 씀)

 

주성분 분석 (PCA)

# PCA의 기본 원리

 

  • 공분산 행렬을 사용하여 데이터의 분산이 최대인 축을 찾는다.
  • 그 주성분 축으로 데이터를 투영하여 저차원 공간으로 변환함으로써 차원을 축소한다.

 

 

 

 

# PCA 진행 과정

※ 변수들의 단위/범위가 다르면 사전에 데이터 정규화 필수.

 

1. 공분산 행렬 계산

  • 변수들 간의 관계를 공분산 행렬로 계산하여, 데이터가 가장 넓게 퍼진 방향 (정보가 많은 방향)을 찾는다.

2. 고유벡터와 고유값 계산

  • 고유벡터: 데이터가 가장 넓게 퍼진 방향(주성분)
  • 고유값: 각 주성분이 설명하는 데이터 분산의 크기 (큰 값일수록 중요)

3. 주성분 선택

  • 고유값이 큰 순서대로 고유벡터(주성분)를 정렬한다.
  • 누적 분산(설명 가능한 데이터 비율)을 기준으로 적절한 개수의 고유벡터들을 선택한다.

4. 데이터를 새로운 축으로 투영(Projection)

  • 데이터를 선택된 고유벡터들로 이루어진 새로운 축으로 투영하여 저차원 공간에 표현한다.

 

※ 공분산

두 개의 확률 변수 간의 관계를 나타내는 통계적 측정치. 공분산은 두 변수의 값이 서로 어떻게 변동하는지를 나타낸다.

  1. 양의 공분산: 두 변수가 같은 방향으로 변동할 때, 즉 한 변수가 증가할 때 다른 변수도 증가하는 경향이 있을 때 공분산은 양수이다.
  2. 음의 공분산: 두 변수가 반대 방향으로 변동할 때, 즉 한 변수가 증가할 때 다른 변수가 감소하는 경향이 있을 때 공분산은 음수이다.
  3. 0에 가까운 공분산: 두 변수 간에 특별한 관계가 없을 때, 즉 두 변수의 변동이 독립적일 때 공분산은 0에 가까워진다.

 

 

- 차원 축소와 주성분 분석(PCA)을 이용한 데이터 압축 방법에 대한 예시

!pip install scikit-learn opencv-python matplotlib

import cv2
import matplotlib.pyplot as plt
import numpy as np
from sklearn.decomposition import PCA

# 1. 이미지 로드 및 전처리
def load_image(image_path, target_size=(128, 128)):
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)  # 이미지 흑백 변환
    img_resized = cv2.resize(img, target_size)  # 이미지 크기 조정
    return img_resized

# 2. 이미지 차원 축소 및 복원
def reduce_and_reconstruct_image(image, n_components=1):
    pca = PCA(n_components=n_components)
    original_shape = image.shape
    image_flattened = image.flatten().reshape(1, -1)  # 이미지를 1차원 벡터로 변환
    
    # PCA 차원 축소
    image_reduced = pca.fit_transform(image_flattened)
    
    # 복원
    image_reconstructed = pca.inverse_transform(image_reduced)
    image_reconstructed = image_reconstructed.reshape(original_shape)  # 원래 이미지 형태로 복원
    
    return image_reconstructed

# 3. 이미지 저장 및 시각화
def save_and_display_images(original_image, reconstructed_image, output_path='reconstructed_image.png'):
    # 이미지 저장
    cv2.imwrite(output_path, reconstructed_image)
    
    # 시각화
    plt.figure(figsize=(8, 4))
    plt.subplot(1, 2, 1)
    plt.imshow(original_image, cmap='gray')
    plt.title('Original Image')
    plt.axis('off')
    
    plt.subplot(1, 2, 2)
    plt.imshow(reconstructed_image, cmap='gray')
    plt.title('Reconstructed Image')
    plt.axis('off')
    
    plt.show()

# 4. 메인 실행 함수
def main(image_path, output_path='reconstructed_image.png', n_components=1):
    original_image = load_image(image_path)
    reconstructed_image = reduce_and_reconstruct_image(original_image, n_components=n_components)
    save_and_display_images(original_image, reconstructed_image, output_path)

# 예제 실행
image_path = '/content/1.png'  # 입력 이미지 경로를 설정합니다.
main(image_path)

데이터를 많이 소실했음에도 오리지날 이미지와 복원된 이미지가 주성분이 살아있기 때문에 비슷하게 나옴.

(공통특징들을 PCA값으로 저장했기 때문에)

 

 

# 그로스 마케팅에서 차원 축소 활용 예제

  • 목표: 고객 데이터를 차원 축소하여 그룹별 특성 분석
  • 데이터: 페이지 방문 수, 광고 클릭 수, 구매 횟수, 구매 금액

- 차원 축소기법 중 하나인 PCA(주성분 분석)를 활용하여 고객 행동 데이터를 분석하는 예제. K-means 클러스터링을 적용하여 고객 그룹을 나누는 과정까지 포함함.

# 그로스 마케팅에서 차원 축소 활용 예제

import numpy as np                             	   # 데이터 처리
import pandas as pd                                # 데이터 처리
import matplotlib.pyplot as plt                    # 시각화
import koreanize_matplotlib
from sklearn.decomposition import PCA              # 차원축소 (PCA)
from sklearn.preprocessing import StandardScaler   # 데이터 정규화
from sklearn.cluster import KMeans                 # K-means 군집화

# 하드 코딩된 고객 행동 데이터 (그로스 마케팅)
data = {
    "Page_Visits": [15, 25, 30, 80, 95, 120, 150, 200, 250, 300,
                    320, 400, 450, 500, 550, 600, 700, 750, 800, 850],
    "Ad_Clicks": [1, 3, 5, 10, 12, 20, 25, 35, 40, 50,
                  60, 70, 80, 90, 100, 110, 120, 130, 140, 150],
    "Purchases": [0, 1, 1, 3, 5, 6, 10, 12, 15, 18,
                  20, 25, 30, 35, 40, 45, 50, 55, 60, 65],
    "Revenue": [50, 80, 120, 200, 250, 300, 500, 700, 900, 1100,
                1300, 1600, 2000, 2400, 2800, 3200, 3700, 4200, 4700, 5200]
}

# 데이터프레임 변환
df = pd.DataFrame(data)

# 데이터 정규화 (PCA를 위해 필수)
# StandardScaler()를 사용해서 모든 데이터를 평균 0, 표준편차 1로 변환.
# 정규화를 하지 않으면 Revenue처럼 값이 큰 변수가 PCA에 너무 많은 영향을 줄 수 있다.
scaler = StandardScaler()
scaled_data = scaler.fit_transform(df)

# PCA 적용 (2차원으로 축소)  > 4차원 데이터를 2차원 데이터로 바꾸는 것 (컬럼수가 4개니까 4차원데이터)
# 4개의 변수를 2개의 주성분으로 축소하기 위해 n_components=2 로 설정하고 축소된 데이터를 pca_result에 저장한다.
pca = PCA(n_components=2)                    # 원래 데이터는 4차원(4개의 변수) → 이를 2차원(PC1,PC2)으로 축소
pca_result = pca.fit_transform(scaled_data)  # fit_transform()을 사용하여 데이터를 주성분으로 변환 

# 변환된 결과를 데이터프레임으로 변환
# 축소된 정보 pca_result를 'PC1', 'PC2' 두가지 컬럼으로 구성된 데이터프레임 df_pca를 생성한다.
df_pca = pd.DataFrame(pca_result, columns=['PC1', 'PC2'])

# K-means를 이용한 고객 군집화 (3개 그룹)
# 2차원으로 축소한 데이터를 K-means를 이용해 3개 그룹으로 분류하고 fit_predict를 사용하여 각 데이터 포인트에 대한 cluster 할당.
kmeans = KMeans(n_clusters=3, random_state=42)   # k-means 알고리즘을 통해 3개의 그룹으로 분류
df_pca['Cluster'] = kmeans.fit_predict(df_pca)   # 구분한 결과를 cluster 컬럼에 할당

# 차원 축소된 데이터 시각화 
# 4차원 데이터 중 주성분을 뽑아 2차원으로 만든 후 클러스터링한 결과를 시각화
# PC1, PC2를 x축/y축으로 두고 산점도(Scatter Plot)로 표현
plt.figure(figsize=(8, 6))
plt.scatter(df_pca['PC1'], df_pca['PC2'], c=df_pca['Cluster'], cmap='viridis', alpha=0.7)
plt.xlabel("주성분 1 (PC1)")
plt.ylabel("주성분 2 (PC2)")
plt.title("PCA 기반 고객 행동 데이터 차원 축소 및 군집화")
plt.colorbar(label="Cluster")
plt.show()

 

 

  • 데이터 정규화 (StandardScaler 적용)
    • PCA를 적용하기 전에 데이터의 스케일(크기)을 맞추는 과정이 필요함.
    • StandardScaler()를 사용해서 모든 데이터를 평균 0, 분산 1이 되도록 변환.
  • PCA(주성분 분석) 적용 → 2차원으로 차원 축소 (변수가 n개면 데이터는 n차원 공간에 존재한다!)
    • 기존 데이터는 4개의 특징(변수)로 구성되어 있음. (4차원)
    • PCA를 통해 데이터를 2개의 차원(PC1, PC2)으로 축소.
    • 차원 축소 후에도 데이터의 분산을 최대한 보존하도록 변환.
  • K-means 클러스터링 적용
    • 차원 축소된 데이터를 3개의 그룹으로 군집화.
    • kmeans.fit_predict()를 사용해 각 데이터 포인트가 어느 그룹에 속하는지 예측.
  • PCA 결과 시각화
    • 군집화된 데이터를 산점도로 시각화하여 고객 행동을 그룹별로 확인.

 

※ 그럼 PCA로 줄인 두개 변수는 어떤 특징을 갖고 있는지 어떻게 확인할까?

# 주성분 로딩 출력
print(pca.components_)

이 결과는 PC1(주성분1)과 PC2(주성분2)가 각각 '페이지 방문 수', '광고 클릭 수', '구매 횟수', '구매 금액' 변수에 얼마나 영향을 미치는지 보여준다. (주성분 로딩 값) 

첫째 줄은 주성분 1 (PC1)이 각 변수에 얼마나 영향을 미치는지를 나타냄.  

페이지 방문 수: 0.50038605 , 광고 클릭 수: 0.5000091 , 구매 횟수: 0.5010076 , 구매 금액: 0.49859411

PC1은 전체적으로 모든 변수에 고르게 영향을 미친다는 것을 의미.

즉, 주성분 1은 '고객의 전반적인 행동 패턴'을 나타낼 수 있다고 볼수 있음.

 

둘째 줄은 주성분 2(PC2)이 각 변수에 얼마나 영향을 미치는지를 나타냄. 

페이지 방문 수: -0.3790927 , 광고 클릭 수: -0.49319569 , 구매 횟수: 0.09772735 , 구매 금액: 0.77685011

PC2는 구매 금액에 가장 큰 영향을 미치며, 그 다음으로 광고 클릭 수와 페이지 방문 수에 영향을 미친다. 구매 횟수는 상대적으로 적은 영향을 미치는 것으로 보여짐.

음수 값이라도 그 변수들이 주성분에 기여하고 있다는 점에서는 차이가 없고, 단지 방향이 반대라는 것임. 

페이지 방문 수와 광고 클릭 수는  PC2 값이 높을수록 상대적으로 낮은 값을 가진다는 뜻. 반면에 구매 금액은 PC2 값이 높을수록 높은 값을 가진다는 뜻.

 

 

 

- 위 코드로 변수많은 csv 파일을 차원축소

customer_segmentation.csv
0.01MB

# customer_segmentation 파일로 위 코드 통해 실습

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans


# 데이터프레임 변환
df = pd.read_csv("customer_segmentation.csv")

# 데이터 정규화 (PCA를 위해 필수)
scaler = StandardScaler()
scaled_data = scaler.fit_transform(df)

# PCA 적용 (2차원으로 축소)
pca = PCA(n_components=2)
pca_result = pca.fit_transform(scaled_data)

# 변환된 결과를 데이터프레임으로 변환
df_pca = pd.DataFrame(pca_result, columns=['PC1', 'PC2'])

# K-means를 이용한 고객 군집화 (3개 그룹)
kmeans = KMeans(n_clusters=3, random_state=42)
df_pca['Cluster'] = kmeans.fit_predict(df_pca)

# 차원 축소된 데이터 시각화
plt.figure(figsize=(8, 6))
plt.scatter(df_pca['PC1'], df_pca['PC2'], c=df_pca['Cluster'], cmap='viridis', alpha=0.7)
plt.xlabel("주성분 1 (PC1)")
plt.ylabel("주성분 2 (PC2)")
plt.title("PCA 기반 고객 행동 데이터 차원 축소 및 군집화")
plt.colorbar(label="Cluster")
plt.show()

# 주성분 로딩 출력
print(pca.components_)

 

 

 


 

 

계층적 군집분석

※ 잘 사용하지 않음. 효율적이지 않음..

 

데이터를 계층적인 구조로 그룹화하는 군집 분석 기법 중 하나. 이 방법은 데이터의 유사성을 기반으로 트리 구조(덴드로그램, Dendrogram)를 생성하며, 주로 병합형 계층적 군집 분석(상향식)과 분할형 계층적 군집분석(하향식)의 두 가지 방식으로 수행된다.

  • 군집 간 계층적 구조를 형성하며, 결과를 트리 형태(덴드로그램)로 표현
  • 사전에 군집의 개수를 정하지 않아도 됨
  • 주어진 데이터의 유사성을 기준으로 군집을 병합(또는 분할)하며 진행

- 데이터간의 거리를 측정해서 유사성을 판단함 : 유클리드 거리, 맨해튼 거리, 코사인 유사도 방법

 

 

- 계층적 군집분석을 수행한 후 덴드로그램과 클러스터링 결과를 시각화

# 고객 세분화를 통한 맞춤형 마케팅 전략 수립
# 샘플 고객 데이터를 생성하고 계층적 군집 분석을 수행한 후 덴드로그램과 클러스터링 결과를 시각화

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster

# 1. 샘플 고객 데이터 생성 (월 평균 구매 금액, 방문 빈도, 고객 평점)
np.random.seed(42)
num_customers = 20

customer_data = pd.DataFrame({
    'Customer_ID': range(1, num_customers + 1),
    'Monthly_Spending': np.random.randint(50, 500, size=num_customers),   # 월 평균 구매 금액 ($)
    'Visit_Frequency': np.random.randint(1, 20, size=num_customers),      # 월 방문 빈도 (회)
    'Customer_Satisfaction': np.random.randint(1, 10, size=num_customers) # 고객 평점 (1~10)
})

# 2. 계층적 군집 분석 수행
X = customer_data[['Monthly_Spending', 'Visit_Frequency', 'Customer_Satisfaction']].values
linked = linkage(X, method='ward')

# 3. 덴드로그램 시각화
plt.figure(figsize=(10, 5))
dendrogram(linked, labels=customer_data['Customer_ID'].values, leaf_rotation=90)
plt.title("Hierarchical Clustering Dendrogram")
plt.xlabel("Customer ID")
plt.ylabel("Distance")
plt.show()

# 4. 최적의 군집 개수를 지정하여 클러스터 할당 (예: 3개)
num_clusters = 3
customer_data['Cluster'] = fcluster(linked, num_clusters, criterion='maxclust')

# 5. 군집별 고객 분포 시각화
plt.figure(figsize=(8, 6))
sns.scatterplot(data=customer_data, x="Monthly_Spending", y="Visit_Frequency", hue="Cluster", palette="viridis", s=100)
plt.title("Customer Segmentation using Hierarchical Clustering")
plt.xlabel("Monthly Spending ($)")
plt.ylabel("Visit Frequency (times/month)")
plt.legend(title="Cluster")
plt.show()

# 6. 결과 데이터 출력 (오류나서 코드바꿈)
import ace_tools_open as tools
tools.display_dataframe_to_user(name="Customer Segmentation Data", dataframe=customer_data)

※ import ace_tools as tools가 오류날때..

설치를 pip install ace_tools_open 이 코드로 한다.

적용을 import ace_tools_open as tools 이 코드로 한다.

근데 이것도 됐다가 안됐다가 함. 꼭 필요한 경우 아니면 다른 방법으로..

 

 

 


 

< 시계열 데이터 예측 >

 

  • 이동 평균(MA, Moving Average)
    • 일정 기간의 평균값을 계산해서 노이즈를 줄이고 추세를 부드럽게 만드는 기법.
  • 지수 가중 이동 평균(EMA, Exponential Moving Average)
    • 최근 데이터에 더 큰 가중치를 부여해서 변화에 더 빠르게 반응하는 이동 평균 방식.
  • 회귀 분석(Regression Analysis)
    • 종속 변수와 독립 변수의 관계를 찾고, 이를 바탕으로 미래 값을 예측하는 모델링 기법.
    • 선형 회귀, 다항 회귀, 랜덤 포레스트 회귀 등 다양한 방법이 있음.

 

이동 평균과 EMA는 데이터 전처리(특징 엔지니어링) 과정에서 활용될 수 있음.
예를 들어, 이동 평균 값을 새로운 변수(특징)로 추가한 후, 회귀 모델을 학습시켜 예측 성능을 높일 수 있음.

 

회귀 분석을 통한 시계열 데이터 예측

 

1. 특징 엔지니어링 (Feature Engineering)

시계열 데이터에는 시간(Year, Month, Day)과 같은 변수를 독립 변수(특징)로 사용할 수 있다.

이동 평균, 지수 가중 이동 평균(EMA) 등을 추가하면 예측 정확도를 높일 수 있다. → 이 방법이 효과 더 좋음.

 

2. 회귀 모델 선택

  • 선형 회귀 : 기본적인 추세 예측
  • 다항 회귀 : 비선형 추세 예측 가능
  • 랜덤 포레스트 회귀 : 시계열 변동성이 클 경우 강력한 성능을 발휘
  • LSTM, XGBoost 등 딥러닝/머신러닝 모델도 활용 가능

시계열 데이터에서 회귀 분석을 활용하면 비교적 간단한 방식으로 미래 값을 예측할 수 있다. 추세가 선형적일 경우 선형 회귀, 변동성이 클 경우 랜덤 포레스트 회귀 또는 LSTM을 활용하여 보다 정교한 예측이 가능하다.

 

- 선형 회귀를 활용한 시계열 데이터 예측 (선형회귀 단독으로)

# 선형 회귀를 활용한 시계열 예측

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

# 1. 데이터 생성 (지난 3년간 월별 매출 데이터)
date_range = pd.date_range(start="2021-01-01", periods=36, freq="M")
np.random.seed(42)
sales = np.linspace(100, 300, num=36) + np.random.randint(-20, 20, size=36)  # 추세 + 변동성 추가

# 데이터프레임 구성
data = pd.DataFrame({'Date': date_range, 'Sales': sales})
data['Month'] = data['Date'].dt.month
data['Year'] = data['Date'].dt.year
data['Time_Index'] = range(1, len(data) + 1)  # 시간 순서 인덱스 생성

# 2. 독립 변수(X)와 종속 변수(y) 설정
X = data[['Time_Index']]
y = data['Sales']

# 3. 훈련 데이터와 테스트 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# 4. 선형 회귀 모델 학습
model = LinearRegression()
model.fit(X_train, y_train)

# 5. 향후 6개월 예측
future_dates = pd.date_range(start="2024-01-01", periods=6, freq="M")
future_index = np.arange(len(data) + 1, len(data) + 7).reshape(-1, 1)
future_sales = model.predict(future_index)

# 6. 시각화: 실제 vs 예측
plt.figure(figsize=(10, 5))
plt.plot(data['Date'], data['Sales'], label="Actual Sales", marker='o')
plt.plot(future_dates, future_sales, label="Predicted Sales", marker='s', linestyle="dashed")
plt.xlabel("Date")
plt.ylabel("Sales")
plt.title("Sales Prediction using Linear Regression")
plt.legend()
plt.xticks(rotation=45)
plt.show()

 

 

이동 평균 (MA) & 지수 가중 이동 평균 (EMA)

 

1. 이동 평균(MA)

  • 일정 기간(n일)의 데이터를 평균 내어 변화 패턴을 부드럽게 만드는 기법
  • 목적: 단기적인 변동성을 줄이고 전체적인 흐름을 확인하는 것
  • 예제:
    • 7일 이동 평균 → (D1 + D2 + D3 + D4 + D5 + D6 + D7) / 7
    • 7일 이동 평균은 매일 새로운 데이터가 들어오면서 가장 오래된 데이터는 제외됨

이동 평균의 특징

  • 단순 이동 평균(SMA)은 모든 데이터에 동일한 가중치를 줌 → 즉, 7일치 데이터면 각각 1/7의 비중
  • 장기 이동 평균(예: 50일, 200일)을 사용할수록 변동성이 줄어들고 더 완만한 추세선이 됨
  • 단점: 최근 데이터의 변화가 반영되는 속도가 느림

 

2. 지수 이동 평균(EMA)

  • 최근 데이터에 더 높은 가중치를 부여하여 빠르게 변화를 반영하는 이동 평균 기법
  • 예제:
    • 7일 EMA에서는 가장 최근의 데이터가 가장 큰 영향을 줌
    • 예를 들어, 오늘의 데이터는 40% 반영하고, 3일 전 데이터는 15%만 반영하는 방식
    • 과거 데이터의 영향을 줄이면서 최신 데이터를 더 빠르게 반영

지수 이동 평균(EMA)의 특징

  • 최근 값에 높은 가중치를 부여하여 빠르게 변화하는 트렌드를 감지
  • 급상승하거나 급하락하는 경우, EMA는 이를 더 빨리 반영
  • 단점: 과거 데이터보다 최근 데이터에 의존도가 높아져 노이즈(급격한 변화)에도 민감함

 

3. 이동 평균과 EMA를 활용하는 방법

  • 장기적인 추세 분석 → 이동 평균(MA) 사용
  • 빠르게 변화하는 시장에서 단기 예측 → EMA 사용
  • 두 가지를 함께 비교하여 추세를 해석하는 것이 일반적

 

구분 이동 평균 (MA) 지수 이동 평균 (EMA)
계산 방식 단순히 최근 n일의 평균을 계산 최근 데이터일수록 더 높은 가중치를 부여
반응 속도 상대적으로 반응이 느림 변화를 더 빠르게 반영
장점 변동성이 큰 데이터를 부드럽게 만들어서 전체적인 트렌드 분석에 유용 최신 데이터의 영향을 더 많이 받아 빠르게 변화하는 트렌드를 잡는 데 유용
단점 최근 변화 반영이 느림 급격한 변화에 민감하여 노이즈(잡음)도 많이 포함될 수 있음
적합한 경우 장기적인 추세 분석 단기적인 변화 감지 및 트렌드 예측

 

 

 

- 시계열 데이터의 추세 분석을 위해 이동 평균(MA)과 지수 가중 이동 평균(EMA)을 적용

이동 평균(MA)으로 일반적인 추세를 확인하고, 지수 가중 이동 평균(EMA)으로 빠른 변화를 반영

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 랜덤 시드 설정
np.random.seed(42)

# 날짜 데이터 생성 (100일치)
dates = pd.date_range(start="2024-01-01", periods=100, freq='D')

# 하드 코딩된 기본 지표 (그로스 마케팅 성과 관련 데이터)
page_visits = np.random.randint(50, 1000, 100)  # 페이지 방문 수
ad_clicks = np.random.randint(5, 200, 100)  # 광고 클릭 수
purchases = np.random.randint(0, 50, 100)  # 구매 수
revenue = purchases * np.random.randint(10, 500, 100)  # 매출 (구매 * 평균 상품 가격)
session_duration = np.random.randint(1, 120, 100)  # 세션 지속 시간 (분)
bounce_rate = np.random.uniform(10, 80, 100)  # 이탈률 (%)

# 데이터프레임 생성
df_growth = pd.DataFrame({
    "Date": dates,
    "Page_Visits": page_visits,
    "Ad_Clicks": ad_clicks,
    "Purchases": purchases,
    "Revenue": revenue,
    "Session_Duration": session_duration,
    "Bounce_Rate": bounce_rate
})

# 이동 평균 (7일 평균, 단기 트렌드)
df_growth["Revenue_MA7"] = df_growth["Revenue"].rolling(window=7).mean()

# 지수 가중 이동 평균 (EMA, 7일)
df_growth["Revenue_EMA7"] = df_growth["Revenue"].ewm(span=7, adjust=False).mean()

# 시각화
plt.figure(figsize=(12, 6))

# 원본 매출 데이터 시각화
plt.plot(df_growth["Date"], df_growth["Revenue"], label="Revenue", color="blue", alpha=0.5)

# 이동 평균 (MA) 시각화
plt.plot(df_growth["Date"], df_growth["Revenue_MA7"], label="7-day MA", color="red", linestyle="dashed")

# 지수 가중 이동 평균 (EMA) 시각화
plt.plot(df_growth["Date"], df_growth["Revenue_EMA7"], label="7-day EMA", color="green", linestyle="dotted")

# 제목 및 축 라벨 추가
plt.title("그로스 마케팅 성과 예측 - 이동 평균 및 EMA 비교")
plt.xlabel("Date")
plt.ylabel("Revenue")
plt.legend()
plt.grid(True)

# 그래프 출력
plt.show()

* 그래프 해석

  • 파란색 실선원본 매출 데이터
    • 일별 변동이 매우 크고, 급격한 상승과 하락을 반복하여 추세를 예측하기 어려움
    • 따라서 이동 평균법을 적용하여 데이터의 변동성을 줄이고(스무딩) 더 명확한 패턴을 분석할 수 있음
  • 빨간색 점선7일 이동 평균 (7-day Moving Average, MA)
    • 최근 7일 동안의 매출 평균을 구하여 단기적인 추세를 확인
    • 변동이 큰 데이터를 부드럽게 만들어 트렌드를 더 명확하게 보여줌
  • 녹색 점선7일 지수 이동 평균 (7-day Exponential Moving Average, EMA)
    • 이동 평균(MA)보다 최근 데이터에 더 높은 가중치를 부여
    • 최근 변화에 더 민감하게 반응하여 변화 방향을 더 빠르게 포착

→ 원본 데이터가 변동이 매우 커서 저런 파란색 실선을 보이면 이동평균, 지수이동평균을 쓰면 좋음!

 

 

 

# 랜덤 포레스트 회귀 모델을 활용하여 이동 평균(MA)과 지수 가중 이동 평균(EMA)을 사용해 7일 후의 미래 매출을 예측하는 코드 (위의 코드 활용)

# 위 코드를 랜덤포레스트 회귀 분석으로 예측 (이동평균선 포함)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestRegressor

# 랜덤 시드 설정
np.random.seed(42)

# 날짜 데이터 생성 (100일치)
dates = pd.date_range(start="2024-01-01", periods=100, freq='D')

# 하드 코딩된 기본 지표 (그로스 마케팅 성과 관련 데이터)
page_visits = np.random.randint(50, 1000, 100)  # 페이지 방문 수
ad_clicks = np.random.randint(5, 200, 100)  # 광고 클릭 수
purchases = np.random.randint(0, 50, 100)  # 구매 수
revenue = purchases * np.random.randint(10, 500, 100)  # 매출 (구매 * 평균 상품 가격)
session_duration = np.random.randint(1, 120, 100)  # 세션 지속 시간 (분)
bounce_rate = np.random.uniform(10, 80, 100)  # 이탈률 (%)

# 데이터프레임 생성
df_growth = pd.DataFrame({
    "Date": dates,
    "Page_Visits": page_visits,
    "Ad_Clicks": ad_clicks,
    "Purchases": purchases,
    "Revenue": revenue,
    "Session_Duration": session_duration,
    "Bounce_Rate": bounce_rate
})

# 이동 평균 (7일 평균, 단기 트렌드)
df_growth["Revenue_MA7"] = df_growth["Revenue"].rolling(window=7).mean()

# 지수 가중 이동 평균 (EMA, 7일)
df_growth["Revenue_EMA7"] = df_growth["Revenue"].ewm(span=7, adjust=False).mean()

# 결측치 처리: 이동 평균 계산 후 처음 6일은 NaN이므로 이를 제거
df_growth = df_growth.dropna(subset=["Revenue_MA7", "Revenue_EMA7"])

# 특성 (특징): 이동 평균(MA)과 지수 가중 이동 평균(EMA)
X = df_growth[["Revenue_MA7", "Revenue_EMA7"]]

# 종속 변수 (목표): 실제 매출
y = df_growth["Revenue"]

# 랜덤 포레스트 회귀 모델 학습
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X, y)

# 마지막 7일 데이터를 기반으로 예측
last_7_days = df_growth.tail(7)
X_future = last_7_days[["Revenue_MA7", "Revenue_EMA7"]]

# 미래 예측
future_revenue_pred = rf_model.predict(X_future)

# 예측된 매출 결과 출력
for i, predicted_revenue in enumerate(future_revenue_pred, 1):
    print(f"Day {i+100}: Predicted Revenue = {predicted_revenue:.2f}")

# 예측 결과를 데이터프레임에 추가
future_dates = pd.date_range(start=df_growth["Date"].max(), periods=8, freq='D')[1:]

df_future = pd.DataFrame({
    "Date": future_dates,
    "Predicted_Revenue": future_revenue_pred
})

# 시각화
plt.figure(figsize=(12, 6))

# 원본 매출 데이터 시각화
plt.plot(df_growth["Date"], df_growth["Revenue"], label="Actual Revenue", color="blue", alpha=0.5)

# 이동 평균 (MA) 시각화
plt.plot(df_growth["Date"], df_growth["Revenue_MA7"], label="7-day MA", color="red", linestyle="dashed")

# 지수 가중 이동 평균 (EMA) 시각화
plt.plot(df_growth["Date"], df_growth["Revenue_EMA7"], label="7-day EMA", color="green", linestyle="dotted")

# 예측된 매출 시각화
plt.plot(df_future["Date"], df_future["Predicted_Revenue"], label="Predicted Revenue (Next 7 Days)", color="orange", linestyle="dashed")

# 제목 및 축 라벨 추가
plt.title("그로스 마케팅 성과 예측 - 이동 평균 및 EMA 비교 (미래 예측 포함)")
plt.xlabel("Date")
plt.ylabel("Revenue")
plt.legend()
plt.grid(True)

# 그래프 출력
plt.show()

 

랜덤 포레스트 회귀 → 시계열 변동성이 클 경우 활용하면 좋다고 해서 한번 써보았다.

 

 

 


 

마케팅 보고서 작성 연습

 

# 가상의 친환경 제품 판매 기업 'GreenTech'의 최근 6개월 동안 시행한 온/오프라인 마케팅 전략에 대해 제품 판매량 증가와 고객 반응 분석을 토대로 평가하고 보고서 작성.

 

- GreenTech의 마케팅 팀의 주요 목표

  • 온라인 광고 (SNS, 검색 광고)를 활용한 브랜드 인지도 향상
  • 오프라인 매장에서의 고객 유입 증가
  • 고객 리뷰 및 피드백을 활용한 제품 개선
  • 연령대 및 지역별 고객 분석을 통한 맞춤 마케팅 전략 수립

- 가상 데이터 : 최근 6개월간(2024년 8월 ~ 2025년 1월)의 수집된 데이터에 대한 주요 분석 항목

  1. 월별 매출 및 판매량 변화
  2. 광고 유형별 마케팅 비용 및 효과
  3. 고객 연령대 및 지역별 판매 트렌드
  4. 고객 리뷰 및 만족도 분석
  5. 재구매율 및 충성 고객 분석

 

* 주어진 가상 데이터

import pandas as pd

# 월별 매출 및 판매량 데이터
sales_data = pd.DataFrame({
    "월": ["2024-08", "2024-09", "2024-10", "2024-11", "2024-12", "2025-01"],
    "온라인 매출(만원)": [1200, 1350, 1500, 1650, 1800, 1950],
    "오프라인 매출(만원)": [800, 950, 1100, 1300, 1400, 1550],
    "총 판매량(개)": [300, 340, 380, 420, 460, 500]
})

# 광고 유형별 마케팅 비용 및 효과
ad_data = pd.DataFrame({
    "광고 유형": ["SNS 광고", "검색 광고", "이메일 마케팅", "오프라인 홍보"],
    "마케팅 비용(만원)": [600, 800, 300, 500],
    "클릭률(%)": [5.2, 4.8, 3.2, 2.5],
    "전환율(%)": [2.3, 2.8, 1.9, 1.5]
})

# 연령대 및 지역별 판매량 데이터
customer_data = pd.DataFrame({
    "연령대": ["20대", "30대", "40대", "50대"],
    "서울 판매량(개)": [120, 140, 160, 100],
    "부산 판매량(개)": [90, 110, 130, 80],
    "대구 판매량(개)": [70, 85, 95, 60],
    "광주 판매량(개)": [60, 75, 85, 55]
})

# 고객 리뷰 및 만족도 분석
review_data = pd.DataFrame({
    "평점": [5, 4, 3, 2, 1],
    "리뷰 수": [150, 200, 100, 50, 30],
    "주요 피드백": ["제품 품질 만족", "가격 대비 우수", "보통 만족", "배송 지연", "불량 제품"]
})

# 재구매율 및 충성 고객 분석
loyalty_data = pd.DataFrame({
    "구매 횟수": ["1회", "2회", "3회 이상"],
    "고객 수": [400, 250, 150],
    "비율(%)": [50, 31.3, 18.7]
})

 

* 그래프 그리기

# 위 데이터를 가지고 분석 그래프 그리기.

import pandas as pd
import matplotlib.pyplot as plt
import koreanize_matplotlib


# 1. 월별 매출 및 판매량 변화

import matplotlib.pyplot as plt
import numpy as np

# 그래프 크기 설정
fig, ax1 = plt.subplots(figsize=(12, 6))  # 그래프 크기를 더 넓게 설정

# X축 값
x = np.arange(len(sales_data["월"]))

# 막대 그래프 (온라인 매출, 오프라인 매출, 총 판매량)
bar_width = 0.25  # 막대 너비를 적당히 설정

# 온라인 매출 막대
online_bars = ax1.bar(x - bar_width, sales_data["온라인 매출(만원)"], width=bar_width, label="온라인 매출", color="#A7C7E7")  # 파스텔 블루
# 오프라인 매출 막대
offline_bars = ax1.bar(x, sales_data["오프라인 매출(만원)"], width=bar_width, label="오프라인 매출", color="#F4A7B9")  # 파스텔 핑크
# 총 판매량 막대
total_sales_bars = ax1.bar(x + bar_width, sales_data["총 판매량(개)"], width=bar_width, label="총 판매량", color="#B0E57C")  # 파스텔 그린

# 각 막대 위에 수치를 레이블로 표시
def add_labels(bars, data):
    for bar, value in zip(bars, data):
        height = bar.get_height()
        ax1.text(bar.get_x() + bar.get_width() / 2, height + 0.05 * max(data), f'{value}',
                 ha='center', va='bottom', fontsize=10, color="black")

# 각 그래프에 레이블 추가
add_labels(online_bars, sales_data["온라인 매출(만원)"])
add_labels(offline_bars, sales_data["오프라인 매출(만원)"])
add_labels(total_sales_bars, sales_data["총 판매량(개)"])

# Y축 레이블 및 타이틀
ax1.set_ylabel("매출 (만원)", fontsize=12)
ax1.set_xlabel("월", fontsize=12)
ax1.set_title("월별 온라인/오프라인 매출 및 총 판매량 변화", fontsize=14)
ax1.set_xticks(x)
ax1.set_xticklabels(sales_data["월"], rotation=45)  # 레이블 회전으로 공간 확보

# Y축 범위 조정
ax1.set_ylim(0, max(sales_data["온라인 매출(만원)"].max(), sales_data["오프라인 매출(만원)"].max(), sales_data["총 판매량(개)"].max()) * 1.2)

# 범례 추가
ax1.legend(loc="upper left")

# 그래프 표시
plt.show()


# 2. 광고 유형별 마케팅 비용 및 효과

fig, ax1 = plt.subplots(figsize=(12, 8))
ax2 = ax1.twinx()
ax1.bar(ad_data["광고 유형"], ad_data["마케팅 비용(만원)"], color="skyblue", label="마케팅 비용")
ax2.plot(ad_data["광고 유형"], ad_data["클릭률(%)"], marker="o", color="red", label="클릭률 (%)")
ax2.plot(ad_data["광고 유형"], ad_data["전환율(%)"], marker="s", color="green", label="전환율 (%)")
ax1.set_xlabel("광고 유형")
ax1.set_ylabel("마케팅 비용(만원)")
ax2.set_ylabel("클릭률 및 전환율 (%)")
ax1.legend(loc="upper left")
ax2.legend(loc="upper right")
plt.title("광고 유형별 마케팅 비용 및 효과")
plt.show()

# 3. 고객 연령대 및 지역별 판매 트렌드

customer_data.set_index("연령대").plot(kind="bar", figsize=(10, 5))
plt.xlabel("연령대")
plt.ylabel("판매량(개)")
plt.title("연령대 및 지역별 판매량")
plt.xticks(rotation=0)
plt.legend(title="지역")
plt.show()

# 4. 고객 리뷰 및 만족도 분석

plt.figure(figsize=(8, 5))
sns.barplot(data=review_data, x="평점", y="리뷰 수", palette="coolwarm")
plt.xlabel("평점")
plt.ylabel("리뷰 수")
plt.title("고객 리뷰 및 만족도 분석")
plt.show()

# 5. 재구매율 및 충성 고객 분석

plt.figure(figsize=(7, 5))
sns.barplot(data=loyalty_data, x="구매 횟수", y="고객 수", palette="viridis")
plt.xlabel("구매 횟수")
plt.ylabel("고객 수")
plt.title("재구매율 및 충성 고객 분석")
plt.show()

 

* 그래프를 분석하여 보고서 작성 연습

 

 

# 가상의 전자제품 회사 'SmartHome'의 최근 6개월 동안 시행한 마케팅 전략에 대해 주어진 데이터에 대한 분석을 토대로 평가하고 보고서 작성.

 

- SmartHome의 마케팅 팀의 주요 목표

  • 온라인 광고 및 인플루언서 마케팅을 활용한 브랜드 인지도 향상
  • 오프라인 매장에서의 고객 유입 증가
  • 고객 리뷰 및 만족도 분석을 통한 제품 개선
  • 구매 고객의 충성도를 높이기 위한 재구매 전략 수립

- 가상 데이터 : 최근 6개월간(2024년 8월 ~ 2025년 1월)의 수집된 데이터에 대한 주요 분석 항목

  1. 월별 매출 및 판매량 변화
  2. 광고 유형별 마케팅 비용 및 효과
  3. 고객 연령대 및 지역별 판매 트렌드
  4. 고객 리뷰 및 만족도 분석
  5. 재구매율 및 충성 고객 분석

 

* 주어진 가상 데이터

import pandas as pd

# 월별 매출 및 판매량 데이터
sales_data = pd.DataFrame({
    "월": ["2024-08", "2024-09", "2024-10", "2024-11", "2024-12", "2025-01"],
    "온라인 매출(만원)": [1500, 1600, 1750, 1900, 2050, 2200],
    "오프라인 매출(만원)": [700, 850, 950, 1100, 1250, 1400],
    "총 판매량(개)": [320, 360, 400, 440, 480, 520]
})

# 광고 유형별 마케팅 비용 및 효과
ad_data = pd.DataFrame({
    "광고 유형": ["SNS 광고", "검색 광고", "유튜브 인플루언서", "전시회 홍보"],
    "마케팅 비용(만원)": [650, 900, 750, 500],
    "클릭률(%)": [5.5, 4.6, 6.2, 3.8],
    "전환율(%)": [2.7, 3.0, 3.5, 1.8]
})

# 연령대 및 지역별 판매량 데이터
customer_data = pd.DataFrame({
    "연령대": ["20대", "30대", "40대", "50대"],
    "서울 판매량(개)": [130, 150, 170, 120],
    "부산 판매량(개)": [100, 120, 140, 90],
    "대구 판매량(개)": [80, 95, 110, 70],
    "광주 판매량(개)": [70, 85, 95, 65]
})

# 고객 리뷰 및 만족도 분석
review_data = pd.DataFrame({
    "평점": [5, 4, 3, 2, 1],
    "리뷰 수": [180, 220, 120, 60, 40],
    "주요 피드백": ["기능이 만족스러움", "디자인이 세련됨", "보통 만족", "앱 연동 문제", "고장 발생"]
})

# 재구매율 및 충성 고객 분석
loyalty_data = pd.DataFrame({
    "구매 횟수": ["1회", "2회", "3회 이상"],
    "고객 수": [450, 270, 180],
    "비율(%)": [52.3, 31.4, 16.3]
})

 

* 그래프 그리기

# 위 데이터를 가지고 분석 그래프 그리기

import pandas as pd
import matplotlib.pyplot as plt
import koreanize_matplotlib


# 월별 매출 및 판매량 그래프
plt.figure(figsize=(10, 6))
plt.plot(sales_data["월"], sales_data["온라인 매출(만원)"], label="온라인 매출", marker='o')
plt.plot(sales_data["월"], sales_data["오프라인 매출(만원)"], label="오프라인 매출", marker='o')
plt.plot(sales_data["월"], sales_data["총 판매량(개)"], label="총 판매량", marker='o')

plt.title('월별 매출 및 판매량 추이')
plt.xlabel('월')
plt.ylabel('금액(만원) / 판매량(개)')
plt.legend()
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# 광고 유형별 마케팅 비용 및 효과 그래프
fig, ax1 = plt.subplots(figsize=(10, 6))

ax1.bar(ad_data["광고 유형"], ad_data["마케팅 비용(만원)"], color='skyblue', alpha=0.6, label="마케팅 비용")
ax1.set_ylabel('마케팅 비용(만원)')
ax1.tick_params(axis='y')

ax2 = ax1.twinx()
ax2.plot(ad_data["광고 유형"], ad_data["클릭률(%)"], label="클릭률(%)", color='green', marker='o')
ax2.plot(ad_data["광고 유형"], ad_data["전환율(%)"], label="전환율(%)", color='red', marker='o')
ax2.set_ylabel('비율(%)', color='black')
ax2.tick_params(axis='y', labelcolor='black')

plt.title('광고 유형별 마케팅 효과')
plt.tight_layout()
plt.legend(loc='upper left')
plt.show()

# 연령대 및 지역별 판매량 그래프
customer_data.set_index("연령대").plot(kind="bar", stacked=True, figsize=(10, 6))
plt.title('연령대 및 지역별 판매량')
plt.xlabel('연령대')
plt.ylabel('판매량(개)')
plt.xticks(rotation=0)
plt.tight_layout()
plt.legend(title="지역", bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()

# 고객 리뷰 및 만족도 분석 그래프
plt.figure(figsize=(10, 6))
plt.bar(review_data["평점"], review_data["리뷰 수"], color='lightcoral')
plt.title('고객 리뷰 및 만족도 분석')
plt.xlabel('평점')
plt.ylabel('리뷰 수')
plt.xticks(review_data["평점"])
plt.tight_layout()
plt.show()

# 재구매율 및 충성 고객 분석 그래프
plt.figure(figsize=(10, 6))
plt.pie(loyalty_data["고객 수"], labels=loyalty_data["구매 횟수"], autopct='%1.1f%%', startangle=90)
plt.title('재구매율 및 충성 고객 분석')
plt.tight_layout()
plt.show()

 

* 그래프를 분석하여 보고서 작성 연습

 

 

* 보고서 작성 회고

- 다양한 그래프를 활용하지 못하고 주로 막대그래프만 그리게 되어서 같은 데이터라도 그 데이터를 가지고 다양한 그래프를 그려보는 연습이 필요함.

- 두 보고서의 데이터 분석 결과가 비슷해서 보고서 작성의 분석내용도 비슷한 내용으로 쓴 것 같아서 아쉬움. 같은 지표라도 다양하게 해석해보는 연습이 필요함.

- 보고서 작성은 간결함이 핵심이다. 문장을 장황하게 쓸수록 보는 사람이 핵심을 파악하기 어려워진다. 문장을 간결하게 쓰는 연습이 필요함을 느낀다.

- 가상의 기업인 GreenTech는 친환경 제품 판매기업이고 SmartHome은 전자제품 회사이다. 보고서 분석 내용을 작성할 때 기업의 해당 분야의 인사이트를 가지고 써야 하는데 전혀 그런 내용이 없음. 가상의 기업이고 이것은 단지 연습이기 때문에 감안하지만, 데이터를 분석하고 그것을 토대로 개선방안 및 결론을 도출하는 데에는 해당 분야(도메인)의 기본적인 이해가 바탕이 되어야 한다는 것을 절실히 느낄 수 있었다.