본문 바로가기

Study/class note

python / 상관관계그래프, 신뢰구간그래프 (도박사 이야기)

159 상관관계 그래프 그리기

상관관계란 두 개의 변수(컬럼) 간의 선형 관계정도를 시각화하는 그래프

 

2. 판다스 

import matplotlib.pyplot as plt
import pandas as pd

ins = pd.read_csv("c:\\data\\insurance.csv")
ins.corr()  # 상관계수 값. 기본이 피어슨이라서 method = 'pearson' 굳이 안써도 됨

plt.matshow(ins.corr(method = 'pearson'))

문제562. 위의 그래프의 결과에서 컬럼명도 같이 출력되게 하시오.

a = ['id','age','bmi','children','expenses']

fig = plt.figure()  # 그래프를 그리겠다고 영역지정. () 안에 아무것도 없으면 기본 지정
ax = fig.add_subplot(111)  # 1x1 그리드, 첫번째 서브플롯을 의미함. add_subplot(1,1,1)
cax = ax.matshow(ins.corr(method = 'pearson'), interpolation = 'bicubic') 
	 # ax를 상관관계 그래프로 그리겠다, interpolation은 연속적으로 보이게 하는 것
fig.colorbar(cax)  # cax변수에 담긴 그래프를 출력

ax.set_xticklabels(['']+a)  # null값을 추가하지 않으면 하나씩 밀림
ax.set_yticklabels(['']+a)   # 위에는 x축, 아래는 y축

plt.show()

왼쪽은 interpolation = 'nearest', 오른쪽은 interpolation = 'bicubic'

색상은 cmap 으로 지정하면 되고, interpolation은 퍼짐정도로 그래프의 경계를 나타내지 않으면서 상관계수의 차이를 보여주고 싶을때 사용

 

+) add_subplot 추가 설명

 

문제563. 미국 우주 왕복선 폭파 원인의 결과로 o형링 파손수와 상관관계가 있는 컬럼이 어떤 것인지 상관관계 그래프로 시각화 하시오.

import pandas as pd

cha = pd.read_csv("c:\\data\\challenger.csv")
cha.corr()

# col 정보
# distress_ct: o형링 파손수
# temperature : 온도
# field_check_pressure : 압력
# flight_num : 비행기 번호

fig = plt.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(cha.corr(method = 'pearson'), cmap = 'GnBu')
fig.colorbar(cax)

fig.set_size_inches(10,8)
ax.set_xticklabels(['']+col)
ax.set_yticklabels(['']+col)

plt.show()

문제564. 위의 상관관계 그래프를 자동화 코드에 추가 시키시오.

g = """
########## 판다스 ##########
import pandas as pd

cha = pd.read_csv("c:\\\data\\\challenger.csv")
cha.corr()

fig = plt.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(cha.corr(method = 'pearson'), cmap = 'GnBu')
fig.colorbar(cax)

fig.set_size_inches(10,8) #그래프 사이즈
ax.set_xticklabels(['']+col)
ax.set_yticklabels(['']+col)

plt.show()

########## seaborn ##########
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
 
cars = pd.read_csv("c:\\data\\usedcars.csv")
sns.heatmap(cars.corr(), annot = True, cmap = 'GnBu', linewidths = 0.2)  
fig = plt.gcf() # fig를 지정하고 나서
fig.set_size_inches(10,8) # 그래프의 사이즈 조절
plt.show()
"""

 

+) 판다스 데이터프레임 특정 컬럼 제외하고 출력하기

import pandas as pd

ins = pd.read_csv("c:\\data\\insurance.csv")
ins[ins.columns.difference(['id'])]

+) 상관관계 그래프 참고 블로그

https://m.blog.naver.com/kiddwannabe/221763497317

 

상관관계 분석 시각화 - correlation matrix (df.corr, sns.heatmap)

변수간의 상관관계를 시각화 하는 방법에 대해 정리해보려고 합니다. 아래와 같이 만들어 보려고 해요 먼저...

blog.naver.com

 

 

160 신뢰구간 그래프 그리기( 도박사 이야기 )

( 원본은 통계학(출판사 성안당) 책 76페이지 참고하였음 )

 

해외 여행 중 어느 뒷골목에서 동전으로 내기를 하는 도박사를 만났다. 

