상관관계(Correlation)의 이해와 기초
1. 상관관계란?
상관관계(Correlation)는 두 변수 간의 관계를 나타내는 통계적 개념으로, 한 변수의 변화가 다른 변수의 변화와 어떤 관계가 있는지를 나타냅니다.
즉, 한 변수가 증가할 때 다른 변수가 증가하거나 감소하는 패턴이 있는지를 분석하는 것입니다.
- 상관계수랑 결정계수(R2)랑 개념이 다른, 비슷한 의미라 헷갈릴수 있음.
2. 상관계수(Correlation Coefficient)
상관관계의 정도는 상관계수(Correlation Coefficient, r)로 표현되며, 가장 많이 사용되는 상관계수는 피어슨 상관계수(Pearson Correlation Coefficient, r)입니다.
3. 상관계수의 해석
4. 상관관계와 인과관계
상관관계가 있다고 해서 반드시 인과관계(causation)가 있는 것은 아닙니다. 즉, 두 변수가 함께 변한다고 해서 하나가 다른 하나의 원인이 된다는 의미는 아닙니다.
인과관계는 시간관계임
예를 들어:
- 아이스크림 판매량과 익사 사고 수는 높은 상관관계를 보이지만, 이는 여름철이라는 공통 요인(Confounding Variable) 때문입니다. → 여름이라는 메타데이터가 있어야 설명이 됨
- 따라서 상관관계를 해석할 때는 반드시 외부 요인과 논리적인 관계를 고려해야 합니다.
5. 상관분석의 응용
- 경제학: 주식 시장에서 주가지수와 경제 지표 간 관계 분석
- 의학: 혈압과 심장 질환 간 관계 분석
- 마케팅: 광고 비용과 매출액 간 관계 분석
- 머신러닝: 독립 변수(특징)와 종속 변수 간 관계 파악
6. 상관계수의 한계
- 상관계수는 선형 관계(linear relationship)만 측정합니다. 즉, 비선형 관계(곡선 형태의 관계)는 측정하지 못할 수 있습니다.
- 극단값(Outliers)에 민감하여 데이터에 이상치가 많으면 왜곡될 수 있습니다.
- 상관계수 값이 낮다고 해서 반드시 두 변수 간에 관계가 없는 것은 아닙니다(비선형 관계 가능성).
7. 피어슨 상관계수 외의 다른 상관계수
- 스피어만 상관계수(Spearman’s Rank Correlation, $\rho$): 순위(rank) 기반 상관계수로, 비선형 관계가 존재하는 경우에도 사용할 수 있습니다.
- 켄달의 타우(Kendall’s Tau, $\tau$): 순위 기반으로 관계를 측정하며, 작은 데이터셋에서도 신뢰성이 높음.
.corr()와 pearsonr() 차이점
함수 | 기본 상관계수 방식 | P-value 제공 여부 | 데이터 타입 |
df.corr() | Pearson (기본) | ❌ 제공 안 함 | DataFrame 전체 가능 |
pearsonr(x, y) | Pearson | ✅ 제공함 | 두 개의 Series 또는 배열만 가능 |
상관계수 계산 코드 1
1인 가구 관심집단 csv 에서 평일외출이 적은 집단 컬럼과 상관도가 높은 컬럼을 선별
import pandas as pd
df = pd.read_csv("1인가구관심집단.csv")
df.columns
target_variable = '평일_외출이_적은_집단'
# 상관계수 계산
correlation_matrix = df.corr(numeric_only = True)
# 종속변수와의 상관계수 추출 (자기 자신 제외)
independent_variables = correlation_matrix[target_variable].drop(target_variable).sort_values(ascending=False)
# 결과 출력
print("평일 외출이 적은 집단과의 상관계수:\\n", independent_variables)
#출력값
평일 외출이 적은 집단과의 상관계수:
출근소요시간_및_근무시간이_많은_집단 0.953097
동영상서비스_이용이_많은_집단 0.943168
커뮤니케이션이_적은_집단 0.888667
생활서비스_이용이_많은_집단 0.832320
재정상태에_대한_관심집단 0.804566
휴일_외출이_적은_집단 0.794170
외출_커뮤니케이션이_모두_적은_집단_전체 0.499605
외출이_매우_적은_집단_전체 0.478128
외출이_매우_많은_집단 0.419057
성별 0.028242
행정동코드 0.003367
연령대 -0.266860
Name: 평일_외출이_적은_집단, dtype: float64
상관계수 계산 (피어슨) 2
#광고비 vs 매출 상관도 분석
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr
# 데이터 생성
data = {
"날짜": pd.date_range(start="2024-02-01", periods=10, freq="D"),
"광고비": [50, 60, 55, 70, 65, 80, 75, 90, 85, 100],
"매출": [300, 350, 320, 400, 390, 450, 420, 500, 470, 550]
}
df = pd.DataFrame(data)
# 상관계수 계산, 피어슨이 데이터 리턴을 두개 해줘서 하나는 빈자리 표시해줌
#pearsonr 은 상관계수와 pvalue를 동시에 계산하는 함수.
#correlation, p_value = pearsonr(df["광고비"], df["매출"])
correlation, _ = pearsonr(df["광고비"], df["매출"])
# 데이터 시각화
plt.figure(figsize=(8, 6)) #그래프 크기
sns.regplot(x="광고비", y="매출", data=df) #seaborn 라이브러리에서 regplot 그래프(광고비와 매출의 관계를 산접도 및 회귀선으로 나타냄, 점들이 직선에 가깝게 몰려있으면 강한 상관관계)
plt.title(f"광고비 vs 매출 (상관계수: {correlation:.2f})") #그래프 제목
plt.xlabel("광고비 (만원)") #x축 제목
plt.ylabel("매출 (만원)") # y축제목
plt.show() #그래프 출력
# 상관계수 출력
print(f"Pearson 상관계수: {correlation:.2f}")
# ROI(투자수익률) 계산 ((매출 - 광고비) / 광고비)
df["ROI"] = (df["매출"] - df["광고비"]) / df["광고비"] * 100
print("\\nROI 데이터:")
print(df[["날짜", "광고비", "매출", "ROI"]])
#출력값
Pearson 상관계수: 1.00
ROI 데이터:
날짜 광고비 매출 ROI
0 2024-02-01 50 300 500.000000
1 2024-02-02 60 350 483.333333
2 2024-02-03 55 320 481.818182
3 2024-02-04 70 400 471.428571
4 2024-02-05 65 390 500.000000
5 2024-02-06 80 450 462.500000
6 2024-02-07 75 420 460.000000
7 2024-02-08 90 500 455.555556
8 2024-02-09 85 470 452.941176
9 2024-02-10 100 550 450.000000
문제풀이
문제 1
서울시_상권분석서비스(추정매출-상권)_2022.csv 데이터 사용
df = pd.read_csv("서울시_상권분석서비스(추정매출-상권)_2022년.csv")
df.info()
df.head(1)[["시간대_17~21_매출_금액",
"주말_매출_금액",
"여성_매출_금액",
"일요일_매출_금액", '연령대_30_매출_금액']]
target_variable = '연령대_30_매출_금액'
# 상관계수 계산
correlation_matrix = df.corr(numeric_only = True)
# 종속변수와의 상관계수 추출 (자기 자신 제외)
independent_variables = correlation_matrix[target_variable].drop(target_variable).sort_values(ascending=False)
# 결과 출력
print("연령대_30_매출_금액과의 상관계수:\\n", independent_variables)
#X 독립변수설정
X = df[[ "시간대_17~21_매출_금액",
"주말_매출_금액",
"여성_매출_금액",
]]
y = df['연령대_30_매출_금액']
# 다중 회귀 모델 생성 및 학습
model = LinearRegression()
model.fit(X, y)
# 예측 결과
predicted_sales = model.predict(X)
r2 = r2_score(y, predicted_sales)
# 회귀 계수 출력
coef_dict = {column: coef for column, coef in zip(X.columns, model.coef_)}
display(coef_dict)
print('rsqare:',r2)
print('intercept:', model.intercept_)
#모델 파라미터 및 결정계수(R²) 출력
print("회귀식:연령대_30_매출_금액 = {:.2f} + {:.5f} * 시간대_17~21_매출_금액 + {:.5f} * 주말_매출_금액 + {:.5f} * 여성_매출_금액".format(
model.intercept_, model.coef_[0], model.coef_[1], model.coef_[2]
))
print("결정계수 (R²): {:.4f}".format(r2_score(y, model.predict(X))))
#예측 결과
a = -642027.6250971854 + 0.24490399598804058 * 2196006.0 + 0.09079722618897196 * 2587530.0 + 0.2176116336453151 * 377191.0
print("실제결과:448104.0 예측결과:", a)
실제결과랑 예측결과 차이가 커서 scatterplot 그려봄
아니면plt.scatter 로 변수 하나씩 검증해서 산포도로 그래프 경향 확인 후, 선형성에 벗어나는 데이터를 가진 컬럼("주말매출금액", "시간대 매출 금액") 최대한 배제.
이번 데이터가 비선형데이터라서 회귀분석으로는 잘 안나옴. (상관관계는 잘나오는데도 불구)
왜 비선형이냐면 시간대별 매출액 데이터라서 매출이 없는 시간대가 있음. 그래서 0~ 이다가 갑자기 매출액 있고 다시 매출 0 되고 그럼.
문제 2
한 온라인 쇼핑몰은 광고비, 웹사이트 방문자 수, 장바구니 담기 횟수, 그리고 최종 매출 간의 관계를 분석하고자 합니다. 마케팅팀은 광고비 증가가 실제 매출 증가로 이어지는지 궁금하며, 웹사이트 방문자 수와 장바구니 추가 횟수가 구매로 전환되는지 확인하려 합니다.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr
# 데이터 생성
data = {
"날짜": pd.date_range(start="2024-02-01", periods=10, freq="D"),
"광고비": [50, 60, 55, 70, 65, 80, 75, 90, 85, 100],
"방문자 수": [1200, 1350, 1250, 1500, 1450, 1600, 1550, 1800, 1750, 2000],
"장바구니 추가 횟수": [150, 180, 160, 210, 200, 230, 220, 270, 260, 300],
"매출": [300, 350, 320, 400, 390, 450, 420, 500, 470, 550]
}
df = pd.DataFrame(data)
# 상관계수 계산
corr_matrix = df.drop(columns=["날짜"]).corr()
# 데이터 시각화 - 상관행렬 히트맵
plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", fmt=".2f")
plt.title("변수 간 상관관계 분석")
plt.show()
# 변수별 상관계수 출력
for col in ["광고비", "방문자 수", "장바구니 추가 횟수"]:
corr, p_value = pearsonr(df[col], df["매출"])
print(f"{col} vs 매출 Pearson 상관계수: {corr:.2f}, P-value: {p_value:.4f}")
# 광고비 vs 매출 시각화
plt.figure(figsize=(8, 6))
sns.regplot(x="광고비", y="매출", data=df)
plt.title("광고비 vs 매출")
plt.xlabel("광고비 (만원)")
plt.ylabel("매출 (만원)")
plt.show()
# 장바구니 추가 횟수 vs 매출 시각화
plt.figure(figsize=(8, 6))
sns.regplot(x="장바구니 추가 횟수", y="매출", data=df)
plt.title("장바구니 추가 횟수 vs 매출")
plt.xlabel("장바구니 추가 횟수")
plt.ylabel("매출 (만원)")
plt.show()
# 상관계수 계산
corr_matrix = df.drop(columns=["날짜"]).corr()
상관계수 계산 시 날짜를 뺀이유?
✔ 날짜는연속형 수치 변수가 아니므로상관계수 계산에서 제외하는 것이 일반적
✔ 날짜를 포함하려면트렌드 분석(시계열 분석)으로 활용하는 것이 더 적절함
✔요일, 월 등으로 변환하면특정 시간 패턴이 매출에 미치는 영향을 분석할 수 있음
- df.corr()은 숫자형(연속형) 변수들 간의 피어슨 상관계수(Pearson correlation coefficient)를 계산해.
- 하지만 "날짜" 컬럼은 datetime 타입이라서 수치형이 아니므로 상관계수 계산에서 제외.
날짜(시간 변수)는 보통 직접적인 상관관계를 분석하는 대상이 아님
- 시간("날짜") 자체가 매출에 직접적인 영향을 주는 변수는 아니야.
- 보통 "날짜"는 트렌드(추세) 분석에 사용하지, 상관계수 계산에서는 독립 변수로 포함되지 않는 경우가 많아.
regplot: 산점도(scatter plot)와 회귀선(regression line)을 함께 그리는 함수
sns.regplot(x, y, data=df)
sns.regplot(x="x", y="y", data=df, order=2) # order=2로 다항 회귀 적용
기본적으로 단순 선형회귀선을 그리지만, order 매개변수를 조정하면 다항 회귀도 가능.
문제 3
상관분석과 회귀분석을 활용한 배달 서비스 이용 예측
2024.12월_29개 통신정보.csv
문제: 1인 가구 비율이 높은 지역에서는 특정 온라인 서비스(배달, 금융, 쇼핑, 동영상 서비스 등)의 이용이 증가하는가?
1인 가구와 온라인 서비스 이용 행태의 관계
(비율 기준은 4분위로 설정함)
# 필요한 라이브러리 임포트
import pandas as pd
# 데이터 불러오기
file_path = "/content/2024.12월_29개 통신정보.csv"
df = pd.read_csv(file_path)
# 분석 대상 변수 설정
single_household = "1인가구수"
services = ["배달 서비스 사용일수", "쇼핑 서비스 사용일수", "금융 서비스 사용일수", "동영상/방송 서비스 사용일수"]
age_col = "연령대"
# 데이터 타입 변환 (쉼표 제거 후 숫자로 변환)
for col in [single_household] + services:
df[col] = df[col].astype(str).str.replace(",", "").str.strip()
df[col] = pd.to_numeric(df[col], errors='coerce')
# 1. 1인 가구 수와 주요 온라인 서비스 사용일수 간의 피어슨 상관계수 계산
correlations = df[[single_household] + services].corr()[single_household].drop(single_household)
# 2. 1인 가구 비율이 높은 지역과 낮은 지역의 서비스 이용 패턴 비교
q1 = df[single_household].quantile(0.25) # 하위 25%
q3 = df[single_household].quantile(0.75) # 상위 25%
high_single_df = df[df[single_household] >= q3] # 1인 가구 비율이 높은 지역
low_single_df = df[df[single_household] <= q1] # 1인 가구 비율이 낮은 지역
# 두 그룹의 서비스 이용 평균 비교
service_means_high = high_single_df[services].mean()
service_means_low = low_single_df[services].mean()
# 3. 연령대별 1인 가구 수와 서비스 이용 패턴 분석
if age_col in df.columns:
age_single_service_means = df.groupby(age_col)[[single_household] + services].mean()
else:
age_single_service_means = None
# 결과 출력
print("\\n1. 1인 가구 수와 온라인 서비스 사용일수 간의 피어슨 상관계수")
print(correlations)
print("\\n2. 1인 가구 비율이 높은 지역과 낮은 지역의 서비스 이용 평균 비교")
print("1인 가구 비율이 높은 지역 (상위 25%):")
print(service_means_high)
print("\\n1인 가구 비율이 낮은 지역 (하위 25%):")
print(service_means_low)
print("\\n3. 연령대별 1인 가구 수와 서비스 이용 평균")
print(age_single_service_means)
문제 4
연령대별 온라인 서비스 선호도의 차이 시각화
필요한 라이브러리 임포트
import pandas as pd
데이터 불러오기
file_path = "/content/2024.12월_29개 통신정보.csv"
df = pd.read_csv(file_path)
분석 대상 변수 설정
age_col = "연령대"
services = ["배달 서비스 사용일수", "쇼핑 서비스 사용일수", "금융 서비스 사용일수", "게임 서비스 사용일수", "동영상/방송 서비스 사용일수"]
데이터에서 실제 존재하는 열만 선택 (일부 열이 누락될 수 있음)
existing_services = [col for col in services if col in df.columns]
쉼표 제거 및 숫자로 변환 (데이터가 문자열일 가능성이 있음)
for col in existing_services:
df[col] = df[col].astype(str).str.replace(",", "").str.strip()
df[col] = pd.to_numeric(df[col], errors='coerce')
연령대별 주요 온라인 서비스 사용일수 평균 계산
age_service_means = df.groupby(age_col)[existing_services].mean()
연령대와 특정 서비스(쇼핑 vs. 금융) 간의 상관관계 분석
age_service_correlations = df[[age_col] + existing_services].corr().loc[age_col, existing_services]
특정 연령대에서 특정 서비스 사용량이 급격히 증가하거나 감소하는 패턴 확인
age_service_differences = age_service_means.diff().dropna() # 연령대별 변화량 계산
결과 출력
print("\\n1. 연령대별 온라인 서비스 이용 평균")
print(age_service_means)
print("\\n2. 연령대와 서비스 이용 간의 상관관계")
print(age_service_correlations)
print("\\n3. 연령대별 서비스 이용 변화량")
print(age_service_differences)
bar보다는 트렌드 그래프로 시각화 하자.
보고서 실습
Day17 보고서 실습 (상관관계).docx
“광고비, 방문자 수, 장바구니 추가 횟수가 매출에 미치는 영향 분석”
1. 개요
본 보고서는 광고비, 웹사이트 방문자 수, 장바구니 추가 횟수가 매출에 미치는 영향을 분석하여 최적의 마케팅 전략을 수립하는 것을 목표로 한다.
데이터 분석을 통해 가장 영향력이 큰 요인을 확인하고, 향후 마케팅 방향성을 제시한다.
2. 데이터 개요
본 분석은 10일간의 데이터를 활용하여 아래 4개의 주요 변수 간 관계를 분석하였다.
3. 데이터 분석 결과
상관관계 분석 히트맵
ROI 분석
시각화 분석
- 광고비 vs 매출
- 방문자 수 vs 매출
- 장바구니 추가 횟수 vs 매출
4. 마케팅 전략 개선 방안
1) 광고비 최적화
2) 웹사이트 방문자 수 증가 전략
3) 장바구니 이탈률 감소 전략
5. 결론 및 실행 계획
결론
- 광고비, 방문자 수, 장바구니 추가 횟수 모두 매출과 강한 양의 상관관계를 보였다.
- 특히 장바구니 추가 횟수가 가장 중요한 변수로 분석되었으며, 장바구니 이탈 방지 전략이 핵심 개선 포인트이다.
- 광고비 최적화 및 전환율 증가 전략을 병행하여 마케팅 ROI를 극대화해야 한다.
실행 계획
- 광고비 대비 ROI 최적화 분석을 수행하고, 효율적인 광고 채널을 선정한다.
- SEO, SNS, 인플루언서 마케팅을 활용한 방문자 수 증가 전략을 실행한다.
- 장바구니 이탈 고객을 대상으로 리마케팅 및 할인 쿠폰 제공을 시작한다.
- A/B 테스트를 진행하여 장바구니 이탈 방지 전략의 효과를 분석한다.
코드 정리
# 컬럼명에 '연령'이 포함된 열만 조회
age_columns = df.loc[:, df.columns.str.contains('연령')]
print(age_columns)
- Object 데이터 타입 변환 예시
df["총인구"] = pd.to_numeric(df["총인구"], errors="coerce")
df["1인가구수"] = pd.to_numeric(df["1인가구수"], errors="coerce")
df_new["1인가구수"] = df_new["1인가구수"].str.replace(",", "").astype(int)
df_new["총인구"] = df_new["총인구"].str.replace(",", "").astype(int)
아니면 map 해도 됨.
- 차이 계산 시 diff() 함수 사용.
4분위수: 1Q는 하위 25%
회고
상관분석으로 독립변수 구하고
그담에 회귀모델 구축 하는 흐름!
이걸 왜 하냐 특징을 구하고 통계적 특성을 구하기 위함 → EDA를 하기 위해.
상관분석, 회귀분석 관련 문제를 계속 풀고 결과 분석을 했는데,
데이터 필터링하는데 생각보다 시간이 걸렸다. 판다스 복습해서 능숙하게 쓸수 있도록.
'STUDY' 카테고리의 다른 글
[멋쟁이사자처럼부트캠프_그로스마케팅] Day18-2 고객 세분화를 위한 통계 분석 (0) | 2025.03.07 |
---|---|
[멋쟁이사자처럼부트캠프_그로스마케팅] Day 18 마케팅 주요 지표 분석 보고서 실습 (2) | 2025.03.07 |
[멋쟁이사자처럼부트캠프_그로스마케팅] Day16 회귀분석, 보고서 실습 (0) | 2025.03.07 |
[멋쟁이사자처럼부트캠프_그로스마케팅] Day15 통계 overview (2) | 2025.03.05 |
[멋쟁이사자처럼부트캠프_그로스마케팅] Day 14 EDA, EDA 데이터 전처리 종합 실습 (0) | 2025.03.05 |