콘텐츠로 이동
Data Prep
상세

가격 최적화 분석 (Pricing Analytics)

개요

가격 최적화 분석은 수익 극대화, 시장 점유율 확보, 고객 가치 극대화를 위한 가격 전략 수립 방법론이다. 수요 탄력성, 경쟁 가격, 고객 세그먼트를 종합적으로 분석한다.

분석 프레임워크

1. 가격 탄력성 분석

수요의 가격 탄력성(PED):

\[ PED = \frac{\% \Delta Q}{\% \Delta P} = \frac{\partial Q / Q}{\partial P / P} \]
PED 값 해석 가격 전략
|PED| > 1 탄력적 가격 인하로 수익 증가
|PED| = 1 단위 탄력적 가격 변화 무관
|PED| < 1 비탄력적 가격 인상으로 수익 증가

추정 방법:

import pandas as pd
import numpy as np
from scipy.optimize import curve_fit
import statsmodels.api as sm

def estimate_price_elasticity(df: pd.DataFrame) -> dict:
    """
    df: price, quantity, (controls) 컬럼 포함
    """
    # 로그-로그 회귀 (상수 탄력성 모델)
    df['log_price'] = np.log(df['price'])
    df['log_quantity'] = np.log(df['quantity'])

    X = sm.add_constant(df['log_price'])
    y = df['log_quantity']

    model = sm.OLS(y, X).fit()

    elasticity = model.params['log_price']
    se = model.bse['log_price']

    return {
        'elasticity': elasticity,
        'std_error': se,
        'r_squared': model.rsquared,
        'interpretation': 'elastic' if abs(elasticity) > 1 else 'inelastic'
    }

# 사용 예시
# result = estimate_price_elasticity(sales_data)
# print(f"가격 탄력성: {result['elasticity']:.2f}")

2. 수요 함수 추정

선형 수요 함수: $$ Q = a - bP + cI + dA + \epsilon $$

  • Q: 수요량
  • P: 가격
  • I: 소득
  • A: 광고비
  • a, b, c, d: 추정 계수

로그-선형 수요 함수: $$ \ln Q = \alpha + \beta \ln P + \gamma \ln I + \delta \ln A + \epsilon $$

def fit_demand_function(df: pd.DataFrame, model_type: str = 'linear') -> dict:
    """수요 함수 추정"""

    if model_type == 'linear':
        X = df[['price', 'income', 'ad_spend']]
        X = sm.add_constant(X)
        y = df['quantity']

    elif model_type == 'log_linear':
        X = np.log(df[['price', 'income', 'ad_spend']])
        X = sm.add_constant(X)
        y = np.log(df['quantity'])

    model = sm.OLS(y, X).fit()

    return {
        'coefficients': model.params.to_dict(),
        'r_squared': model.rsquared,
        'price_elasticity': model.params['price'] if model_type == 'log_linear' else None
    }

3. 최적 가격 도출

이윤 극대화 가격:

이윤 함수: $$ \pi = (P - MC) \cdot Q(P) $$

1차 조건 (FOC): $$ \frac{\partial \pi}{\partial P} = Q + (P - MC) \cdot \frac{\partial Q}{\partial P} = 0 $$

최적 가격 공식 (마크업): $$ P^* = \frac{MC}{1 + \frac{1}{PED}} $$

def optimal_price(marginal_cost: float, elasticity: float) -> float:
    """이윤 극대화 가격 계산"""
    if abs(elasticity) <= 1:
        raise ValueError("탄력성 절대값이 1보다 커야 함 (수익 극대화 조건)")

    markup = 1 / (1 + 1/elasticity)
    optimal_p = marginal_cost / markup

    return optimal_p

# 예시: MC=100, PED=-2
# optimal_price(100, -2) = 200

가격 전략 유형

1. 침투 가격 (Penetration Pricing)

  • 목적: 시장 점유율 확보
  • 적용: 신제품 출시, 네트워크 효과 시장
  • 특징: 초기 저가 → 점진적 인상
단계 가격 목표
출시 경쟁사 -30% 인지도 확보
성장 경쟁사 -15% 점유율 20%
성숙 시장 평균 수익성 회복

2. 스키밍 가격 (Skimming Pricing)

  • 목적: 초기 고수익 확보
  • 적용: 혁신 제품, 특허 보호 시장
  • 특징: 초기 고가 → 점진적 인하

