資料專區
貝氏機器學習-上午
程式碼 一、
#下載 gdown 套件
!pip install gdown
# 匯入需要用到的 Python 套件
import gdown
import pandas as pd
# 從 Google Drive 下載 CSV 檔
# 用 gdown 需要提供檔案 ID,或用 --fuzzy 讓它自動判斷
url = "https://drive.google.com/file/d/1n60X99FfZ12DIVpdwVrmmMjTUpyzO3Qq/view?usp=sharing"
filename = "pokemon_Bug.csv" #把檔名存成一個變數
# --fuzzy 可以讓 gdown 自動從分享連結抓到正確下載網址
gdown.download(url, filename , fuzzy=True)
# 用 pandas 讀取剛剛下載的 CSV 檔
df = pd.read_csv(filename, encoding="utf-8-sig")
# 確認前 30 筆資料
df.head(30)
結果顯示
程式碼 二、
# 2) 分開蟲系 / 非蟲系
bug_df = df[df["屬性"] == "Bug"]
nonbug_df = df[df["屬性"] != "Bug"]
# 印出分組後的資料
print("=== 蟲系資料集 (bug_df) ===")
print(bug_df.head()) # 只顯示前5筆,避免太長
print("\n=== 非蟲系資料集 (nonbug_df) ===")
print(nonbug_df.head()) # 只顯示前5筆
結果顯示
程式碼 三、
# 3) 算勝率
p_win_given_bug = (bug_df["輸贏"] == 1).mean() # 蟲系勝率
p_win_given_nonbug = (nonbug_df["輸贏"] == 1).mean() # 非蟲系勝率
print(f"P(勝利|蟲系) = {p_win_given_bug*100:.2f}%")
print(f"P(勝利|非蟲系) = {p_win_given_nonbug*100:.2f}%")
結果顯示
程式碼 四、
# 4) 固定先驗 (每種屬性等機率 1/18)
p_bug = 1/18
程式碼 五、
# 5) 貝氏翻轉公式
p_bug_given_win = p_bug * p_win_given_bug / (p_bug * p_win_given_bug + (1 - p_bug) * p_win_given_nonbug)
程式碼 六、
# 6) 輸出結果
print("=== 貝氏翻轉:P(蟲系 | 勝利) ===")
print(f"固定 P(蟲系) = {p_bug*100:.2f}%")
print(f"P(勝利|蟲系) = {p_win_given_bug*100:.2f}%")
print(f"P(勝利|非蟲系) = {p_win_given_nonbug*100:.2f}%")
print(f"P(蟲系|勝利) = {p_bug_given_win*100:.2f}%")
結果顯示
貝氏機器學習-下午
程式碼 一、
"""
Step 1:沒有孩子資料時,根據「父親目前未發病」的資訊做第一次貝氏更新
目標:Posterior = P(爸爸是Dd | 爸爸未發病)
"""
# 定義一個函數,名稱為:bayes_prior_no_kids
def bayes_prior_no_kids(p):
prior = 0.5 # Prior : P(爸爸是Dd) 初始假設
like_Dd = 1 - p # Likelihood : P(爸爸未發病 | 爸爸是Dd)
like_dd = 1.0 # Likelihood : P(爸爸未發病 | 爸爸是dd)
# Evidence :
# P(爸爸未發病) = P(爸爸是Dd)*P(爸爸未發病|爸爸是Dd) + (1-P(爸爸是Dd))*P(爸爸未發病|爸爸是dd)
evidence = prior * like_Dd + (1 - prior) * like_dd
# Posterior :
# P(爸爸是Dd | 爸爸未發病) = [P(爸爸是Dd) × P(爸爸未發病|爸爸是Dd)] / P(爸爸未發病)
posterior = (prior * like_Dd) / evidence
return posterior
程式碼 二、
"""
Step 2:計算小新發病機率
目標:Posterior = P(小新發病|爸爸未發病)
"""
# 定義一個函數,名稱為:calc_initial_risk
def calc_initial_risk(p):
# 這是上一步得到的 Posterior [P(爸爸是Dd|爸爸未發病)],作為此步的Prior
prob_father_Dd = bayes_prior_no_kids(p)
# P(小新遺傳到D|爸爸是Dd)
prob_inherit_D = 0.5
# P(小新發病機率)
# p為疾病穿透力=P(小新發病|小新是Dd)
risk = prob_father_Dd * prob_inherit_D * p
# 函數回傳兩個數值
return prob_father_Dd, risk
程式碼 三、
# =========================================
# Step 3:觀察到「已有 n 個健康小孩」後,再做一次貝氏更新
# 目標:Posterior = P(爸爸是Dd|n個健康小孩)
# Step 4:用更新機率計算下一個小孩得病機率
# 目標:Risk = P(下一個小孩發病)
# =========================================
# 定義一個函數,名稱為:calc_updated_risk
def calc_updated_risk(p, n):
# Step 3
prior = 0.5 # Prior:P(爸爸為Dd)
like_Dd =(1-p)* (1 - p/2) ** n # Likelihood:P(有n個小孩健康,爸爸健康|爸爸為Dd)
like_dd = 1.0 # Likelihood:P(有n個小孩健康,爸爸健康|爸爸為dd)
# Evidence:P(有n個小孩健康)
evidence = prior * like_Dd + (1 - prior) * like_dd
# Posterior:P(爸爸為Dd|有n個小孩健康)
posterior = (prior * like_Dd) / evidence
# Step 4
# 下一胎得病機率 = Posterior × P(下一個小孩遺傳到D|爸爸是Dd) × P(下一個小孩發病|下一個小孩是Dd)
risk = posterior * 0.5 * p
return posterior, risk
程式碼 四、
# 輸出結果
# 顯示整體風險分析結果(Bayes 概率計算後的輸出)
# p : 疾病的穿透力(penetrance),0~1 之間 ; n : 已知健康的小孩數量
def show_results(p, n):
print(f"參數:穿透力 p = {p}, 健康小孩數 n = {n}\n")
# A. 初始(僅用「爸爸未發病」作為證據)
prob_father_Dd_init, risk_init = calc_initial_risk(p)
# B. 更新(再加入「n 個孩子皆健康」作為新證據)
prob_father_Dd_updated, risk_updated = calc_updated_risk(p, n)
# --- 列印初始結果 ---
print("► 計算小新發病機率:")
print(f" - Posterior P(父親是Dd | 未發病) = {prob_father_Dd_init*100:.2f}%")
print(f" - P(小新得病) = {risk_init*100:.2f}%")
# --- 列印更新後結果 ---
print(f"\n► 已有 {n} 個健康小孩(加入新證據):")
print(f" - Posterior P(父親是Dd | n 健康) = {prob_father_Dd_updated*100:.2f}%")
print(f" - P(第{n+1}小孩得病) = {risk_updated*100:.2f}%")
程式碼 五、
# === 參數設定 ===
p = 0.6 # 穿透力(0~1)
n = 3 # 已健康小孩數
# === 執行計算 ===
show_results(p, n)
結果顯示