본문 바로가기
기본소양/CODE

2. Statistics [4] CODE

by EXUPERY 2021. 1. 10.
반응형

0. 데이터 셋 만들기

# 패키지설치
!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf
!pip3 install numpy
!pip3 install pandas

import pandas as pd
import numpy as np
import io 
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl
import warnings

plt.rc('font', family='NanumBarunGothic') 
mpl.rc('axes', unicode_minus=False)
warnings.filterwarnings("ignore")
%matplotlib inline
%config InlineBackend.figure_format='retina'
# Local Fiel Upload
from google.colab import files 
uploaded = files.upload() 
df = pd.read_csv(io.BytesIO(uploaded['file1.csv']), encoding='CP949')

# URL
URL = "https://..."
df = pd.read_csv("URL", sep="\t", skiprows = 1)
# 데이터 확인
print(df.head()) # 데이터 head 열어서 파악
print(df.tail()) # 데이터 head 열어서 파악
print(df.info()) # 데이터의 type등 확인
print(df.shape) # shape확인
print(df.isnull().sum()) # 결측 값 수
print(df.sum()) # 합
# 데이터 바꾸기
df.dropna(inplace=True) # 결측값제거하고 (필요시) 
df.isnull().sum() # 결측값없앤거 확인 (필요시)
df.fillna(0, inplace=True) # 결측값 0으로 바꾸기

df.set_index('feature이름', inplace=True) # feature를 index로 set
df = df.drop(index=['index1', 'index3', 'index5']) # 필요없는 index제거
df = df.replace({'-':0}) # -를 0으로 바꾸기
df[feature1] = pd.to_numeric(trees['feature1'].str.replace(',','')) # ,를 없애기

def toInt(string): # toInt 함수만들기 (apply 용)
  if type(string) == str :
    return int(string.replace(',',''))
  else :
    return string

for i in df.columns : # for로 apply
    df[i] = df[i].apply(toInt)

# 슬라이싱하기
 # 열 고르기 
df['feature1'] df[['feature1','feature2']] # 여러 열 고르기 
df.loc[:, "feature3"] # 3열까지 고르기
df.loc[:, ["feature1", "feature2"]] # 1,2열 고르기 
df.loc[:, "feature1" : "feature3"] # 3열까지 고르기 
df.iloc[:, 0] # 0열 df.iloc[:, [0, 2]] # 0,2열 
df.iloc[:, 0:2] # 0~1열 

 # 행 슬라이싱 
df['index1':'index3'] # 행1부터 3까지 
df.loc['index1'] # 1행만 
df.loc[['index1','index3']] # 1,3행 
df.loc['index1':'index3'] # 행1 ~ 행3 
df.iloc[0] # row 0번째 df.iloc[[0, 2]] # 0,2 행 
df.iloc[0:2] # 0~1 행 

 # 원소 선택 
df.loc['index','feature'] 
df.iloc['index number','feature number']

 # 특정데이타가 있는 행 슬라이싱
df = df[df['feature1'] == 'dataname'][['feature1','feature2','feature3']] # 1번방법
df.query('feature1 =="dataname"') # 2번방법

1. One Sample T-tests

# H0 : 알려진 평균  = 표본의 평균
# H1 : 알려진 평균 != 표본의 평균

from scipy import stats
print(df['feature1'].mean()) # 표본의평균
print(stats.ttest_1samp(df['feature1'], 알려진평균))
# Output >>> T-statics, pvalue

2. Two Sample T-tests

# H0 : 표본1의 평균  = 표본2의 평균
# H1 : 표본1의 평균 != 표본2의 평균 (two tailed)
# H1 : 표본1의 평균 < 표본2의 평균 or 표본1의 평균 > 표본2의 평균

from scipy import stats
print(df['feature1'].mean()) # 표본1의평균
print(df['feature2'].mean()) # 표본2의평균
print(stats.ttest_ind(df['feature1'],df['feature2']))
# Output >>> T-statics, pvalue

# Two-tailed >> pvalue
# One-tailed >> pvalue/2 >> statistics 확인 후 대소비교

3. One Sample Chi-square Test

# H0 : 종속변수는 독립변수와 연관성이 없다
# H1 : 종속변수는 독립변수와 연관성이 있다

df = df[['독립변수','종속변수']] # 종속변수데이터를 갖고있는 독립변수를 뽑고
df.columns = ['독립변수','종속변수'] # 이름바꾸고
df = pd.DataFrame(df.groupby('독립변수').종속변수.sum()) #독립변수를 groupby해줘서 독립변수당ㅇ 한 수치만 남기고
df #데이터셋 완성

#with scipy chisquare
from scipy.stats import chisquare  
chisquare(df, axis=None)
# Output >>> chisquare-statics, pvalue


#without scipy chisquare
from scipy import stats
obs = np.array(df['종속변수']) # 관측값
exp = df['종속변수'].mean() # 기대빈도
squared = np.power(obs - exp,2) # (관측값 - 기대빈도)^2
df_list = df['종속변수'].tolist() # 갯 수새기위해서 
n = len(df_list) # n
freedom = len(df_list) - 1 # 자유도
x2 = np.sum(squared/exp) # 카이제곱 값
pv = 1 - stats.chi2.cdf(x2, freedom) # pvalue로 전환

