카테고리 없음

[DAY13] 멋쟁이사자처럼부트캠프 그로스마케팅_Today I Learnd

hachaenii 2025. 2. 19. 19:12

 

오늘의 학습 내용
- 데이터 변환
- 데이터 표준화 및 정규화

 

오늘의 메인은 결측값 확인하고 알맞은 방법으로 처리하는 것..!

결측값을 처리하기 위한 다양한 데이터 변환 법들을 공부했다 


시각화 그래프 

그래프 종류 히스토그램 선형 그래프
예시
활용 사례 광고 클릭 수 분포 분석 시간에 따른 매출 변화
주요 목적 데이터의 분포 파악 시간별 트렌드 분석
그래프 종류 막대 그래프 산점도
예시
활용 사례 채널별 전환율 비교 광고비 vs 전환율 관계 분석
주요 목적 범주형 데이터 비교 상관관계 분석
그래프 종류 파이 차트 히트맵
예시
활용 사례 고객 세그먼트 비율 분석 시간대별 광고 성과 분석
주요 목적 비율 비교 다차원 데이터의 패턴 분석
그래프 종류 박스 플롯
예시

        [ 박스 플롯에서 이상치 표시 방식 ]

  • 박스(Box): Q1(25%) ~ Q3(75%) 사이의 값을 표시 (데이터의 50% 포함)
  • 중앙값(Median, Q2): 박스 내부의 가로선으로 표시
  • 수염(Whiskers): 이상치를 제외한 데이터의 최대/최소값을 연결하는 선
  • 이상치(Outlier): 박스 플롯 바깥쪽의 점(●, x)으로 표시
활용 사례 이상치가 포함된 수익 분석
주요 목적 이상치 감지 및 데이터 분포 확인

데이터 변환

1. 데이터 변환의 중요성

데이터를 정확하게 분석하려면 데이터 변환(Data Transformation)이 필수적이다.

데이터 변환을 통해 데이터 품질을 개선하고, 비즈니스 인사이트를 도출할 수 있다

데이터 변환이 필요한 이유

  • 데이터 정제(Data Cleaning): 결측값, 이상치를 처리하여 신뢰성 있는 데이터 확보
  • 데이터 표준화(Standardization): 분석 및 비교를 위해 일관된 데이터 형식 유지
  • 특성 엔지니어링(Feature Engineering): 마케팅 인사이트를 도출하기 위한 새로운 변수 생성
  • 머신러닝 모델 준비(Model Preparation): 모델 학습을 위한 데이터 전처리 수행

2. API 통신 중 발생할 수 있는 결측치와 데이터베이스 저장 형태

데이터를 주고받을 때, 클라이언트에서 요청한 값이 정상적으로 수신되지 않거나 일부 데이터가 누락되는 경우가 발생

결측치는 데이터베이스에 저장될 때 다양한 형태로 나타날 수 있으며, 그 원인과 유형을 이해하는 것이 중요

 

2.1 NULL 값으로 저장되는 경우

  • API 제공자가 필드를 명시적으로 null로 반환하는 경우
  • 외부 데이터 소스에서 해당 값을 제공하지 않는 경우
  • 클라이언트가 특정 필드를 입력하지 않고 요청을 보낸 경우

예제

# API응답 :
{
  "id": 1,
  "name": "김철수",
  "email": null,
  "phone": "010-1234-5678"
}
# 데이터베이스 저장 형태 (MySQL 예시):
INSERT INTO users (id, name, email, phone) VALUES (1, '김철수', NULL, '010-1234-5678');

 

> email 필드가 NULL로 저장

 

2.2 빈 문자열로 저장되는 경우

  • API가 null 대신 빈 문자열을 반환하는 경우
  • 클라이언트에서 값 입력을 생략했으나 NULL이 아닌 빈 값으로 설정한 경우

예제

# API응답:
{
  "id": 2,
  "name": "이영희",
  "email": "",
  "phone": "010-9876-5432"
}
# 데이터베이스 저장 형태:
INSERT INTO users (id, name, email, phone) VALUES (2, '이영희', '', '010-9876-5432');

 

> email 필드가 NULL이 아닌 빈 문자열로 저장

 

2.3 ' 0' 또는 기본값으로 저장되는 경우

  • API에서 값이 없을 경우 기본값을 설정하는 경우
  • 데이터 제공자가 특정 필드의 기본값을 0으로 정의한 경우
  • 클라이언트가 값을 입력하지 않았으나 API가 자동으로 0을 반환한 경우

