728x90

2023-10-19 31st Class

여러개의 정보가 있는 경우의 베이즈정리

Excercise 2. 스팸메일 (info가 2개인 경우) continue


#️⃣ 표준 통계학 관점의 데이터
스팸메일(SPAM)과 일반메일(HAM)의 비율
Spam : Ham = 0.5 : 0.5

#️⃣ 스팸 메일 기준의 Class 구분(y)
기준1
Link가 있는 메일이 스팸일 경우 = 0.6
Link가 있는 메일이 일반메일일 경우 = 0.2

기준 2
Word가 있는 메일이 스팸일 경우 = 0.4
Word가 있는 메일이 일반메일일 경우 = 0.05

이 경우에
(1) Link 기준으로 Bayes Theorem 값 -> P(S|L) = 0.75
(2) Word 기준으로 Bayes Theorem 값 -> P(S|W) = 0.89
(3) Link와 Word를 모두 고려한 Bayes Theorem 값을 구하기 -> P(S| L∩W) = 0.96


상기는 2개의 feature를 고려한 Bayes theorem val (posterior) 을 구한 것임

베이즈 추정은 기존 prior probability에서 새로운 피처로 posterior 값을 갱신하는 과정

따라서,
Link 기준으로 Bayes Theorem 값을 구하면 P(S|L) = 0.75
Link 기준으로 구한 Bayes Theorem 값 0.75를 prior probability로 설정하고
Word 기준을 추가하여 Bayes Theorem 값을 구하면 P(S| L∩W) 와 같은 0.96 값이 나옴

베이즈정리는 데이터가 적어도 추정이 가능


베이지안 테이블 코드 구현

#️⃣ 기본 코드

def bayesian_table_test():  
    table = pd.DataFrame(index=['Spam', 'Ham'])  
    table['prior'] = 0.5  
  
    # link에 대한 (spam, ham)    table['likelihood'] = 0.6, 0.2  
  
    # joint probability  
    table['unnorm'] = table['prior'] * table['likelihood']  
  
    # normalization constant (분모)  
    norm_const = table['unnorm'].sum()  
  
    # posterior  
    table['posterior'] = table['unnorm'] / norm_const  
  
    print(table)
      prior  likelihood  unnorm  posterior
Spam    0.5         0.6     0.3       0.75
Ham     0.5         0.2     0.1       0.25

#️⃣ 일반화 메서드

def bayesian_table(table: pd.DataFrame, prior: list, likelihood: list) -> pd.DataFrame:  
    # table = pd.DataFrame(index=['Spam', 'Ham'])  
  
    # table['prior'] = 0.5    
    table['prior'] = prior  
  
    # link에 대한 (spam, ham)    
    # table['likelihood'] = 0.6, 0.2    
    table['likelihood'] = likelihood  
  
    # joint probability  
    table['unnorm'] = table['prior'] * table['likelihood']  
  
    # normalization constant (분모)  
    norm_const = table['unnorm'].sum()  
  
    # posterior  
    table['posterior'] = table['unnorm'] / norm_const  
  
    return table
  • 필요한 숫자는 파라미터 인자값으로 받아서 사용할 수 있도록 일반화

#️⃣ 단일 피처 베이지안 테이블

def single_bayes_test():  
    table = pd.DataFrame(index=['Spam', 'Ham'])  
  
    print("link 기준 (단일) bayes table")  
    df = bayesian_table(table=table, prior=0.5, likelihood=[0.6, 0.2])  
    print(df)  
  
    print("word 기준 (단일) bayes table")  
    df2 = bayesian_table(table=table, prior=0.5, likelihood=[0.4, 0.05])  
    print(df2)
link 기준 (단일) bayes table
      prior  likelihood  unnorm  posterior
Spam    0.5         0.6     0.3       0.75
Ham     0.5         0.2     0.1       0.25
word 기준 (단일) bayes table
      prior  likelihood  unnorm  posterior
Spam    0.5        0.40   0.200   0.888889
Ham     0.5        0.05   0.025   0.111111
  • 일반화 메서드를 각각 호출하여 baysian table을 구함

#️⃣ 2개 이상의 피처 베이지안 테이블

def stacked_bayes_test():  
    table = pd.DataFrame(index=['Spam', 'Ham'])  
  
    print("link 기준 (단일) bayes table")  
    df = bayesian_table(table=table, prior=0.5, likelihood=[0.6, 0.2])  
    print(df)  
  
    # set posterior prob to new prior prob  
    prior_series = df['posterior']  
    print("word 추가 반영한 bayes table")  
    df2 = bayesian_table(table=df, prior=prior_series, likelihood=[0.4, 0.05])  
    print(df2)
link 기준 (단일) bayes table
      prior  likelihood  unnorm  posterior
Spam    0.5         0.6     0.3       0.75
Ham     0.5         0.2     0.1       0.25
word 추가 반영한 bayes table
      prior  likelihood  unnorm  posterior
Spam   0.75        0.40  0.3000       0.96
Ham    0.25        0.05  0.0125       0.04
  • 최초 basian table 구하는 bayesian_table 메서드를 call 한 후 return 받은 Pandas dataframe을
  • table 파라미터로 재설정하여 baysian_table 메서드를 call 함

Excercise 3. 단지 안의 공 베이지안 추정 (코드 계산)