"앞면이 나오면 당신에게 1달러, 뒷면이 나오면 나에게 1달러, 어때요? 이 내기 한번 해볼래요?"

그런데 동전에 부정이 있는듯해 실제로 알아봤더니 8회 중 7회는 뒷면이 나왔다. 이 동전은 뒷면이 나오기 쉬운 것 아니냐고 물었더니 도박사는 "앞면과 뒷면이 나올 확률이 같은 동전이라도 우연히 그럴 수 있다."라고 대답했다. 어떻게 반론하면 좋을까?

 

예제1. 동전 하나를 10000번 던져서 앞면이 나올 횟수를 출력하시오. ( 힌트 : random.randint(0,1) )

import random

cnt = 0
for i in range(10000):
    a = random.randint(0,1)  # 앞면: 0, 뒷면: 1
    if a == 0:
        cnt += 1
        
print(cnt)

+) random모듈의 randint()

randint() 괄호 안에 넣은 값의 범위에서 랜덤 정수를 리턴함. 

 

예제2. 동전 하나를 8번 던졌을 때 그 중 뒷면이 5번이 나오는 횟수를 출력하시오.

import random

cnt = 0   # 뒷면이 5번 나오는 횟수 담기 위한 변수
for i in range(10000):
    coin_cnt = 0   # 뒷면이 나오는 횟수 담기 위한 변수
    for k in range(8):
        result = random.randint(0,1)  # 앞면: 0, 뒷면: 1
        if result == 1: # 뒷면일때
            coin_cnt += 1
    if coin_cnt == 5:
        cnt += 1
        
print(cnt)

예제3. 도박사의 동전으로 동전을 8번 던졌을 때 뒷면이 7번이 나왔습니다. 이게 도박사의 말처럼 우연인지 아니면 도박사가 동전에 트릭을 써서 "뒷면이 나오기 쉽게" 상황을 만든건지를 증명하려면 다음과 같은 실험을 한 결과가 있어야 합니다. 

> "동전을 8번 던져서 뒷면이 나오는 횟수가 아래의 리스트에 담으시오"

동전의 뒷면이 나오는 횟수 

0      1      2       3         4        5         6       7       8

[412, 3026, 10798, 22010, 27651, 21682, 10851, 3191, 379]

# 내가 쓴 코드
import random

sum_cnt = {}   # 동전 뒷면이 나오는 횟수를 각각 0~8번째까지 사전형으로 만듦
for s in range(0,9):
    sum_cnt[s] = []

for i in range(100000):
    coin_cnt = 0   # 뒷면이 나오는 횟수 담기 위한 변수
    for k in range(8):
        result = random.randint(0,1)  # 앞면: 0, 뒷면: 1
        if result == 1: # 뒷면일때
            coin_cnt += 1
    for num in range(9):   # num번째일때 1씩 리스트에 추가됨
        if coin_cnt == num:
            sum_cnt[num].append(1)

result = [] 
for r in range(0,9):
    result.append(len(sum_cnt[r]))   # 리스트에 담긴 1의 갯수를 카운트 = sum의 기능
result

# 다른사람이 쓴 코드 참고해서 수정한 코드
import random

sum_cnt = [0]*9

for i in range(100000):
    coin_cnt = 0   # 뒷면이 나오는 횟수 담기 위한 변수
    for k in range(8):
        result = random.randint(0,1)  # 앞면: 0, 뒷면: 1
        if result == 1: # 뒷면일때
            coin_cnt += 1
    for num in range(9):   # num번째일때 1씩 리스트에 추가됨
        if coin_cnt == num:
            sum_cnt[num]+= 1

sum_cnt

=> 여기서 중요한 것은 리스트의 요소값에 사칙연산이 가능하다는 것

a = [1]

a[0] +=1
a   # [2]

b = ['대한']
b[0] += '민국'
b   # ['대한민국']

+) 다른 사람이 쓴 코드 

import random

coin = [0]*9   # 0이 9개인 리스트를 만듦