예제

# API 응답:
{
  "id": 3,
  "name": "박민수",
  "age": 0,
  "salary": 3000000
}
# 데이터베이스 저장 형태:
INSERT INTO employees (id, name, age, salary) VALUES (3, '박민수', 0, 3000000);

 

> age  값이 NULL이 아닌 0으로 저장

 

2.4 데이터 타입이 잘못 저장되는 경우

  • API 응답 값이 비정상적인 형식으로 제공된 경우
  • 데이터 타입 검증이 제대로 이루어지지 않은 경우
  • 클라이언트에서 잘못된 데이터를 입력한 경우

예제

# API 응답:
{
  "id": 4,
  "name": "정수빈",
  "age": "unknown",
  "salary": 2500000
}
# 데이터베이스 저장 형태 (잘못 저장된 경우):
INSERT INTO employees (id, name, age, salary) VALUES (4, '정수빈', 'unknown', 2500000);

 

> 일반적으로 age 필드는 INT 타입이어야 하지만 문자열 "unknown"이 저장되면서 데이터 정합성이 깨질 수 있음

 

2.5 특정 데이터가 아예 저장되지 않는 경우

  • API 설계 변경으로 인해 특정 필드가 더 이상 제공되지 않는 경우
  • 외부 데이터 소스에서 해당 정보를 제공하지 않는 경우
  • 요청 시 일부 필드만 선택적으로 제공하는 경우

예제

# API응답:
{
  "id": 5,
  "name": "최진혁"
}
# 데이터베이스 저장 형태:
INSERT INTO users (id, name, email, phone) VALUES (5, '최진혁', NULL, NULL);

 

> API 응답에서 emailphone 필드가 아예 존재하지 않았기 때문에 데이터베이스에 NULL로 저장

 

이러한 결측치를 처리하는 방법 

  • NULL 값 변환: coalesce() 함수를 사용하여 NULL 값을 기본값으로 변환
  • 데이터 타입 검증: API 응답 데이터를 저장하기 전에 데이터 타입을 변환 또는 검증
  • 기본값 설정: DEFAULT 값을 설정하여 필드가 NULL이 아닐 때 기본값을 자동 삽입

3. 데이터 변환 기법

3.1 데이터 정제 (Data Cleaning)

그로스 마케팅 데이터를 분석하기 전에 결측값과 이상치를 처리해야 함

  • 결측값이 있으면 평균값 또는 중앙값으로 대체
  • 이상치(극단값)는 제거하거나 다른 값으로 조정
import pandas as pd
import numpy as np

# 예제 데이터 생성
data = {
    "Age": [25, 30, np.nan, 40, 35],  # 결측값 포함
    "Ad Influence": [5, np.nan, 3, 4, 5],  # 결측값 포함
    "Product Satisfaction": [np.nan, 4, 3, 5, 4]  # 결측값 포함
}
# nan은 nat a numbber로 문자가 아닌 데이터 타입이며 numpy가 nan으로 저장되도록 한다

df = pd.DataFrame(data)

# 결측값을 평균으로 대체
df.fillna(df.mean(), inplace=True)

print(df)

 

결측치 확인 : isnull()

데이터프레임(DataFrame) 또는 시리즈(Series)에서 결측치(NaN)를 확인하는 함수

결과는 각 값이 결측치인지(True) 또는 아닌지(False)를 나타내는 불리언(Boolean) 값으로 반환

import pandas as pd
import numpy as np

data_example = {
    "User ID": [1, 2, 3, 4, 5],
    "Ad Clicks": [10, np.nan, 25, 30, np.nan],  # 일부 결측치 포함
    "Conversion Rate": [0.05, 0.07, np.nan, 0.12, 0.09],  # 일부 결측치 포함
    "Revenue": [1000, 2000, np.nan, 4000, 5000]  # 일부 결측치 포함
}

# 데이터프레임 생성
df_example = pd.DataFrame(data_example)

# 결측치 확인 코드
missing_values_example = df_example.isnull().sum()

# 데이터 및 결측치 개수 출력
print("Example Dataset:")
print(df_example)
print("\nMissing Values Count:")
print(missing_values_example)

 

3.2 데이터 타입 변환 (Data Type Conversion)