3. 가치 기반 가격 (Value-Based Pricing)

  • 핵심: 고객이 인지하는 가치 기준
  • 방법: Conjoint Analysis, Van Westendorp

Van Westendorp 분석:

def van_westendorp_analysis(df: pd.DataFrame) -> dict:
    """
    df 컬럼: too_cheap, cheap, expensive, too_expensive
    """
    prices = np.linspace(df['too_cheap'].min(), df['too_expensive'].max(), 100)

    # 누적 분포 계산
    too_cheap_cum = [(df['too_cheap'] >= p).mean() for p in prices]
    cheap_cum = [(df['cheap'] >= p).mean() for p in prices]
    expensive_cum = [(df['expensive'] <= p).mean() for p in prices]
    too_expensive_cum = [(df['too_expensive'] <= p).mean() for p in prices]

    # 교차점 찾기
    # PMC (Point of Marginal Cheapness): too_cheap = expensive
    # PME (Point of Marginal Expensiveness): too_expensive = cheap
    # OPP (Optimal Price Point): too_cheap = too_expensive
    # IPP (Indifference Price Point): cheap = expensive

    results = {
        'acceptable_range': (find_intersection(too_cheap_cum, expensive_cum, prices),
                            find_intersection(too_expensive_cum, cheap_cum, prices)),
        'optimal_price': find_intersection(too_cheap_cum, too_expensive_cum, prices),
        'indifference_price': find_intersection(cheap_cum, expensive_cum, prices)
    }

    return results

def find_intersection(curve1, curve2, prices):
    diff = np.array(curve1) - np.array(curve2)
    idx = np.argmin(np.abs(diff))
    return prices[idx]

4. 동적 가격 (Dynamic Pricing)

실시간 수요/공급에 따른 가격 조정.

적용 산업: - 항공: 좌석 가용성, 예약 시점 - 호텔: 점유율, 시즌 - 이커머스: 경쟁 가격, 재고 - 라이드셰어: 수요/공급 비율 (서지 프라이싱)

class DynamicPricer:
    def __init__(self, base_price: float, min_price: float, max_price: float):
        self.base_price = base_price
        self.min_price = min_price
        self.max_price = max_price

    def calculate_price(
        self, 
        demand_ratio: float,  # 현재 수요 / 평균 수요
        inventory_ratio: float,  # 현재 재고 / 최대 재고
        competitor_price: float = None
    ) -> float:
        """동적 가격 계산"""

        # 수요 계수 (수요 높으면 가격 상승)
        demand_factor = 1 + 0.5 * (demand_ratio - 1)

        # 재고 계수 (재고 적으면 가격 상승)
        inventory_factor = 1 + 0.3 * (1 - inventory_ratio)

        # 경쟁 계수
        if competitor_price:
            comp_factor = 0.9 + 0.2 * (competitor_price / self.base_price)
        else:
            comp_factor = 1.0

        # 최종 가격
        price = self.base_price * demand_factor * inventory_factor * comp_factor

        # 범위 제한
        return np.clip(price, self.min_price, self.max_price)

세그먼트별 가격 차별화

가격 차별화 유형

유형 설명 예시
1급 개인별 지불의사 추출 경매, 협상
2급 수량/버전별 차등 볼륨 디스카운트, Freemium
3급 세그먼트별 차등 학생 할인, 지역별 가격

세그먼트 가격 최적화

def segment_price_optimization(segments: list[dict]) -> dict:
    """
    각 세그먼트별 최적 가격 계산

    segments = [
        {'name': 'premium', 'size': 1000, 'elasticity': -1.5, 'wtp_mean': 150},
        {'name': 'standard', 'size': 5000, 'elasticity': -2.5, 'wtp_mean': 80},
        {'name': 'budget', 'size': 10000, 'elasticity': -4.0, 'wtp_mean': 40},
    ]
    """
    results = {}
    mc = 30  # 한계비용 가정

    for seg in segments:
        ped = seg['elasticity']

        # 마크업 가격
        optimal_p = mc / (1 + 1/ped)

        # 예상 수요 (가격 변화에 따른)
        price_change = (optimal_p - seg['wtp_mean']) / seg['wtp_mean']
        quantity_change = price_change * ped
        expected_quantity = seg['size'] * (1 + quantity_change)

        # 예상 이익
        profit = (optimal_p - mc) * expected_quantity

        results[seg['name']] = {
            'optimal_price': round(optimal_p, 2),
            'expected_quantity': int(expected_quantity),
            'expected_profit': round(profit, 0)
        }

    return results