print('관측값 : ',obs)
print('기대값 : ',exp)
print('(관측값 - 기대값)의 제곱 : ',squared)
print('자유도 : ', freedom)
print('\n 카이스퀘어함수를 사용하지않은 결과값')
print('카이제곱값 : ',x2)
print('p-value =',pv)

4. Two Sample Chi-square Test

# H0 : 종속변수는 독립변수와 연관성이 없다
# H1 : 종속변수는 독립변수와 연관성이 있다

# 독립변수 1과 독립변수 2를 행과 열로 넣는다.
df = df[['독립변수1','독립변수2','종속변수']] 
df.columns = ['독립변수1','독립변수2','종속변수']
df = pd.crosstab(index=df['독립변수1'],columns=df['독립변수2'],values=df['종속변수'],aggfunc=np.sum)
df = df[['독립변수2의 feature1','독립변수2의 feature2','독립변수2의 feature3']]
df # 독립변수1이 행으로, 독립변수 2가 열로, 그 데이터가 종속변수로들어감

#two sample 카이제곱 검정
from scipy.stats import chi2_contingency
print(chi2_contingency(twochi, correction = False)) 
print(chi2_contingency(twochi, correction = True))
# Output >>> chisquare-statics, pvalue

5. One-way ANOVA

import scipy.stats as stats
import urllib
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
import matplotlib.pyplot as plt
%matplotlib inline
plot_data = [A,B,C,D]
ax = plt.boxplot(plot_data)
plt.show()
# 박스플롯으로 EDA
stats.f_oneway(A, B, C, D)
# Output >>> F-statics, pvalue

6. Sample 추출방법 (검정이전)

np.random.seed(1234) # seed 쓰거나
sample1 = df.sample(n=20, random_state=1234) # random_state사용
sample2 = df.sample(n=200, random_state=1234) #200개 표본 뽑은 sample2

7. 추출된 Sample 사용하여 신뢰구간측정 (구간추정)

class myCI( ) :
  def Describe (sample) :
    n = len(sample)
    mean = sample.mean()
    dof = len(sample)-1
    sd = np.std(sample, ddof=1)
    serr = sd / (n ** 0.5)
    min, max = t.interval(.95, dof, loc = mean, scale = serr)
    print('표본의 크기 : ', n)
    print('표본의 평균 : ', mean)
    print('표본의 자유도 : ', dof )
    print('표본의 표준편차 : ', sd)
    print('표본의 오차 : ', serr)
    print('\n')
  def CI_interval(sample) :  
    n = len(sample)
    stderr = stats.sem(sample) 
    print('표본의 오차 : ',stderr)
    mean = sample.mean()
    interval = stderr * stats.t.ppf( (1 + 0.95) / 2 , n - 1)
    print('신뢰구간 : ',mean - interval, mean + interval)

8. 시각화

# 에러를 반환하는 함수
def myerr (sample) :
  n = len(sample)
  mean = sample.mean()
  dof = len(sample)-1
  sd = np.std(sample, ddof=1)
  serr = sd / (n ** 0.5)
  min, max = t.interval(.95, dof, loc = mean, scale = serr)
  return serr
# Error Bar
x = ['size20','size200']
y = [sample1.mean(),sample2.mean()]
error = [myerr(sample1),myerr(sample2)]

plt.errorbar(x, y, yerr=error, capsize=10, linestyle="", marker='o')
plt.show()
# Bar + Error Bar
plt.bar('sample1', sample1.mean(), yerr=myerr(sample1), align='center', alpha=0.8, ecolor='black', capsize=6)
plt.bar('sample2', sample2.mean(), yerr=myerr(sample2), align='center', alpha=0.8, ecolor='black', capsize=6)
plt.show()

# With Seaborn
import seaborn as sns
data1 = pd.DataFrame({"sample20":sample1, "sample200":sample2})
ax = sns.barplot(data=data1, capsize=0.1)
# Displot
sample_list=[sample1,sample2]
ax = plt.subplots()
for sample in sample_list: 
  sns.distplot(sample)

9. Bayesian Theory

# P(실제음주자 | 테스트양성)
plusplus = 1 * 0.001 / (1 * 0.001 + 0.999 * 0.08) 
# 음주테스트결과'양성'인데 진짜음주 / (음주테스트결과'양성'인데 진짜음주 + 음주테스트결과'양성'인데 음주안함 )
print('{0:.2f}%'.format(plusplus*100))
  # prob_drunk_prior = 0.001
  # true_positive_rate = 1
  # false_positive_rate = 0.08

def prob_drunk_given_positive(prob_drunk_prior, false_positive_rate, true_positive_rate) : 
    real_drunk = prob_drunk_prior / (true_positive_rate * prob_drunk_prior + false_positive_rate * (1 - prob_drunk_prior))
    return real_drunk # 사후 확률

def bayes_times(n):
    if n != 1 :
        a = prob_drunk_given_positive(0.001,0.08,1)
        for i in range(0,n-1) :
            a = prob_drunk_given_positive(a,0.08,1)
        print(i+2,'회차 :','{0:.2f}%'.format(a*100))
        return a
    else :
        a = prob_drunk_given_positive(0.001,0.08,1)
        print(1,'회차 :','{0:.2f}%'.format(a*100))
        return a

i = 1
while True :
    if bayes_times(i) < 0.95 :
      i = i + 1 
      continue
    else :
      print('실제로 음주 했을 확률이 95% 이상으로 보장되기 위해서는, ',i,'번의 음주 테스트가 필요로 합니다')
      break
반응형

댓글