그로스 마케팅 데이터를 분석할 때는 데이터 유형을 적절하게 변환

  • 문자열을 숫자로 변환 (예: "Yes"/"No" → 1/0)
  • 날짜 데이터를 변환하여 분석 가능하도록 변경
# 광고 시청 여부를 0과 1로 변환
df["Ad Viewed"] = ["Yes", "No", "Yes", "No", "Yes"]
df["Ad Viewed"] = df["Ad Viewed"].map({"Yes": 1, "No": 0})

# 날짜 데이터 변환
df["Survey Date"] = pd.to_datetime(["2024-02-01", "2024-02-02", "2024-02-03", "2024-02-04", "2024-02-05"])

print(df["Ad Viewed"])
print(df)

 

 

* 문자열로 보내는 경우 : 데이터를 모르는 사람이 받아야 하고 설명이 불가한 경우 데이터에 대한 이해를 돕도록 

 

3.3 범주형 데이터 변환 (Categorical Encoding)

광고 캠페인이나 고객 세그먼트 같은 범주형 데이터는 머신러닝 모델에서 바로 사용할 수 없기 때문에 숫자로 변환

  • 레이블 인코딩(Label Encoding): 범주형 데이터를 숫자로 변환
  • 원-핫 인코딩(One-Hot Encoding)***: 범주형 데이터를 여러 개의 이진(0/1) 컬럼으로 변환
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder

# 예제 데이터 생성 (결측값 포함)
data = {
    "User ID": [101, 102, 103, 104, 105],
    "Age": [25, 30, np.nan, 40, 35],  # 결측값 포함
    "Ad Clicks": [10, 50, 35, 30, 60],  
    "Conversion Rate": [0.02, 0.05, 0.03, 0.04, 0.07],
    "Ad Influence": [5, np.nan, 3, 4, 5],  # 결측값 포함
    "Product Satisfaction": [np.nan, 4, 3, 5, 4],  # 결측값 포함
    "Campaign": ["YouTube Ad", "SNS Ad", "Search Ad", "Email Marketing", "SNS Ad"]
}

df = pd.DataFrame(data)

# 먼저 numeric(숫자)만 평균값을 계산하고 결측값을 각 컬럼의 평균으로 대체
df.fillna(df.mean(numeric_only=True), inplace=True)

# 레이블 인코딩 (Campaign을 숫자로 변환)
# 레이블 인코더를 le라는 객체로 저장하고 le 객체의 fit_transform 메서드를 호출해서 campaign컬럼을 숫자로 바꾸고
# campaign_encoded라는 컬럼을 추가해 저장
le = LabelEncoder()
df["Campaign_Encoded"] = le.fit_transform(df["Campaign"])

# 원-핫 인코딩 적용
df_one_hot = pd.get_dummies(df, columns=["Campaign"])

# 최종 결과 출력
print(df_one_hot)

 

3.4 데이터 스케일링 (Data Scaling)

범위를 0과 1사이 값으로 변환하는 것

변환 하는 이유 : 연속형 변수는 범위가 다를 수 있는데 범위가 다 다르게 되면 데이터를 다루기 어려움

> 모델 학습과 비교를 위해 정규화(Normalization) 또는 표준화(Standardization) 적용이 필요

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
df[["Ad Influence", "Product Satisfaction"]] = scaler.fit_transform(df[["Ad Influence", "Product Satisfaction"]])

print(df)
3.5 피처 엔지니어링 (Feature Engineering)

 

기존 데이터를 가공하여 새로운 인사이트를 얻을 수 있는 변수를 추가

# 제품 만족도 점수가 4 이상이면 "High", 그렇지 않으면 "Low"
df["Satisfaction Level"] = df["Product Satisfaction"].apply(lambda x: "High" if x >= 0.8 else "Low")

print(df)

4. 데이터 변환을 활용한 그로스 마케팅 분석 사례

4.1 광고 캠페인별 효과 분석

그로스 마케팅에서 가장 중요한 것은 광고 캠페인의 효과를 분석하는 것

import pandas as pd
import numpy as np

# 새로운 데이터 생성 (광고 캠페인별 효과 분석)
data = {
    "Campaign": np.random.choice(["Google Ads", "Facebook Ads", "Instagram Ads", "YouTube Ads", "Email Marketing"], 100),  # 캠페인명
    "Ad Influence": np.random.randint(1, 10, 100),  # 광고 영향도 (1~10점)
    "Click Through Rate (CTR)": np.round(np.random.uniform(0.02, 0.18, 100), 3),  # 클릭률 (2%~18%)
    "Conversion Rate": np.round(np.random.uniform(0.02, 0.25, 100), 3),  # 전환율 (2%~25%)
    "Revenue": np.random.randint(2000, 15000, 100),  # 매출 (2,000~15,000원)
    "Customer Segment": np.random.choice(["VIP", "Regular", "New"], 100),  # 고객 세그먼트
}