#️⃣ 문제 설정

  • 눈 앞에 단지가 하나 있는데, 단지 X 혹은 단지 Y라는 사실은 알고 있지만
    겉으로 봐서는 어느 쪽인지 알 수가 없다.
  • 단지 X에는 흰 공 아홉개와 검은 공 한개 (흰9, 검1)
  • 단지 Y에는 흰 공 두 개와 검은 공 여덟 개 (흰2, 검8)가 들어 있다는 정보를 가지고 있다.
  • 우리는 앞으로 공을 꺼내서 색깔을 확인한다.
  • 그리고 나오는 색깔을 통해서 눈앞의 단지가 어떤 타입인지 추측해보자.

ex.1) 공을 하나 꺼냈을 때, 검은색이었다.

  • 눈앞의 단지가 X 타입일 확률 = 0.111111
  • 눈앞의 단지가 Y 타입일 확률 = 0.888889
===============Black===============
   prior  likelihood  unnorm  posterior
X    0.5         0.1    0.05   0.111111
Y    0.5         0.8    0.40   0.888889

ex.2) 공을 하나 꺼냈을 때, 흰색이었다.

  • 눈앞의 단지가 X 타입일 확률 = 0.818182
  • 눈앞의 단지가 Y 타입일 확률 = 0.181818
===============White===============
   prior  likelihood  unnorm  posterior
X    0.5         0.9    0.45   0.818182
Y    0.5         0.2    0.10   0.181818

ex.3) 공을 두 번 뽑았을 때, B B였다.

  • 눈앞의 단지가 X 타입일 확률 = 0.015385
  • 눈앞의 단지가 Y 타입일 확률 = 0.984615
===============B & B===============
   prior  likelihood  unnorm  posterior
X    0.5         0.1    0.05   0.111111
Y    0.5         0.8    0.40   0.888889
------1st update_black------
      prior  likelihood    unnorm  posterior
X  0.111111         0.1  0.011111   0.015385
Y  0.888889         0.8  0.711111   0.984615
------2nd update_black------

ex.4) 공을 두 번 뽑았을 때, B W였다.

  • 눈앞의 단지가 X 타입일 확률 = 0.36
  • 눈앞의 단지가 Y 타입일 확률 = 0.64
===============B & W===============
   prior  likelihood  unnorm  posterior
X    0.5         0.1    0.05   0.111111
Y    0.5         0.8    0.40   0.888889
------1st update_black------
      prior  likelihood    unnorm  posterior
X  0.111111         0.9  0.100000       0.36
Y  0.888889         0.2  0.177778       0.64

#️⃣ full code

def bayesian_table(table: pd.DataFrame, prior: list, likelihood: list) -> pd.DataFrame:  
    # table = pd.DataFrame(index=['Spam', 'Ham'])  
  
    # table['prior'] = 0.5    if 'posterior' in table.columns:  
        table['prior'] = table['posterior']  
  
    else:  
        table['prior'] = prior  
  
    # link에 대한 (spam, ham)    # table['likelihood'] = 0.6, 0.2    table['likelihood'] = likelihood  
  
    # joint probability  
    table['unnorm'] = table['prior'] * table['likelihood']  
  
    # normalization constant (분모)  
    norm_const = table['unnorm'].sum()  
  
    # posterior  
    table['posterior'] = table['unnorm'] / norm_const  
  
    return table

def balls_in_boxes_test():  
    print("="*15+"Black"+"="*15)  
    likelihood_black = [0.1, 0.8]  
    table = pd.DataFrame(index=['X', 'Y'])  
    df = bayesian_table(table=table, prior=0.5, likelihood=likelihood_black)  
    print(df)  
  
    print("=" * 15 + "White" + "=" * 15)  
    likelihood_white = [0.9, 0.2]  
    table = pd.DataFrame(index=['X', 'Y'])  
    df2 = bayesian_table(table=table, prior=0.5, likelihood=likelihood_white)  
    print(df2)  
  
    print("=" * 15 + "B & B" + "=" * 15)  
    likelihood_black = [0.1, 0.8]  
    table = pd.DataFrame(index=['X', 'Y'])  
    table = bayesian_table(table=table, prior=0.5, likelihood=likelihood_black)  
    print(table)  
    print("------1st update_black------")  
    table = bayesian_table(table=table, prior=0.5, likelihood=likelihood_black)  
    print(table)  
    print("------2nd update_black------")  
  
    print("=" * 15 + "B & W" + "=" * 15)  
    likelihood_black = [0.1, 0.8]  
    table = pd.DataFrame(index=['X', 'Y'])  
    table = bayesian_table(table=table, prior=0.5, likelihood=likelihood_black)  
    print(table)  
    print("------1st update_black------")  
    likelihood_white = [0.9, 0.2]  
    table = bayesian_table(table=table, prior=0.5, likelihood=likelihood_white)  
    print(table)

if __name__ == '__main__':  
	balls_in_boxes_test()

Excercise 4. 단지 안의 공 베이지안 추정 (코드 계산)

#️⃣ 문제 설정

PlayTennis 데이터를 이용하여

  1. prior
  2. likelihood
  3. 모든 경우의 수의 posterior 확인할 수 있는  posterior table을 구하세요.
Outlook Temperature Humidity Wind Play Tennis
Sunny Hot High Weak No
Sunny Hot High Strong No
Overcast Hot High Weak Yes
Rain Mild High Weak Yes
Rain Cool Normal Weak Yes
Rain Cool Normal Strong No
Overcast Cool Normal Strong Yes
Sunny Mild High Weak No
Sunny Cool Normal Weak Yes
Rain Mild Normal Weak Yes
Sunny Mild Normal Strong Yes
Overcast Mild High Strong Yes
Overcast Hot Normal Weak Yes
Rain Mild High Strong No
반응형