티스토리 뷰

★ 범주형 vs 범주형

- 교차표: crosstab()

- 시각화: 100% stacked Bar, Mosaic Plot

- 수치화: 카이제곱 검정

 

 

1. 교차표

 

범주형 vs 범주형을 비교하기 위해서는 교차표를 먼저 만들어야된다.

 

- Pandas 사용

crosstab()

 

Sex(범주형) -> Survived(범주형) 교차표

pd.crosstab(titanic['Sex'], titanic['Survived'])
 

 

Embarked(범주형) -> Survived(범주형) 교차표

pd.crosstab(titanic['Embarked'], titanic['Survived'])

 

※ 교차표의 속성값(normalize)

'index': 각 행의 상대적인 비율(각 행의 합이 1)

'columns': 각 열의 상대적인 비율(각 열의 합이 1)

'all': 각 셀의 상대적인 비율(전체 합 1)

 

pd.crosstab(titanic['Embarked'], titanic['Survived'], normalize='columns')
pd.crosstab(titanic['Embarked'], titanic['Survived'], normalize='index')
pd.crosstab(titanic['Embarked'], titanic['Survived'], normalize='all')

통상적이로 'index' 속성을 많이 사용한다.

 

2. 시각화

 

범주형 vs 범주형 시각화는 100% Stacked Bar, Mosaic Plot 도구를 사용한다.

 

1) 100% Stacked Bar

 

- 범주형 vs 범주형이므로 교차표를 일단 만들기

Pclass(범주형) -> Survived(범주형)

table = pd.crosstab(titanic['Pclass'], titanic['Survived'], normalize='index')
table

Pclass 행의 합이 1이되고 

각 객실등급별로 생존자, 사망자의 비율을 나타낼 수 있게되었다.

 

- 교차표 만들었으니 Stacked Bar로 시각화하기

1 - titanice['Survived'].mean()은 사망자의 평균이다.

table.plot(kind='bar', stacked=True)

plt.axhline(1-titanic['Survived'].mean(), color='r')
plt.xticks(rotation=0)
plt.show()

 

육안으로 봤을때 비율을 따져보면 

1: 생존자 > 사망자

2: 생존자 = 사망자

3: 생존자 < 사망자


사망자의 평균을 봤을 때 1클래스, 2클래스는 평균보다 생존자가 많다는 것을 알 수 있다.

 

2) Mosaic Plot

 

100 % Stacked Bar는 비율만 비교하므로 양에 대한 비교는 할 수 없다.

이를 극복하기위하여 Mosaic Plot이 나왔다.

 

- tastmodels.graphics.mosaicplot

mosaic(): Mosaic Plot 그리기

 

mosaic(titanic, ['Pclass', 'Survived'])
plt.axhline(1-titanic['Survived'].mean(), color='r')
plt.show()

 

 

x 축 길이는 객식 등급별 승객 비율을 양적으로 나타낸것 

=> 3 > 1 > 2 순으로 많이 탔죠?

 

y 축 길이는 객실 승객의 사망, 생존 비율을 나타낸것

=> 3은 사망자 수가 많고, 1은 생존자 수가 많고, 2는 비슷하고

 

왜 x 축이 3, 1, 2 순으로 표시될까? 범주형이기때문에 그냥 표에서 나타난 순으로 표시한것임

정렬하고 싶으면 

sort_values() 사용

※ gap을 통해 영역 간격 조절 가능

mosaic(titanic.sort_values(['Pclass', 'Survived']), ['Pclass', 'Survived'], gap=0.01)
plt.axhline(1-titanic['Survived'].mean(), color='r')
plt.show()

 

이렇게 할 경우 Pclass로 먼저 정렬하고 Survived로 정렬

 

3. 수치화

 

범주형 vs 범주형 관계를 수치화해 비교할 때는 카이제곱검정을 사용

개념: 기대값과 실제값의 차이가 얼마나 큰지?(이론적으로 나와야할값 vs 실제값)

 

- scipy.stats 라이브러리 사용

chi2_contingency()

 

※ 카이제곱통계량(어려움 주의)

카이제곱통계량은 클수록 기대빈도로부터 실제 값의 차이가 크다는 의미

=> 자유도의 2~3배보다 크면, 차이가 있다고 본다

 

예를들어 Pclass 범주가 3개, Survived 범주가 2개이면

카이제곱검정은

(3-1)*(2-1) = 2

2의 2~3배인 4~6보다 통계량이 크면 차이가 있다고 볼 수 있다.

 

카이제곱 예시)

기대값과 실제값이 얼마나 차이가 나는지 확인

 

ⅰ. 문제

학년에 따라 급식 선호도가 다를까?

=>

grade, like 둘다 범주형

=>

3학년이 좋아함이 확실히 많지만 인원도 많으니 이걸 수치적으로 확인해봐야된다.

=>

기대값(기대빈도를 확인)

 

학교 급식

 

ⅱ. 기대빈도 계산

만약 학년과 선호도 사이에 차이가 없다면이라는 전제하에 계산을 하는 것

 

 

1학년이 좋아함 기대값

 

ⅲ. 실제값과 기대값의 차이를 구한다.

우리가 계산한 기대빈도: 133

실제값: 80

 

ⅳ. 차이가 얼마나 큰지 카이제곱 통계량을 구한다.

 

왜 제곱이냐? 어떤 값은 양수, 어떤 값은 음수여서 차이를 더하면 서로 상쇄될 수 있다.

그러면 차이의 크기가 왜곡될 수 있다.

 

왜 차이를 기대값으로 나누냐? 기대값이 작은 값과 큰 값이 있을 때 같은 차이를 똑같이 평가 할 수 없으므로

비율을 똑같이 만들어줘야함 => 상대적인 차이를 반영해야됨

 

이를 반복해서 다 더하기

 

 

ⅴ. 값이 자유도의 2~3배보다 크면 학년과 급식 선호도가 관련이 있다라고 판단할 수 있다.

 

 

-실습-

 

1) 범주형 vs 범주형이므로 교차표 만들기

 

table = pd.crosstab(titanic['Pclass'], titanic['Survived'])
table

 

2) 카이제곱 검정 수행

chi2_countingency(table)

result = spst.chi2_contingency(table)
print('* 카이제곱통계량:', result[0])
print('* p-value:', result[1])
print('* 기대빈도:\n',result[3])

 

 

카이제곱은 자동으로 나오니 어려워하지말자

result = spst.chi2_contingency(table)
print('* 카이제곱통계량:', result[0])
print('* p-value:', result[1])
print('* 기대빈도:\n',result[3])

 

카이제곱통계량: 기대빈도와 실제 빈도의 차이가 크다!!

p-value: 대립가설 채택 기대빈도와 실제빈도가 유의미하게 다름

기대빈도: 우리가 계산한 기대값

결론: 객실 등급별로  생존자수가 엄청나게 차이난다!!

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함