for k in range(100000):  # 동전 8번 던지는 실험을 10만번 실시
    cnt = 0   # 동전 뒷면이 나오는 횟수를 담을 변수 0으로 초기화
    for i in range(8):   
        n = random.randint(0,1)  # 동전을 던진 결과가
        if n == 1:    # 뒷면이면
            cnt += 1   # 카운트
    coin[cnt] += 1    # 뒷면이 나온 갯수와 coin리스트의 요소 번호가 같음
                      # 해당 요소 값에 1씩 더함

print(coin)

예제4. (점심시간 문제) 뒷면이 나온 횟수를 센 리스트를 가지고 확률로 나타내시오

import random

coin = [0]*9   # 0이 9개인 리스트를 만듦

for k in range(100000):  # 동전 8번 던지는 실험을 10만번 실시
    cnt = 0   # 동전 뒷면이 나오는 횟수를 담을 변수 0으로 초기화
    for i in range(8):   
        n = random.randint(0,1)  # 동전을 던진 결과가
        if n == 1:    # 뒷면이면
            cnt += 1   # 카운트
    coin[cnt] += 1    # 뒷면이 나온 갯수와 coin리스트의 요소 번호가 같음
                      # 해당 요소 값에 1씩 더함
coin_p = []
for j in coin:
     coin_p.append(j/100000)
    
coin_p

예제5. 위의 리스트의 결과를 막대 그래프로 그리시오.

x축을 [0,1,2,3,4,5,6,7,8] y축을 확률로 넣으시오.

import random
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

coin = [0]*9   # 0이 9개인 리스트를 만듦

for k in range(100000):  # 동전 8번 던지는 실험을 10만번 실시
    cnt = 0   # 동전 뒷면이 나오는 횟수를 담을 변수 0으로 초기화
    for i in range(8):   
        n = random.randint(0,1)  # 동전을 던진 결과가
        if n == 1:    # 뒷면이면
            cnt += 1   # 카운트
    coin[cnt] += 1    # 뒷면이 나온 갯수와 coin리스트의 요소 번호가 같음
                      # 해당 요소 값에 1씩 더함
coin_p = []
for j in coin:
     coin_p.append(j/100000)
    
coin_p

x = [0,1,2,3,4,5,6,7,8]

plt.bar(x,coin_p, tick_label = x, color = 'lightsteelblue')
plt.rc('font',family = 'Malgun Gothic')  # 한글 안깨지게 하는 코드
plt.legend(['뒷면이 나오는 확률'])
plt.show()

지금 위에서 출력된 막대 그래프의 결과에 확률값들에 대한 신뢰구간을 지정하려면 확률밀도함수값을 알아야함.

 

확률밀도함수 : 확률 변수의 분포를 나타내는 함수로, 확률변수 x가 구간 [a,b]에 포함될 확률을 출력하는 함수 

확률밀도함수값을 출력하려면 x축의 값들에 대한 평균값과 표준편차를 구해야함.

 

예제6. x변수에 들어있는 동전 뒷면이 나온 횟수들의 평균값과 표준편차를 출력하시오.

import numpy as np

x = [0,1,2,3,4,5,6,7,8]

x_m = np.mean(x)   # 평균값
x_s = np.std(x)    # 표준편차

print(x_m)  # 4.0
print(x_s)  # 2.581988897471611

예제7. 위에서 구한 평균값과 표준편차를 이용해서 x변수의 요소값에 대한 확률 밀도함수값을 출력하시오.

import numpy as np
x = [0,1,2,3,4,5,6,7,8]
x_m = np.mean(x)   # 평균값
x_s = np.std(x)    # 표준편차

print(x_m)  # 4.0
print(x_s)  # 2.581988897471611

from scipy.stats import norm

result = norm.pdf(x, x_m, x_s)
print(result)   # x변수의 요소값에 따른 각각의 확률밀도함수
# [0.04653742 0.0786696  0.11446359 0.14334535 0.15450968 0.14334535 0.11446359 0.0786696  0.04653742]

from scipy.stats import norm 에 확률밀도함수 구하는 메소드가 있음.

확률밀도함수 = norm.pdf(데이터, 평균값, 표준편차) 

 

예제8. x =[0,1,2,3,4,5,6,7,8]을 x축으로 두고 위의 확률밀도함수값을 y축으로 두어서 확률밀도함수 그래프를 그리시오.