# 데이터프레임 생성
df = pd.DataFrame(data)

# 광고 캠페인별 광고 영향도 평균 계산
campaign_ad_influence = df.groupby("Campaign")["Ad Influence"].mean().reset_index()

# 전체 데이터셋 출력 (상위 10개 행)
print("Ad Campaign Effectiveness Dataset (Top 10 Rows):")
print(df.head(10))

# 캠페인별 광고 영향도 평균 출력
print("\n Campaign Ad Influence Summary:")
print(campaign_ad_influence)

 

광고 캠페인별 주요 성과 분석

Ad Influence(광고 영향도) 평균 비교

Campaign Ad Influence (평균)
YouTube Ads 5.12
Email Marketing 4.81
Google Ads 5.04
Facebook Ads 4.06
Instagram Ads 4.63

 

분석 보고서.pdf

Ad Influence.pdf
0.09MB

 

4.1 고객 세그먼트 분석

광고 시청 여부와 연령대별 재구매 의향(Repurchase Intent)을 비교하면, 어떤 고객 그룹이 재구매율이 높은지 확인 가능

import pandas as pd
import numpy as np

# 예제 데이터 생성
data = {
    "User ID": [101, 102, 103, 104, 105],
    "Age": [25, 30, 35, 40, 45],  
    "Repurchase Intent": [1, 0, 1, 1, 0]  # 1: 재구매 의향 있음, 0: 없음
}

df = pd.DataFrame(data)

# 연령대 구분 (예: 20대, 30대, 40대)
bins = [20, 30, 40, 50]  # 연령대 구간 설정
labels = ["20s", "30s", "40s"]
df["Age Group"] = pd.cut(df["Age"], bins=bins, labels=labels, right=False)

# 연령대별 재구매율 분석 (observed=False 추가)
repurchase_rate = df.groupby("Age Group", observed=False)["Repurchase Intent"].mean() * 100

# 결과 출력
print(repurchase_rate)

5. 그로스 마케팅에서 활용되는 데이터 변환 예시

결측값 처리 → 광고 클릭, 전환율 등 데이터 손실 방지
데이터 변환 → 숫자 변환, 인코딩, 로그 변환 등을 활용하여 비교 가능하게 변환
스케일링 적용 → 정규화 및 표준화를 통해 광고 비용, 클릭 수 등의 비교 가능
피처 엔지니어링 → 고객 세그먼트, 날짜 기반 변수 등을 추가하여 분석력 향상
이상치 제거 → 광고 효과 분석의 정확성을 높이기 위해 극단값 조정

 

5.1 결측값 처리

평균(Mean) 또는 중앙값(Median)으로 대체

5.1.1 평균(Mean)으로 대체

예를 들어, 광고 클릭 수(Ad Clicks) 데이터가 [10, 50, NaN, 30, 60] 일 때,

결측값을 평균값 (10+50+30+60)/4 = 37.5로 대체

import pandas as pd
import numpy as np

# 예제 데이터 생성
data = {
    "User ID": [101, 102, 103, 104, 105],
    "Ad Clicks": [10, 50, np.nan, 30, 60],  # 결측값 포함
    "Conversion Rate": [0.02, 0.05, 0.03, np.nan, 0.07]  # 결측값 포함
}

df = pd.DataFrame(data)

# 평균으로 결측값 대체
df["Ad Clicks"].fillna(df["Ad Clicks"].mean())
df["Conversion Rate"].fillna(df["Conversion Rate"].mean())

print(df)

출력결과

 

5.1.1 중앙값(Median)으로 대체

예를 들어, 광고 클릭 수 데이터가 [10, 30, NaN, 50, 60]일 때, 정렬 후 [10, 30, NaN, 50, 60]  중앙값 30으로 대체

# 중앙값으로 결측값 대체
df["Ad Clicks"].fillna(df["Ad Clicks"].median())
df["Conversion Rate"].fillna(df["Conversion Rate"].median())

print(df)

출력결과

5.2 데이터 타입 변환

