통계분석을 통한 가설검정 (t-test) 두 변수의 평균에 차이가 있는지 검정
# t-test(t-검정)은 주 변수(데이터군)의 평균에 통계적으로 유의한 차이가 있는지 알아볼 때 사용하는 통계분석 기법
- 중요한것은 피벨류의 값이고 유의하다라는것은 우연히 차이날 확률이 작다는것이고 우연이 아니다 라는걸로 해석할 수 있습니다.
# scipy패키지의 ttest_ind()를 통해 t-검정을 수행 (scipy라이브러리 설치 필요)
# t-test.py
# t-test (t-검정)
# 두 변수(=두 데이터군)의 평균을 기준으로 유사도를 검증하는 통계분석 기법
# scipy 라이브러리를 사용
def p(str):
print(str, '\n')
# compact자동차와 suv자동차의 도시연비 t검정
import pandas as pd
mpg = pd.read_csv('../assets/mpg.csv')
mpg.info()
## 기술 통계 분석
# category가 compact이거나 suv
# category가 같은것들 그룹핑
# n변수에는 category의 개수, mean변수에는 cty의 평균값
mpg_agg = mpg.query('category in ["compact", "suv"]') \
.groupby('category', as_index=False) \
.agg(n=('category', 'count'), mean=('cty', 'mean'))
p(mpg_agg)
# category별로 도시연비(cty) 분리
compact = mpg.query('category=="compact"')['cty']
suv = mpg.query('category=="suv"')['cty']
print(compact, suv)
# t-test
from scipy import stats
# equal_var=True : 집단 간 분산이 같다고 가정
# p-value가 0.05보다 작다 = 유의확률이 작다 = 통계적으로 유의하다 = 상관 있다
p(stats.ttest_ind(compact, suv, equal_var=True))
# 실습 : 일반휘발유(fl:r)와 고급휘발유(fl:p)의 도시연비(cty) t-test
## 기술 통계 분석
# r, p 추출하기
# fl별 분리
# 빈도 구하기
# cty 평균 구하기
mpg_fl = mpg.query('fl in ["r", "p"]') \
.groupby('fl', as_index=False) \
.agg(n=('fl', 'count'), mean=('cty', 'mean'))
p(mpg_fl)
regular = mpg.query('fl=="r"')['cty'] # 일반휘발유
premium = mpg.query('fl=="p"')['cty'] # 고급휘발유
# t-test
# p-value가 0.05보다 크다 = 유의확률이 크다 = 통계적으로 유의하지 않다 = 상관도가 적다
p(stats.ttest_ind(regular, premium, equal_var=True))
이렇게 pvalud값이 0.05보다 크다면 통계적으로 상관도가 적다는것입니다.
전체적으로 다시 복습하자면
t-검정 이라는 통계기법을 사용해서 소형차와 suv연비가 정말로 다른건지 아니면 우연히 차이가 난건지에 대한 데이터분석을 해보려고하는겁니다.
1. 데이터를 불러옵니다.
필요한 외부라이브로리는 판다스라서 판다스를 불러오고
pd.read_csv('경로')를 이용해서 파일을 읽어줍니다.
그 다음 .info()를 이용해서 간단한 파일정보를 알아봅니다.
확인할수있는것은 데이터 크기, 열, 행의 개수정도를 알 수 있습니다.
2. 첫번째 비교 : 소형차(compact)와 suv 도시 연비비교
2-1. 소형차와 suv그룹만들
compact와 suv차종의 데이터만 필요하고 나머지는 딱히 필요가 없겠죠?
그러니 compact, suv 종끼리 그룹바이를 해서 평균 연비를 계산해보려 합니다.
mpg.query('category in ["compact", "suv"]')
- query()는 데이터를 조건에 맞게 필터링해주는 함수입니다. 여기서는 category 열이 "compact"(소형차) 또는 "suv"(SUV)인 데이터만 골라내고 있어요.
- 즉, 소형차와 SUV만 선택하는 과정이라고 보면 됩니다.
groupby('category', as_index=False)
- groupby()는 데이터를 특정 기준으로 묶어주는 함수입니다. 여기서는 category를 기준으로 소형차와 SUV를 각각 묶고 있어요. 묶인 데이터들끼리 계산을 쉽게 할 수 있죠.
- as_index=False는 그룹을 묶을 때 인덱스로 사용하지 말라는 뜻이에요. 즉, 데이터프레임 형태로 계속 유지하겠다는 의미입니다.
.agg(n=('category', 'count'), mean=('cty', 'mean'))
- agg() 함수는 그룹별로 원하는 계산(예: 합계, 평균 등)을 할 수 있게 해줍니다.
- 여기서는 두 가지 계산을 하고 있어요:
- n=('category', 'count'): 각 그룹(소형차, SUV)에 몇 대의 차량이 있는지 세고 있어요.
- mean=('cty', 'mean'): 각 그룹의 도시 연비(cty)의 평균을 계산하고 있습니다.
결과적으로, 이 코드는 소형차와 SUV의 개수와 그들의 평균 도시 연비를 보여줍니다.
2.2. 소형차와 SUV의 연비 데이터 따로 저장하기
이 부분에서는 소형차와 SUV 각각의 연비 데이터를 따로 나누어 저장합니다.
mpg.query('category=="compact"')['cty']
- 이 코드는 query()를 사용해 category가 "compact"인 데이터, 즉 소형차의 데이터만 선택한 다음, 그 중에서도 cty(도시 연비) 열만 따로 저장하는 거예요.
- 마찬가지로 mpg.query('category=="suv"')['cty']는 SUV의 도시 연비 데이터만 선택해서 저장합니다.
이렇게 나눠진 데이터를 나중에 비교 분석할 수 있습니다.
2.3. 두 그룹의 연비 차이를 비교(t-검정)
이 코드는 scipy 라이브러리의 ttest_ind() 함수를 사용해 두 그룹(소형차와 SUV)의 평균 연비가 통계적으로 다른지 비교하는 부분입니다.
stats.ttest_ind(compact, suv, equal_var=True)
- ttest_ind()는 두 그룹의 평균이 통계적으로 다른지 확인하는 함수예요. 여기서는 소형차와 SUV의 연비 평균이 차이가 나는지 알아봅니다.
- equal_var=True는 두 그룹의 데이터가 비슷한 분산(데이터의 흩어짐 정도)을 가지고 있다고 가정한다는 뜻이에요. 보통 초급 단계에서는 이렇게 설정합니다.
- 이 함수는 두 그룹의 평균 차이가 통계적으로 유의미한지를 알려주는 p-value라는 결과를 반환합니다. 이 p-value가 0.05보다 작으면 "소형차와 SUV의 평균 연비 차이는 우연이 아니고, 정말로 다르다"고 결론을 내릴 수 있어요.
3. 일반휘발유와 고급휘발유 차량의 도시 연비 비교하기
이제 두 번째 비교인 연료 종류에 따른 연비 차이를 분석해봅시다.
3.1. 일반휘발유와 고급휘발유 그룹 만들기
여기서는 연료가 일반휘발유(r)나 고급휘발유(p)인 차량들을 추출해서 그들의 평균 연비를 계산하고 있습니다.
mpg.query('fl in ["r", "p"]')
- query()를 사용해 연료(fl)가 "r"(일반휘발유) 또는 "p"(고급휘발유)인 데이터만 골라내고 있어요.
groupby('fl', as_index=False)
- groupby()로 연료 종류별로 차량을 묶습니다. 즉, 일반휘발유 차량끼리, 고급휘발유 차량끼리 묶어서 계산할 수 있도록 준비하는 거죠.
.agg(n=('fl', 'count'), mean=('cty', 'mean'))
- agg() 함수로 각 그룹의 차량 수(n)와 도시 연비 평균(mean)을 계산하고 있습니다.
3.2. 각 그룹의 연비 데이터 따로 저장하기
이 부분에서는 일반휘발유와 고급휘발유 차량의 도시 연비 데이터를 각각 따로 저장합니다.
3.3. 두 그룹의 연비 차이를 비교(t-검정)
마찬가지로, ttest_ind() 함수로 두 그룹(일반휘발유와 고급휘발유 차량)의 평균 연비가 통계적으로 다른지 확인합니다. 결과로 나오는 p-value가 0.05보다 크다면 "두 그룹의 평균 연비 차이는 우연일 가능성이 크다"고 결론을 내릴 수 있어요.
통계분석을 통한 가설검정 (상관분석)
연속 변수가 서로 관련이 있는지 검정
# 상관분석 (correlation analysis) 연속 변수가 서로 관련이 있는지 검정하는 통계 분석 기법
# 상관계수 (correlation coefficient)
* 변수의 관련도를 0~1의 값으로 표시하며 1에 가까울수록 상관성이 큼
* 양수면 정비례, 음수면 반비례
# 상관행렬 (correlation matrix)
* 변수들 간의 상관계수를 행렬로 표시
* DataFrame의 corr()메소드를 통해 상관행렬을 생성
# 상관계수와 유의확률은 scipy의 stats.pearsonr()을 이용해 구함
# 히트맵(상관행렬을 도식화)은 seaborn의 heatmap()을 이용해 그림 (mtcars.csv를 assets폴더에 복사)
#correlationanalysis.py
# 상관분석 : 두 변수간의 관계를 분석 (주로 연속된 값에 대한 관계)
def p(str):
print(str, '\n')
#economics 데이터 불러오기
import pandas as pd
economics = pd.read_csv('../assets/economics.csv')
economics.info()
#상관행렬 만들기
p(economics[['unemploy', 'pce']].corr()) #실업자수, 개인소비지출
#상관분석(상관계수, 유의확률<p-value>)
# 상관계수는 -1~1의 값: 1이나 -1에 가까울수록 상관도가 높다.
# : 양수는 정비례, 음수는 반비례 관계이다.
from scipy import stats
p(stats.pearsonr(economics['unemploy'], economics['pce']))
#상관계수 == 0.614517614193208(정비례), p-value((6.773527303290177e-61))= 상관도가 높다
## 상관행렬 히트맵 만들기
# mtcars 데이터 불러오기
mtcars = pd.read_csv('../assets/mtcars.csv')
p(mtcars.head())
# 상관행렬 만들기
car_cor = mtcars.corr()
# 소수점 둘째자리 반올림
car_cor = round(car_cor, 2)
p(car_cor)
#그래프 설정
import matplotlib.pyplot as plt
plt.rcParams.update({
"figure.dpi": '120', #해상도
'figure.figsize': [7.5, 5.5], #화면크기
})
#히드맵 그리기
import seaborn as sns
# # annot=True 상관계수 표시, cmap:컬러맵
# sns.heatmap(car_cor, annot=True, cmap='RdBu')
# plt.show()
#대각행렬 제거용 mask 만들기
import numpy as np
mask = np.zeros_like(car_cor) #0으로 채운 행렬
p(mask)
#오른쪽 위 대각행렬을 1로 바꾸기
mask[np.triu_indices_from(mask)] = 1
p(mask)
#mask 적용된 히트맵 표시
# sns.heatmap(data=car_cor, annot=True, cmap='RdBu', mask=mask)
# plt.show()
# 빈 행, 빈 열, 히트맵에서 제거
mask_new = mask[1:, :-1] #행렬에서 첫 행, 마지막 열 제거
cor_new = car_cor.iloc[1:, -1]
# 히트맵 만들기
sns.heatmap(data=cor_new, annot=True, cmap='RdBu', mask=mask_new)
plt.show()
#히트맵 세부 설정 옵션
sns.heatmap(
data = cor_new, #데이터
anoot = True, #상관계수 표시
cmap = 'RdBu', #컬러맵 설정
mask = mask_new, #mask설정
linewidths=.5, #경계구분선 두께
vmax = 1, #가장 진한 파랑색으로 표현할 최대값
vmin = -1, #가장 진한 빨간색으로 표현할 최소값
cbar_kws= {'shrink': .5} #범례 크기
)
plt.show()
자세하게 코드 복습을 해보자면
1. 데이터 불러오기와 간단한 정보 확인
pd.read_csv()
- 이 함수는 CSV 파일을 불러와서 economics라는 변수에 데이터를 저장합니다. 여기서는 경제 데이터(economics.csv)를 불러오고 있어요.
economics.info()
- info() 함수는 불러온 데이터의 간단한 정보를 보여줍니다. 예를 들어, 몇 개의 행과 열이 있는지, 각 열이 어떤 데이터 타입을 가지고 있는지 등을 확인할 수 있어요.
2. 상관 행렬 만들기
이제 두 변수 간의 상관관계를 계산해보는 단계입니다. 상관관계는 두 값이 어떻게 함께 변하는지를 나타내요. 예를 들어, 실업자가 많아질수록 소비지출이 줄어드는지, 아니면 늘어나는지를 알아보는 거예요.
economics[['unemploy', 'pce']].corr()
- corr() 함수는 상관 행렬을 계산합니다. 상관 행렬은 여러 변수 간의 상관관계를 보여줘요.
- 여기서는 실업자 수(unemploy)와 개인소비지출(pce) 간의 상관관계를 계산하고 있어요.
- 상관관계의 값은 -1에서 1 사이의 값이에요. 1에 가까울수록 두 변수는 강하게 양의 상관관계를 가지며, -1에 가까울수록 강한 음의 상관관계를 가집니다. 0에 가까우면 상관관계가 거의 없다는 뜻이에요.
3. 상관 분석 (상관계수와 유의확률)
이제 두 변수 간의 상관계수와 p-value를 구해보는 단계입니다. 상관계수는 두 변수 간의 관계 강도를 나타내고, p-value는 그 관계가 통계적으로 의미 있는지 확인하는 값이에요.
stats.pearsonr()
- pearsonr() 함수는 두 변수 간의 피어슨 상관계수를 계산해줍니다. 피어슨 상관계수는 -1에서 1 사이의 값이며, 두 변수 간의 선형 관계를 측정해요.
- 여기서는 실업자 수(unemploy)와 개인소비지출(pce) 간의 피어슨 상관계수를 계산하고 있어요.
- 이 함수는 상관계수와 p-value를 반환해요.
- 상관계수: 두 변수 간의 관계 강도를 나타내요. 값이 1에 가까우면 양의 상관관계(정비례), -1에 가까우면 음의 상관관계(반비례)입니다.
- p-value: 상관관계가 통계적으로 유의미한지 확인하는 값이에요. 보통 p-value가 0.05보다 작으면 상관관계가 있다고 결론을 내릴 수 있어요.
4. 상관 행렬 히트맵 만들기
이제 다른 데이터(mtcars.csv)를 사용해 상관 행렬을 시각적으로 표현하는 히트맵을 만들어볼 거예요. 히트맵은 상관관계를 색깔로 나타낸 그래프입니다.
4.1. 데이터 불러오기와 상관 행렬 계산
mtcars.head()
- head() 함수는 데이터의 처음 몇 줄을 보여줍니다. 데이터가 어떻게 생겼는지 확인할 수 있어요.
mtcars.corr()
- 이 함수는 mtcars 데이터의 상관 행렬을 계산합니다. 여러 변수 간의 상관관계를 한 번에 확인할 수 있어요.
- round(car_cor, 2)는 상관계수 값을 소수점 둘째 자리까지 반올림해 깔끔하게 보여주는 작업이에요.
4.2. 히트맵 그리기
이제 상관 행렬을 히트맵으로 시각화해보겠습니다.
- matplotlib.pyplot은 그래프를 그리기 위한 라이브러리이고, seaborn은 데이터를 더 쉽게 시각화할 수 있는 라이브러리예요.
plt.rcParams.update()
- 이 코드는 그래프의 설정을 바꿔요. 해상도(dpi)와 그래프의 크기(figsize)를 설정할 수 있어요.
sns.heatmap()
- heatmap() 함수는 상관 행렬을 시각적으로 표현하는 히트맵을 그려줍니다.
- annot=True: 각 셀에 상관계수를 표시해줍니다.
- cmap='RdBu': 히트맵의 색깔 맵을 빨강-파랑(Red-Blue)으로 설정합니다. 양의 상관관계는 파란색, 음의 상관관계는 빨간색으로 표현돼요.
- plt.show()는 그래프를 화면에 표시합니다.
4.3. 대각선 행렬 제거하기
히트맵에서 대각선 부분은 변수와 자기 자신과의 상관관계라 의미가 없어요. 이를 제거해봅시다.
np.zeros_like()
- 이 함수는 주어진 행렬(car_cor)과 같은 크기의 0으로 채워진 행렬을 만들어줍니다. 이 행렬을 mask라고 해요.
np.triu_indices_from()
- 이 함수는 행렬의 오른쪽 위 대각선 부분의 인덱스를 반환해줍니다.
- 여기서는 mask 행렬의 오른쪽 위 대각선 부분을 1로 바꿔줘요. 이는 히트맵에서 그 부분을 표시하지 않도록 하기 위함이에요.
- mask=mask: 오른쪽 위 대각선 부분을 가리도록 mask를 적용해요. 이제 그 부분은 히트맵에서 표시되지 않아요.
4.4. 빈 행과 빈 열 제거하기
히트맵에서 첫 번째 행과 마지막 열을 제거한 새로운 히트맵을 만들 수 있어요.
mask[1:, :-1]
- mask 행렬에서 첫 번째 행과 마지막 열을 제거합니다.
- 이 히트맵은 앞에서 만든 것과 비슷하지만, 첫 행과 마지막 열이 제거된 상태입니다.
4.5. 히트맵 세부 설정
마지막으로 히트맵을 더 세부적으로 설정할 수 있는 옵션을 추가해볼게요.
세부 설정 설명
- `linewidth
함수(매소드) | 설명(역할) | |
1 | equal_var = True | 집단 간 분산이 같다고 가정 |
2 | corr() | 상관행렬을 생성 |
3 | round( , 2) | 2번째 자리에서 반올림 |
4 | annot=True | 상관계수 표시하겠다는 이야기 |
5 | scipy패키지의 ttest_ind() | t_test를 확인할 수 있는 함수 |
6 | query | 데이터를 조건에 맞게 필터링해주는 함수입니다. |
'데이터 분석 및 시각화' 카테고리의 다른 글
[데이터분석] ML_linearregression(선형회귀) (0) | 2024.08.23 |
---|---|
[데이터분석] ML(머신러닝)_basic, 데이터 분리 (0) | 2024.08.21 |
[데이터분석] 넘파이&판다스 (0) | 2024.08.19 |
[데이터분석]텍스트마이닝 , 워드클라우드, 지도시각화 (0) | 2024.08.14 |
[데이터분석] 인터렉티브, 마크다운 실습 (0) | 2024.08.13 |