import numpy as np
x = [0,1,2,3,4,5,6,7,8]
x_m = np.mean(x)   # 평균값
x_s = np.std(x)    # 표준편차

print(x_m)  # 4.0
print(x_s)  # 2.581988897471611

from scipy.stats import norm

result = norm.pdf(x, x_m, x_s)   
print(result)

import seaborn as sns
import matplotlib.pyplot as plt

plt.plot(x, result, color = 'black')
plt.show()

확률밀도함수 그래프로 보면, 동전 뒷면이 4개가 나오는 확률이 가장 높음을 확인할 수 있음.

 

예제9. 위의 그래프에서 신뢰구간 68%에 해당하는 부분만 색을 색칠하시오.

 

- 신뢰구간범위( 양측검정)

1. 68% : 평균을 기준으로 ± 1 * 표준편차

2. 95% : 평균을 기준으로 ± 1.96 * 표준편차

3. 99% : 평균을 기준으로 ± 2.58 * 표준편차

 

import matplotlib.pyplot as plt

plt.plot(x, result, color = 'black')
plt.fill_between(x, result, where = (x < x_m + x_s)&(x > x_m - x_s), color = 'lightsteelblue')
plt.show()

예제10. 신뢰구간 95%에 해당하는 영역으로 색을 칠하시오

import matplotlib.pyplot as plt

plt.plot(x, result, color = 'black')
plt.fill_between(x, result, where = (x < x_m + 1.96*x_s)&(x > x_m - 1.96*x_s), color = 'lightsteelblue')
plt.xticks(range(0,9))
plt.show()

x = [0,1,2,3,4,5,6,7,8] 

 

예제11. 동전을 8번 던졌을 때 동전이 뒷면이 나오는 횟수가 신뢰구간 68% 안에 드는지 아닌지를 출력하는 함수를 생성하시오.

def coin_hypo(count):
    import numpy as np
    
    x = [0,1,2,3,4,5,6,7,8]
    x_m = np.mean(x)   # 평균값
    x_s = np.std(x)    # 표준편차

    if (count < x_m + x_s) and (count > x_m - x_s):
        print('동전 8번 던졌을 때 뒷면이 나오는 횟수가 ',count,'번이 나올 확률은 신뢰구간 68% 안에 있습니다.')
    else:
        print('동전 8번 던졌을 때 뒷면이 나오는 횟수가 ',count,'번이 나올 확률은 신뢰구간 68% 안에 없습니다.')

 

ㅇ 단측검정과 양측검정

- 단측검정

귀무가설 : (도박사) 앞면과 뒷면이 나올 확률은 같다. (우연히 뒷면이 많이 나왔다)

대립가설 : (검정하는 사람) 뒷면이 나오기 쉽다. 

 

- 양측검정

귀무가설 : (도박사) 앞면과 뒷면이 나올 확률은 같다.

대립가설 : (검정하는 사람) 앞면과 뒷면이 나올 확률은 같지 않다.

기각역 안에 들어간다면 대립가설을 채택 ? 

기각역 밖에 있다면 귀무가설을 수용함 ?

> 확률 공부해서 확실하게 알아두기

https://blog.naver.com/awess0me/222538319459

- 단측검정일 때 신뢰구간

1. 95% : 평균 ± 1.65*표준편차

2. 99% : 평균 ± 2.33*표준편차

 

다른예제. 2000년 초등학교 5학년 어린이들의 전국 평균키는 148.5cm, 분산은 7.8^2 이었다. 식생활의 변화로 인해 어린이들의 성장에 변화가 일어났다고 생각된다. 그래서 현대의 초등학교 5학년 어린이들을 무작위로 100명을 추출했다. 그 평균키는 149.2cm였다. 

초등학교 5학년 어린이들의 키에 변화가 일어났는지를 유의수준5%로 검정해보자. 단, 분산은 변화없다고 가정하자

 

1. 귀무가설 > 평균키는 148.5cm이다. 

2. 대립가설 > 평균키는 148.5cm보다 크다.

3. 유의수준 정하기 > 5%로 유의수준을 정함

4. 검정통계량의 분포를 그린다 > 

5. 기각역을 설정

6. 검정통계량의 값이 기각역에 있는지 확인한다.

 