카테고리형 데이터를 숫자로

# 광고 시청 여부를 0과 1로 변환
df["Ad Viewed"] = ["Yes", "No", "Yes", "No", "Yes"]
df["Ad Viewed"] = df["Ad Viewed"].map({"Yes": 1, "No": 0})

print(df)

원-핫 인코딩 (One-Hot Encoding) :  범주형 데이터를 숫자로

# 광고 캠페인 유형을 원-핫 인코딩으로 변환
df["Campaign"] = ["YouTube Ad", "SNS Ad", "Search Ad", "Email Marketing", "SNS Ad"]
df = pd.get_dummies(df, columns=["Campaign"])

print(df)

5.3  데이터 스케일링 

정규화, 표준화 등으로 데이터를 일정한 범위로 변환하여 비교 가능하도록

정규화

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
df[["Ad Clicks", "Conversion Rate"]] = scaler.fit_transform(df[["Ad Clicks", "Conversion Rate"]])

print(df)

표준화

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df[["Ad Clicks", "Conversion Rate"]] = scaler.fit_transform(df[["Ad Clicks", "Conversion Rate"]])

print(df)

5.4  피처 엔지니어링

데이터를 추가 변환하여 새로운 분석 변수를 생성

로그 변환 (Log Transformation)

import numpy as np

# 광고 비용 데이터
df["Ad Cost"] = [100, 5000, 2000, 10000, 3000]

# 로그 변환 적용 (0 방지 위해 1 추가)
df["Log Ad Cost"] = np.log1p(df["Ad Cost"])

print(df)

5.5  이상치 처리

사분위 범위 (IQR, Interquartile Range) 이용한 이상치 제거

# 이상치 탐지
Q1 = df["Ad Clicks"].quantile(0.25)
Q3 = df["Ad Clicks"].quantile(0.75)
IQR = Q3 - Q1

# 이상치 제거
df_filtered = df[(df["Ad Clicks"] >= Q1 - 1.5 * IQR) & (df["Ad Clicks"] <= Q3 + 1.5 * IQR)]

print(df_filtered)

데이터 표준화 및 정규화

1. 데이터 표준화 및 정규화의 필요성

그로스 마케팅에서는 광고 효과 분석, 고객 행동 데이터 비교, 마케팅 성과 평가 등을 위해 다양한 데이터를 분석

이러한 데이터는 값의 범위가 다르기 때문에, 효과적인 비교를 위해 데이터 변환(Data Transformation)이 필수

1.1 정규화(Normalization)

 데이터를 0과 1 사이의 범위로 변환하여 상대적인 크기를 조정

정규화가 데이터를 0과 1 사이의 범위로 변환하는 과정을 시각화

 

 

 

파란색 점 (Original Data)
: 원본 데이터 값 (10, 50, 30, 80, 60)
빨간색 점 (Normalized Data)
: 정규화된 값 (0 ~ 1 범위로 변환됨)

 

 

 

정규화 과정 설명

최소값(10)은 0으로 변환됨
최대값(80)은 1로 변환됨
나머지 값은 최소값과 최대값을 기준으로 0~1 사이의 값으로 조정됨
50 → 0.5
30 → 0.25
60 → 0.75

 

이처럼 정규화를 적용하면 데이터의 상대적 크기는 유지하면서, 값의 범위를 일정하게 맞출 수 있다.

 

(정규화내용은 다음 수업때 표준화에 대해 더 배우고 같이 다시한번 정리하려고 한다 오늘은 여기까지 ..!) 


"오늘의 회고"

 

오랜만에 조금 덜 지쳤던 수업..! 이것저것 배운 개념이 많아 정리할 게 많았지만

오늘의 메인은 바로 결측치 확인과 결측치 처리!!

데이터 분석가에게 너무너무 중요한 것임을 대학 전공 프로젝트를 하며 깨달았어서 유난히 집중해서 들었다

데이터가 주어지면 꼭 결측치 이상값 확인하기..!!!

그리고 오늘도 역시나 힘들었던 보고서 작성,, 지표를 잡는게 가장 어려운 것 같다

뭐가 내 분석목적에 있어 중요한 지표인지 판단하는 연습을 많이 해야 할 것 같다

 

다들 고생하셨어요 오늘도..! 이번주 이틀 남았습니다 아자아자

오늘은 수고한 저와 1기 동기들에게 보내는 꽃 임티로 마무리!