CoolFace
Apppublic

Wen1201/BayesianPyMc1

sourceHugging Faceupdated 8mo agoView on Hugging Face
0likes
bayesian_llm_assistant.py552 linesDownload Raw Back to root
1import google.generativeai as genai2import json3import re4import graphviz5import io6from PIL import Image7 8class BayesianLLMAssistant:9    """10    貝氏階層模型 LLM 問答助手(支援動態 DAG 生成)11    協助用戶理解貝氏分析結果,並可根據描述生成客製化 DAG 圖12    """13 14    def __init__(self, api_key, session_id, api_provider="Google Gemini"):15        """16        初始化 LLM 助手17        18        Args:19            api_key: API key (Gemini 或 Claude)20            session_id: 唯一的 session 識別碼21            api_provider: API 提供商 ("Google Gemini" 或 "Anthropic Claude")22        """23        self.api_provider = api_provider24        self.session_id = session_id25        self.conversation_history = []26        27        if api_provider == "Google Gemini":28            import google.generativeai as genai29            genai.configure(api_key=api_key)30            self.model = genai.GenerativeModel('gemini-2.0-flash-exp')31            self.client = None32        else:  # Anthropic Claude33            import anthropic34            self.client = anthropic.Anthropic(api_key=api_key)35            self.model_name = "claude-sonnet-4-5-20250929"36            self.model = None37 38        39        # 系統提示詞(加入 DAG 生成能力)40        # 完整修改後的 system_prompt41        # 替換 bayesian_llm_assistant.py 第 40-181 行42 43        self.system_prompt = """You are an expert Bayesian statistician specializing in hierarchical models and meta-analysis, particularly in the context of Pokémon battle statistics.44 45**IMPORTANT - Language Instruction:**46- Always respond in the SAME language as the user's question47- If user asks in Traditional Chinese (繁體中文), respond in Traditional Chinese48- If user asks in English, respond in English49- Maintain language consistency throughout the conversation50 51你是一位精通貝氏階層模型和統合分析的統計專家,特別專注於寶可夢對戰統計分析。52 53Your role is to help users understand Bayesian hierarchical model results analyzing 54win rate comparisons between Fire-type and Water-type Pokémon across different matchup pairs.55你的角色是幫助使用者理解貝氏階層模型分析結果,56了解火系與水系寶可夢在不同配對組合下的勝率比較。57 58**NEW CAPABILITY: DAG Diagram Generation | 新能力:DAG 圖生成**59When users ask you to draw, create, or visualize a DAG (Directed Acyclic Graph) or model structure, you can generate Graphviz DOT code.60當用戶要求你繪製、創建或視覺化 DAG(有向無環圖)或模型結構時,你可以生成 Graphviz DOT 代碼。61 62**How to generate DAG code:**631. Detect requests like: "draw a DAG", "show me the model structure", "visualize the relationships", "畫一個 DAG 圖", "顯示模型結構"642. Generate Graphviz DOT code wrapped in special tags:65   ```graphviz66   digraph G {67       // Your DOT code here68   }69   ```703. The system will automatically render it as an image71 72**IMPORTANT - Font and Label Instructions for DAG:**73- NEVER use Chinese characters in node labels74- Use ONLY English labels, or use English + romanized Chinese75- DO NOT set fontname in the graph76- Example of good labels: "d (overall effect)" or "delta[i] (pair-specific)"77- Example of bad labels: "整體效應" or any Chinese text78 79**重要 - DAG 圖的字型和標籤指示:**80- 絕對不要在節點標籤中使用中文字81- 只使用英文標籤,或使用「英文 + 拼音」82- 不要設定 fontname83- 好的標籤範例:"d (overall effect)" 或 "delta[i] (pair-specific)"84- 不好的標籤範例:"整體效應" 或任何中文85 86**Example DAG code for Bayesian hierarchical model:**87```graphviz88digraph BayesianModel {89    rankdir=TB;90    node [shape=ellipse, style=filled, fillcolor=lightblue];91    92    // Priors93    d [label="d\n(Fire vs Water overall)", fillcolor=lightyellow];94    tau [label="tau\n(precision)", fillcolor=lightyellow];95    sigma [label="sigma = 1/√tau", shape=diamond, fillcolor=lightgray];96    97    // Hierarchy98    d -> delta [label="mean"];99    tau -> delta [label="precision"];100    sigma -> delta [style=dashed];101    102    delta [label="delta[i]\n(pair-specific)", fillcolor=lightgreen];103    mu [label="mu[i]\n(baseline)", fillcolor=lightyellow];104    105    // Likelihood106    delta -> pt [label="effect"];107    mu -> pc;108    mu -> pt;109    110    pc [label="pc[i]\n(Water win rate)", shape=diamond, fillcolor=lightgray];111    pt [label="pt[i]\n(Fire win rate)", shape=diamond, fillcolor=lightgray];112    113    pc -> rc_obs [label="probability"];114    pt -> rt_obs [label="probability"];115    116    rc_obs [label="rc_obs[i]\n(Water wins)", shape=box, fillcolor=lightcoral];117    rt_obs [label="rt_obs[i]\n(Fire wins)", shape=box, fillcolor=lightcoral];118}119```120 121You should:1221. Explain Bayesian concepts in simple, accessible terms1232. Interpret posterior distributions, HDI (Highest Density Interval), and credible intervals1243. Explain hierarchical structure and why it's useful1254. Help users understand heterogeneity (sigma) between different matchup pairs1265. Discuss the practical significance of Fire vs Water type advantages1276. Provide insights about which matchup pairs favor Fire-types the most1287. Suggest team building strategies based on the statistical findings1298. Clarify differences between Bayesian and frequentist approaches1309. Explain MCMC diagnostics (R-hat, ESS) when relevant13110. **Generate custom DAG diagrams based on user descriptions**132 133你應該:1341. 用簡單易懂的方式解釋貝氏概念1352. 詮釋後驗分佈、HDI(最高密度區間)和可信區間1363. 解釋階層結構及其優勢1374. 幫助使用者理解不同配對間的異質性(sigma)1385. 討論火系與水系屬性優劣勢的實際意義1396. 提供哪些配對組合中火系最具優勢的見解1407. 根據統計發現提出組隊策略建議1418. 說明貝氏方法與頻率論方法的差異1429. 適時解釋 MCMC 診斷指標(R-hat、ESS)14310. **根據用戶描述生成客製化 DAG 圖**144 145Key concepts to explain when relevant:146- **Bayesian Hierarchical Model**: Borrows strength across matchup pairs, shrinkage effect147- **Prior & Posterior**: How data updates beliefs148- **HDI (Highest Density Interval)**: 95% most credible values149- **d (overall effect)**: Average log odds ratio of Fire vs Water across all pairs150- **sigma (between-pair variation)**: How much different matchup pairs vary in Fire advantage151- **delta (pair-specific effects)**: Each matchup pair's individual Fire advantage/disadvantage152- **Odds Ratio**: exp(d) - how much more likely Fire-types are to win compared to Water-types153- **MCMC**: Markov Chain Monte Carlo sampling method154- **Convergence**: R-hat < 1.1, good ESS (effective sample size)155- **DAG (Directed Acyclic Graph)**: Visual representation of model structure156 157重要概念解釋(當相關時):158- **貝氏階層模型**:跨配對借用資訊,收縮效應159- **先驗與後驗**:資料如何更新信念160- **HDI(最高密度區間)**:95% 最可信的數值範圍161- **d(整體效應)**:火系相對於水系的平均對數勝算比(跨所有配對)162- **sigma(配對間變異)**:不同配對組合的火系優勢差異程度163- **delta(配對特定效應)**:每組配對的個別火系優勢/劣勢164- **勝算比**:exp(d) - 火系相對於水系獲勝的可能性倍數165- **MCMC**:馬可夫鏈蒙地卡羅抽樣方法166- **收斂性**:R-hat < 1.1,良好的 ESS(有效樣本數)167- **DAG(有向無環圖)**:模型結構的視覺化表示168 169When discussing Pokémon type matchups:170- Connect statistical findings to type advantage mechanics (Water typically beats Fire in core games)171- Explain why Fire vs Water matchups show certain patterns172- Discuss individual matchup variations and their causes (e.g., specific Pokémon abilities, stats)173- Identify which Fire/Water Pokémon pairs show unusual results (Fire winning despite type disadvantage)174- Consider team building and type coverage implications175 176討論寶可夢屬性對抗時:177- 將統計發現連結到屬性相剋機制(水系通常剋火系)178- 解釋火系對水系的對戰模式為何呈現特定趨勢179- 討論個別配對的變異及其可能原因(例如特殊能力、數值差異)180- 識別哪些火/水系配對顯示異常結果(火系儘管屬性不利仍獲勝)181- 考慮組隊和屬性覆蓋的影響182 183Always be clear, educational, and engaging. Use examples when helpful.184Format responses with proper markdown for better readability.185 186請務必清晰、具教育性、引人入勝。適時使用範例說明。使用適當的 Markdown 格式以提升可讀性。"""187    188    def get_response(self, user_message, analysis_results=None):189        """190        獲取 AI 回應(支援 DAG 生成)191        192        Args:193            user_message: 用戶訊息194            analysis_results: 分析結果字典(可選)195            196        Returns:197            tuple: (回應文字, DAG 圖片或 None)198        """199        # 準備上下文資訊200        context = ""201        if analysis_results:202            context = self._prepare_context(analysis_results)203        204        # 添加用戶訊息到歷史205        self.conversation_history.append({206            "role": "user",207            "content": user_message208        })209        210        try:211            # 構建完整的提示詞212            full_prompt = self.system_prompt213            214            if context:215                full_prompt += f"\n\n## Current Analysis Context:\n{context}"216            217            # 構建對話歷史文字218            conversation_text = "\n\n## Conversation History:\n"219            for msg in self.conversation_history[:-1]:220                role = "User" if msg["role"] == "user" else "Assistant"221                conversation_text += f"\n{role}: {msg['content']}\n"222            223            # 組合最終提示詞224            final_prompt = full_prompt + conversation_text + f"\nUser: {user_message}\n\nAssistant:"225            226            227            # 調用對應的 API228            if self.api_provider == "Google Gemini":229                response = self.model.generate_content(230                    final_prompt,231                    generation_config=genai.types.GenerationConfig(232                        temperature=0.7,233                        max_output_tokens=4000,234                    )235                )236                assistant_message = response.text237                238            else:  # Anthropic Claude239                response = self.client.messages.create(240                    model=self.model_name,241                    max_tokens=4000,242                    temperature=0.7,243                    system=self.system_prompt,244                    messages=[245                        {"role": "user", "content": final_prompt}246                    ]247                )248                assistant_message = response.content[0].text            249            250            # 檢查是否包含 Graphviz 代碼251            dag_image = self._extract_and_render_dag(assistant_message)252            253            # 添加助手回應到歷史254            self.conversation_history.append({255                "role": "assistant",256                "content": assistant_message257            })258            259            return assistant_message, dag_image260            261        except Exception as e:262            error_msg = f"❌ Error: {str(e)}\n\nPlease check your API key and try again."263            return error_msg, None264    265 266            267    def _extract_and_render_dag(self, text):268        """269        從文字中提取 Graphviz 代碼並渲染成圖片270        271        Args:272            text: 包含可能的 Graphviz 代碼的文字273            274        Returns:275            PIL Image 或 None276        """277        # 方法 1: 嘗試提取 ```graphviz ... ``` 格式278        pattern1 = r'```graphviz\s*\n(.*?)\n```'279        matches = re.findall(pattern1, text, re.DOTALL)280        281        if matches:282            dot_code = matches[0]283        else:284            # 方法 2: 嘗試提取 digraph ... } 格式(沒有 markdown 包裹)285            #pattern2 = r'(digraph\s+\w+\s*\{.*?\n\})'286            pattern2 = r'(digraph\s+\w+\s*\{.*\})'287            matches = re.findall(pattern2, text, re.DOTALL)288            289            if not matches:290                return None291            292            dot_code = matches[0]293        294        try:295            # 使用 Graphviz 渲染296            graph = graphviz.Source(dot_code)297            png_bytes = graph.pipe(format='png')298            299            # 轉換為 PIL Image300            img = Image.open(io.BytesIO(png_bytes))301            302            return img303            304        except Exception as e:305            print(f"Failed to render DAG: {e}")306            return None           307           308    309    def _prepare_context(self, results):310        """準備分析結果的上下文資訊"""311        312        if not results:313            return "目前尚無分析結果。No analysis results available yet."314        315        overall = results['overall']316        interp = results['interpretation']317        diag = results['diagnostics']318        319        # 找出顯著的配對320        sig_types = [321            results['trial_labels'][i] 322            for i, sig in enumerate(results['by_trial']['delta_significant']) 323            if sig324        ]325        326        context = f"""327## Current Bayesian Hierarchical Model Analysis | 目前的貝氏階層模型分析328 329### Overall Effect | 整體效應330- **d (Log Odds Ratio) | d(對數勝算比)**: 331  - Mean | 平均: {overall['d_mean']:.4f}332  - SD | 標準差: {overall['d_sd']:.4f}333  - 95% HDI: [{overall['d_hdi_low']:.4f}, {overall['d_hdi_high']:.4f}]334 335- **sigma (Between-pair Variation) | sigma(配對間變異)**: 336  - Mean | 平均: {overall['sigma_mean']:.4f}337  - SD | 標準差: {overall['sigma_sd']:.4f}338  - 95% HDI: [{overall['sigma_hdi_low']:.4f}, {overall['sigma_hdi_high']:.4f}]339 340- **Odds Ratio | 勝算比**: 341  - Mean | 平均: {overall['or_mean']:.4f}342  - SD | 標準差: {overall['or_sd']:.4f}343  - 95% HDI: [{overall['or_hdi_low']:.4f}, {overall['or_hdi_high']:.4f}]344 345### Model Diagnostics | 模型診斷346- **R-hat (d)**: {f"{diag['rhat_d']:.4f}" if diag['rhat_d'] is not None else 'N/A'} {'✓' if diag['rhat_d'] and diag['rhat_d'] < 1.1 else '✗'}347- **R-hat (sigma)**: {f"{diag['rhat_sigma']:.4f}" if diag['rhat_sigma'] is not None else 'N/A'} {'✓' if diag['rhat_sigma'] and diag['rhat_sigma'] < 1.1 else '✗'}348- **ESS (d)**: {int(diag['ess_d']) if diag['ess_d'] is not None else 'N/A'}349- **ESS (sigma)**: {int(diag['ess_sigma']) if diag['ess_sigma'] is not None else 'N/A'}350- **Convergence | 收斂狀態**: {'✓ Converged 已收斂' if diag['converged'] else '✗ Not Converged 未收斂'}351 352### Interpretation | 結果解釋353- **Overall Effect | 整體效應**: {interp['overall_effect']}354- **Significance | 顯著性**: {interp['overall_significance']}355- **Effect Size | 效果大小**: {interp['effect_size']}356- **Heterogeneity | 異質性**: {interp['heterogeneity']}357 358### Significant Pairs | 顯著的配對359{len(sig_types)} out of {results['n_trials']} pairs show significant Fire advantage:360{len(sig_types)} 組配對(共 {results['n_trials']} 組)顯示顯著的火系優勢:361{', '.join(sig_types) if sig_types else 'None 無'}362 363### Number of Pairs Analyzed | 分析的配對數量364{results['n_trials']} pairs in total 共 {results['n_trials']} 組配對365 366### Key Finding | 關鍵發現367{368    f"On average, Fire-type Pokémon are {overall['or_mean']:.2f} times more likely to win compared to Water-type (95% HDI: [{overall['or_hdi_low']:.2f}, {overall['or_hdi_high']:.2f}]). 平均而言,火系寶可夢獲勝的可能性是水系的 {overall['or_mean']:.2f} 倍 (95% HDI: [{overall['or_hdi_low']:.2f}, {overall['or_hdi_high']:.2f}])。"369 370    if overall['or_mean'] > 1371    else f"Interestingly, Water-type Pokémon show advantage over Fire-type despite type matchup, with OR = {overall['or_mean']:.2f}. 有趣的是,儘管屬性相剋,水系寶可夢相對火系仍顯示優勢,OR = {overall['or_mean']:.2f}。"372}373 374The variation between matchup pairs (sigma = {overall['sigma_mean']:.3f}) indicates {interp['heterogeneity'].lower()}.375配對間的變異(sigma = {overall['sigma_mean']:.3f})表示{interp['heterogeneity'].lower()}。376"""377        return context378    379    def draw_custom_dag(self, description):380        """381        根據用戶描述生成客製化 DAG 圖382        383        Args:384            description: 用戶對 DAG 的描述385            386        Returns:387            tuple: (解釋文字, DAG 圖片或 None)388        """389        prompt = f"""Based on the following description, generate a Graphviz DOT code for a DAG diagram:390 391User description: {description}392 393Please:3941. Create a clear and informative DAG3952. Use appropriate node shapes (ellipse for random variables, box for observed data, diamond for deterministic nodes)3963. Use different colors to distinguish node types3974. **CRITICAL: Use ONLY English labels - NO Chinese characters in node labels**3985. Add labels to explain what each node represents (in English)3996. Wrap your DOT code in ```graphviz ``` tags4007. Provide a brief explanation in Traditional Chinese about what the diagram shows401 402根據以下描述,生成 Graphviz DOT 代碼的 DAG 圖:403 404用戶描述:{description}405 406請:4071. 創建清晰且有資訊性的 DAG4082. 使用適當的節點形狀(橢圓代表隨機變數,矩形代表觀測資料,菱形代表確定性節點)4093. 使用不同顏色區分節點類型4104. **重要:節點標籤必須使用英文,不能使用中文**4115. 添加標籤說明每個節點代表什麼(用英文)4126. 將 DOT 代碼包在 ```graphviz ``` 標籤中4137. 用繁體中文簡要說明圖表顯示什麼"""414        415        return self.get_response(prompt, None)416    417    # 保留原有的所有方法...418    def generate_summary(self, analysis_results):419        """自動生成分析結果總結"""420        421        summary_prompt = """請根據提供的貝氏階層模型分析結果生成一份完整的總結報告,包含:422 4231. **模型目的**:簡述這個階層模型在分析什麼(火系 vs 水系配對比較)4242. **整體發現**:425   - 火系相對於水系的整體勝率優勢如何?426   - d 和勝算比告訴我們什麼?427   - HDI 的意義是什麼?4283. **配對間差異**:429   - sigma 告訴我們什麼?430   - 哪些配對組合中火系特別強勢?哪些則較弱?4314. **模型品質**:432   - 模型收斂得好嗎?(R-hat、ESS)433   - 結果可信嗎?4345. **實戰啟示**:435   - 訓練師如何運用這些資訊?436   - 在火水對抗中,應該選擇哪些特定的寶可夢?437 438請用清楚的繁體中文 Markdown 格式撰寫,包含適當的章節標題。"""439        440        text, _ = self.get_response(summary_prompt, analysis_results)441        return text442    443    def explain_metric(self, metric_name, analysis_results):444        """解釋特定指標"""445        446        metric_explanations = {447            'd': 'd (火系 vs 水系整體對數勝算比)',448            'sigma': 'sigma (配對間變異)',449            'or_speed': 'Odds Ratio (火系對水系勝算比)',450            'hdi': '95% HDI (最高密度區間)',451            'delta': 'delta (配對特定效應)',452            'rhat': 'R-hat (收斂診斷)',453            'ess': 'ESS (有效樣本數)'454        }455        456        metric_display = metric_explanations.get(metric_name, metric_name)457        458        explain_prompt = f"""請在這次貝氏階層模型分析的脈絡下,解釋以下指標:459 460指標:{metric_display}461 462請包含:4631. 這個指標在貝氏統計中測量什麼?4642. 在本次分析中得到的數值是多少?4653. 如何從寶可夢對戰的角度詮釋這個數值?4664. 與頻率論統計的對應指標有何不同?4675. 有什麼需要注意的限制或注意事項?468 469請用繁體中文回答。"""470        471        text, _ = self.get_response(explain_prompt, analysis_results)472        return text473    474    def explain_bayesian_vs_frequentist(self):475        """解釋貝氏與頻率論的差異"""476        477        explain_prompt = """請用簡單的方式解釋貝氏統計和頻率論統計的差異,特別是在寶可夢對戰分析的情境下。478 479請涵蓋:4801. 兩者的根本哲學差異是什麼?4812. p 值 vs HDI(可信區間)有什麼不同?4823. 為什麼我們用階層模型來分析多組配對?4834. 貝氏方法的優勢和限制是什麼?4845. 什麼時候該用貝氏、什麼時候該用頻率論?485 486請用寶可夢的實際例子讓說明更具體易懂,全程使用繁體中文。"""487        488        text, _ = self.get_response(explain_prompt, None)489        return text490    491    def explain_hierarchical_model(self):492        """解釋階層模型的概念"""493        494        explain_prompt = """請用簡單的方式解釋貝氏階層模型,特別是在火系對水系配對分析的情境下。495 496請涵蓋:4971. 什麼是階層模型?為什麼要用階層結構?4982. 「借用資訊」(borrowing strength) 是什麼意思?499   - 在本分析中,如何跨 46 組配對借用資訊?5003. 收縮效應 (shrinkage) 如何運作?501   - 為什麼某些極端的配對結果會被「拉回」?5024. 為什麼階層模型適合分析多組配對?5035. d(整體火系優勢)、sigma(配對間變異)、delta(各配對特定效應)之間的關係是什麼?504 505請用火系對水系的實際配對例子讓說明更具體易懂,全程使用繁體中文。"""506        507        text, _ = self.get_response(explain_prompt, None)508        return text509    510    def battle_strategy_advice(self, analysis_results):511        """提供對戰策略建議"""512        513        strategy_prompt = """根據貝氏階層模型的分析結果,請為寶可夢訓練師提供實際的組隊策略建議。514 515請考慮:5161. 整體而言,火系對水系的勝率如何?5172. 哪些火系寶可夢在對抗水系時特別強?(對應 delta 顯著為正的配對)5183. 是否有火系寶可夢即使對抗水系仍表現不佳?(delta 顯著為負)5194. 訓練師在選擇火系對抗水系時應該注意什麼?5205. 對競技對戰的組隊和屬性覆蓋有什麼啟示?5216. 有沒有出乎意料的發現?(例如某些火系特別強/弱)522 523請具體且可操作,使用繁體中文回答。"""524        525        text, _ = self.get_response(strategy_prompt, analysis_results)526        return text527    528    def compare_types(self, analysis_results):529        """比較不同配對"""530        531        compare_prompt = """請比較分析結果中不同配對組合的火系優勢差異。532 533請說明:5341. 哪些配對中火系特別強勢?可能的原因是什麼?535   - 考慮:特殊能力、數值優勢、招式組合5362. 哪些配對中火系反而處於劣勢?為什麼?5373. 配對間的異質性(sigma)告訴我們什麼?538   - 是否某些火/水系寶可夢特別能打破屬性相剋?5394. 有沒有令人意外的發現?540   - 例如:某個火系儘管屬性不利仍大幅獲勝541   - 或某個火系表現比預期差很多5425. 這些差異對組隊策略有什麼啟示?543   - 如何針對性地選擇火系來對抗水系?544 545請用繁體中文回答。"""546        547        text, _ = self.get_response(compare_prompt, analysis_results)548        return text549    550    def reset_conversation(self):551        """重置對話歷史"""552        self.conversation_history = []