== 149.2cm는 기각역에 없다는 것을 확인하였으므로 귀무가설을 기각할 수 없다.

 

 

https://thebook.io/080246/part04/ch15/unit32-10/

 

모두의 인공지능 기초 수학: UNIT 32 통계적 검정 - 10

 

thebook.io

 

 

문제565. 서울시 초등학생 백만명의 키 모집단을 구성하는데 평균키가 148.5cm이고 표준편차가 30인 모집단을 만드시오.

import numpy as np

avg = 148.5
std = 30
N = 1000000

mo = np.random.randn(N)*std+avg   # 모집단
print(mo)

문제566. 위의 모집단에서 100명을 표본추출하여 100명의 평균키를 비어있는 리스트 a에 입력하는 작업을 10000번 수행되게 하세요.

import numpy as np

avg = 148.5
std = 30
N = 1000000

mo = np.random.randn(N)*std+avg   # 모집단

a = []
for i in range(10000):
    result = np.random.choice(mo,100).mean()  # 모집단에서 랜덤 100명 추출, 평균 구하기
    a.append(result)

print(a)

문제567. 위의 a 리스트에 담겨진 표본의 평균키값들에 대한 확률밀도함수 값을 출력하시오.

import numpy as np

avg = 148.5
std = 30
N = 1000000

mo = np.random.randn(N)*std+avg   # 모집단

a = []
for i in range(10000):
    result = np.random.choice(mo,100).mean()  # 모집단에서 랜덤 100명 추출, 평균 구하기
    a.append(result)

from scipy.stats import norm

x = np.arange(140,160,0.001) # 140부터 160까지 0.001간격으로 x축 생성
y = norm.pdf(x, np.mean(a), np.std(a) )   # 확률 밀도함수 값

print(y)

문제568. 위의 x값과 확률 밀도 함수값 y를 가지고 확률밀도함수 그래프를 그리시오.

import numpy as np

avg = 148.5
std = 30
N = 1000000

mo = np.random.randn(N)*std+avg   # 모집단

a = []
for i in range(10000):
    result = np.random.choice(mo,100).mean()  # 모집단에서 랜덤 100명 추출, 평균 구하기
    a.append(result)

from scipy.stats import norm

x = np.arange(140,160,0.001) # 140부터 160까지 0.001간격으로 x축 생성
y = norm.pdf(x, np.mean(a), np.std(a) )   # 확률 밀도함수 값

import matplotlib.pyplot as plt

plt.plot(x, y)

plt.show()

문제569. 149.2cm 키에 대한 지점을 다음과 같이 그래프로 그리시오.

import numpy as np

avg = 148.5
std = 30
N = 1000000

mo = np.random.randn(N)*std+avg   # 모집단

a = []
for i in range(10000):
    result = np.random.choice(mo,100).mean()  # 모집단에서 랜덤 100명 추출, 평균 구하기
    a.append(result)

from scipy.stats import norm

x = np.arange(148.5-10,148.5+10,0.001) # 140부터 160까지 0.001간격으로 x축 생성
y = norm.pdf(x, np.mean(a), np.std(a) )   # 확률 밀도함수 값

import matplotlib.pyplot as plt

plt.plot(x, y)
plt.scatter(149.2, 0, color = 'red')

plt.show()

문제570. 아래의 초등학생 5학년 키에 대한 귀무가설과 대립가설을 파이썬으로 구현하여 표본 평균키 149.2cm가 기각역이 있는지 없는지 출력되게 하시오.

tall_gumjung(149.2)

"149.2cm는 기각역에 없습니다."

def tall_gumjung(num):
    import numpy as np

    avg = 148.5
    std = 7.8
    N = 1000000

    mo = np.random.randn(N)*std+avg   # 모집단

    result = np.random.choice(mo,100) # 모집단에서 랜덤 100명 추출

    result_m = np.mean(result)
    result_s = np.std(result)

    if (num < result_m + result_s) and (num >result_m -result_s):
        print(num,'는 기각역에 없습니다.')
    else:
        print(num,'는 기각역에 있습니다.')

 

 

 

 

 

+) 참고 유튜브 영상

https://www.youtube.com/watch?v=WXmn6oQ3xGk 

https://www.youtube.com/watch?v=xBINhrCQB-g 

 

 

반응형