경쟁 가격 분석

가격 포지셔닝 맵

높은 가격
    │  ★ 프리미엄    ★ 고급
    │     (우리)
    ├──────────────────────── 높은 품질
    │  ★ 가성비      ★ 표준
낮은 가격

경쟁 가격 모니터링

from dataclasses import dataclass
from typing import Optional
import requests

@dataclass
class CompetitorPrice:
    competitor: str
    product: str
    price: float
    timestamp: str
    url: Optional[str] = None

class CompetitorPriceTracker:
    def __init__(self):
        self.price_history: list[CompetitorPrice] = []

    def add_price(self, price_data: CompetitorPrice):
        self.price_history.append(price_data)

    def get_price_position(self, our_price: float, product: str) -> dict:
        """우리 가격의 경쟁 포지션"""
        product_prices = [
            p.price for p in self.price_history 
            if p.product == product
        ]

        if not product_prices:
            return {'position': 'unknown'}

        avg_price = np.mean(product_prices)
        min_price = np.min(product_prices)
        max_price = np.max(product_prices)

        percentile = (our_price - min_price) / (max_price - min_price) * 100

        return {
            'our_price': our_price,
            'market_avg': round(avg_price, 2),
            'market_min': round(min_price, 2),
            'market_max': round(max_price, 2),
            'percentile': round(percentile, 1),
            'vs_avg': f"{((our_price/avg_price)-1)*100:+.1f}%"
        }

가격 실험 (A/B 테스트)

실험 설계

요소 권장
샘플 크기 MDE 5% 기준 ~10,000/그룹
기간 최소 2주 (주간 변동 고려)
가격 변동폭 10-20% (너무 크면 이탈)
측정 지표 전환율, AOV, LTV, 이탈률
from scipy import stats

def price_ab_test_analysis(
    control_conversions: int,
    control_visitors: int,
    treatment_conversions: int,
    treatment_visitors: int,
    control_aov: float,
    treatment_aov: float
) -> dict:
    """가격 A/B 테스트 분석"""

    # 전환율
    cr_control = control_conversions / control_visitors
    cr_treatment = treatment_conversions / treatment_visitors

    # 전환율 차이 유의성 (Z-test)
    pooled_cr = (control_conversions + treatment_conversions) / \
                (control_visitors + treatment_visitors)
    se = np.sqrt(pooled_cr * (1 - pooled_cr) * \
                 (1/control_visitors + 1/treatment_visitors))
    z_stat = (cr_treatment - cr_control) / se
    p_value = 2 * (1 - stats.norm.cdf(abs(z_stat)))

    # 매출 (RPV: Revenue per Visitor)
    rpv_control = cr_control * control_aov
    rpv_treatment = cr_treatment * treatment_aov
    rpv_lift = (rpv_treatment - rpv_control) / rpv_control

    return {
        'conversion_rate': {
            'control': round(cr_control * 100, 2),
            'treatment': round(cr_treatment * 100, 2),
            'lift': f"{((cr_treatment/cr_control)-1)*100:+.1f}%",
            'p_value': round(p_value, 4)
        },
        'aov': {
            'control': round(control_aov, 0),
            'treatment': round(treatment_aov, 0),
            'lift': f"{((treatment_aov/control_aov)-1)*100:+.1f}%"
        },
        'revenue_per_visitor': {
            'control': round(rpv_control, 2),
            'treatment': round(rpv_treatment, 2),
            'lift': f"{rpv_lift*100:+.1f}%"
        },
        'recommendation': 'treatment' if rpv_treatment > rpv_control and p_value < 0.05 else 'control'
    }

산업별 적용

산업 주요 방법 핵심 변수
SaaS 가치 기반, Freemium 기능 차등, 사용량
이커머스 동적 가격, 경쟁 기반 재고, 경쟁가, 시즌
항공/호텔 수익 관리 (RM) 좌석/객실 가용성
제조 비용+ 가격 원가, 마진 타겟
B2B 협상, 볼륨 디스카운트 계약 규모, 관계

체크리스트

  • [ ] 가격 탄력성 추정
  • [ ] 수요 함수 모델링
  • [ ] 고객 세그먼트별 WTP 분석
  • [ ] 경쟁 가격 벤치마크
  • [ ] 최적 가격점 도출
  • [ ] A/B 테스트 설계
  • [ ] 가격 민감도 모니터링

참고 자료


마지막 업데이트: 2026-03-04