python एक विशिष्ट अनुप्रयोग के लिए बायेसियन नेटवर्क का पायथोनिक कार्यान्वयन




bayesian bayesian-networks (4)

मैं बायेसियन नेटवर्क से परिचित नहीं हूं, इसलिए मुझे उम्मीद है कि निम्नलिखित उपयोगी है:

अतीत में मुझे गेसियन प्रोसेस रजिस्ट्रार के साथ बाइसियन क्लासिफायरियर के बजाय एक समान समस्या थी।

मैंने विरासत का उपयोग करके समाप्त किया, जो अच्छी तरह से काम करता था। सभी मॉडल-विशिष्ट paremeters कंस्ट्रक्टर के साथ सेट किए गए हैं। गणना () फ़ंक्शन आभासी हैं। विभिन्न तरीकों को कैस्केडिंग करना (जैसे एक सम-विधि जो अन्य तरीकों की एक मनमानी संख्या को जोड़ती है) भी अच्छी तरह से काम करती है।

यही कारण है कि मैं यह सवाल पूछ रहा हूं: पिछले साल मैंने एक विशेष प्रकार के मॉडल (बायेसियन नेटवर्क द्वारा वर्णित) के लिए पश्चगामी संभावनाओं की गणना करने के लिए कुछ सी ++ कोड बनाया था। मॉडल ने बहुत अच्छा काम किया और कुछ अन्य लोगों ने मेरे सॉफ़्टवेयर का उपयोग करना शुरू कर दिया। अब मैं अपने मॉडल में सुधार करना चाहता हूं। चूँकि मैं पहले से ही नए मॉडल के लिए थोड़ा अलग इंजेक्शन एल्गोरिदम कोडिंग कर रहा हूं, इसलिए मैंने अजगर का उपयोग करने का फैसला किया क्योंकि रनटाइम गंभीर रूप से महत्वपूर्ण नहीं था और अजगर मुझे और अधिक सुरुचिपूर्ण और प्रबंधनीय कोड बना सकता है।

आमतौर पर इस स्थिति में मैं अजगर में एक मौजूदा बायेसियन नेटवर्क पैकेज की खोज करूंगा, लेकिन मैं जो प्रयोग कर रहा हूं, उसमें इनविटेशन एल्गोरिदम मेरे अपने हैं, और मुझे भी लगा कि यह अजगर में अच्छे डिजाइन के बारे में अधिक जानने का एक शानदार अवसर होगा।

मैंने पहले से ही नेटवर्क ग्राफ़ (नेटवर्कएक्स) के लिए एक शानदार अजगर मॉड्यूल पाया है, जो आपको प्रत्येक नोड और प्रत्येक किनारे पर एक शब्दकोश संलग्न करने की अनुमति देता है। अनिवार्य रूप से, यह मुझे नोड्स और किनारों के गुण देगा।

किसी विशेष नेटवर्क के लिए और यह मनाया गया डेटा है, मुझे एक फ़ंक्शन लिखने की ज़रूरत है जो मॉडल में अनसाइन किए गए चर की संभावना की गणना करता है।

उदाहरण के लिए, क्लासिक "एशिया" नेटवर्क ( http://www.bayesserver.com/Resources/Images/AsiaNetwork.png ) में, "एक्सरे रिजल्ट" और "डायस्पनेया" के राज्यों के साथ, मुझे एक फ़ंक्शन लिखने की आवश्यकता है इस संभावना की गणना करने के लिए कि अन्य चर के कुछ मान हैं (कुछ मॉडल के अनुसार)।

यहां मेरा प्रोग्रामिंग प्रश्न है: मैं मुट्ठी भर मॉडल की कोशिश करने जा रहा हूं, और भविष्य में यह संभव है कि मैं उसके बाद एक और मॉडल की कोशिश करना चाहता हूं। उदाहरण के लिए, एक मॉडल बिल्कुल एशिया नेटवर्क की तरह लग सकता है। एक अन्य मॉडल में, "एश टू एशिया" से "हैज़ लंग कैंसर" के लिए एक निर्देशित धार जोड़ी जा सकती है। एक अन्य मॉडल मूल निर्देशित ग्राफ का उपयोग कर सकता है, लेकिन "डिस्नेना" नोड के लिए संभाव्यता मॉडल को "तपेदिक या कैंसर" और "हैज ब्रोंकाइटिस" नोड अलग-अलग हो सकते हैं। ये सभी मॉडल एक अलग तरीके से संभावना की गणना करेंगे।

सभी मॉडलों में पर्याप्त ओवरलैप होगा; उदाहरण के लिए, "या" नोड में जाने वाले कई किनारे हमेशा "0" बनाएंगे यदि सभी इनपुट "0" और "1" अन्यथा हों। लेकिन कुछ मॉडलों में नोड्स होंगे जो कुछ रेंज में पूर्णांक मानों को लेते हैं, जबकि अन्य बूलियन होंगे।

अतीत में मैंने इस तरह की चीजों को प्रोग्राम करने के लिए संघर्ष किया है। मैं झूठ नहीं बोलने वाला; कॉपी किए गए और पेस्ट किए गए कोड की एक उचित मात्रा है और कभी-कभी मुझे एक ही विधि से कई फ़ाइलों में परिवर्तन का प्रचार करने की आवश्यकता होती है। इस बार मैं वास्तव में इसे सही तरीके से करने के लिए समय बिताना चाहता हूं।

कुछ विकल्प:

  1. मैं पहले से ही यह सही तरीके से कर रहा था। पहले कोड, बाद में प्रश्न पूछें। कोड को कॉपी और पेस्ट करना और प्रत्येक मॉडल के लिए एक वर्ग होना तेज़ है। दुनिया एक अंधेरे और अव्यवस्थित जगह है ...
  2. प्रत्येक मॉडल का अपना वर्ग होता है, लेकिन सामान्य बायेसिएन नेटवर्क्स मॉडल का एक उपवर्ग भी होता है। यह सामान्य मॉडल कुछ कार्यों का उपयोग करेगा जो ओवरराइड होने वाले हैं। गर्व से गर्व होता।
  3. एक ही वर्ग में कई कार्य करें जो विभिन्न संभावना की गणना करते हैं।
  4. एक सामान्य बायेसिएन नेटवर्क्स लाइब्रेरी को कोड करें और इस लाइब्रेरी द्वारा पढ़े गए विशिष्ट ग्राफ़ के रूप में मेरी अनुमान समस्याओं को लागू करें। नोड्स और किनारों को "बूलियन" और "ऑर्फ़ंक्शन" जैसी संपत्तियां दी जानी चाहिए, जो कि मूल नोड के ज्ञात राज्यों को दिए गए हैं, का उपयोग विभिन्न परिणामों की संभावनाओं की गणना करने के लिए किया जा सकता है। इन संपत्ति स्ट्रिंग्स, जैसे "ऑर्फ़ंक्शन" को सही फ़ंक्शन को देखने और कॉल करने के लिए भी इस्तेमाल किया जा सकता है। शायद कुछ वर्षों में मैं 1988 के गणित के संस्करण के समान कुछ बनाऊंगा!

आपकी सहायता के लिए धन्यवाद।

अद्यतन: वस्तु उन्मुख विचार यहां बहुत मदद करते हैं (प्रत्येक नोड में एक निश्चित नोड उपप्रकार के पूर्ववर्ती नोड्स का निर्दिष्ट सेट होता है, और प्रत्येक नोड में एक संभावना फ़ंक्शन होता है, जो पूर्ववर्ती नोड्स के राज्यों को दिए गए विभिन्न परिणाम राज्यों की इसकी संभावना की गणना करता है, आदि)। )। OOP FTW!


मोज़ार्ट / ओज़ 3 बाधाओं पर आधारित आक्रमण प्रणाली एक समान समस्या का हल करती है: आप अपनी समस्या को परिमित डोमेन चर, अवरोधी प्रचारकों और वितरकों, लागत कार्यों के संदर्भ में बताते हैं। जब कोई और अधिक अनुमान संभव नहीं होता है, लेकिन फिर भी अनबाउंड वैरिएबल होते हैं, तो यह अनबाउंड वैरिएबल पर समस्या स्थान को विभाजित करने के लिए आपके लागत कार्यों का उपयोग करता है जो कि सबसे अधिक संभावना खोज लागत को कम करता है: अर्थात, यदि X [a, c] के बीच है तो ऐसा वैरिएबल , और ग (एक <b <c) खोज लागत को कम करने की सबसे अधिक संभावना है, आप दो समस्या उदाहरणों के साथ समाप्त होते हैं जहां एक्स [ए, बी] के बीच है और, दूसरे उदाहरण में, एक्स [बी, सी के बीच है] ]। मोजार्ट ऐसा नहीं बल्कि शान से करता है क्योंकि यह पहली श्रेणी की वस्तु के रूप में चर बंधन को स्वीकार करता है (यह बहुत उपयोगी है, क्योंकि मोजार्ट व्यापक रूप से समवर्ती और वितरित है, एक समस्या नोड को एक अलग नोड में स्थानांतरित करने के लिए)। इसके कार्यान्वयन में, मुझे संदेह है कि यह एक कॉपी-ऑन-राइट रणनीति नियुक्त करता है।

आप एक ग्राफ़-आधारित लाइब्रेरी में कॉपी-ऑन-राइट स्कीम को लागू कर सकते हैं (टिप: कॉपी करने के लिए बहुत सी विभिन्न रणनीतियों का उपयोग करता है; यदि आप इस पर अपने ग्राफ़ का प्रतिनिधित्व करते हैं, तो आपको मुफ्त में कॉपी-ऑन-राइट शब्दार्थ मिल सकता है) अपने लक्ष्य पर पहूंचें।


मैं अपने खाली समय में इस तरह की चीजों पर काफी समय से काम कर रहा हूं। मुझे लगता है कि मैं अभी इसी समस्या के अपने तीसरे या चौथे संस्करण पर हूँ। मैं वास्तव में डायनेमिक बायेसियन मॉडल शामिल और एक अलग दृढ़ता परत के साथ फेथोम (https://github.com/davidrichards/fathom/wiki) का एक और संस्करण जारी करने के लिए तैयार हो रहा हूं।

जैसा कि मैंने अपना उत्तर स्पष्ट करने की कोशिश की है, यह काफी लंबा हो गया है। मैं उसके लिए माफी माँगता हूँ। यहां बताया गया है कि मैं उस समस्या पर हमला कर रहा हूं, जो आपके कुछ सवालों का जवाब देती है (कुछ अप्रत्यक्ष रूप से):

मैंने यहूदिया पर्ल के साथ बायेसियन नेटवर्क में विश्वास के प्रसार के टूटने के साथ शुरू किया है। यही है, यह माता-पिता से आने वाली पूर्व बाधाओं (कारण समर्थन) और बच्चों से आने वाले संभावना (नैदानिक ​​समर्थन) के साथ एक ग्राफ है। इस तरह, बेसिक क्लास सिर्फ एक BeliefNode है, बहुत कुछ जैसा आपने BeliefNodes, एक LinkMatrix के बीच एक अतिरिक्त नोड के साथ वर्णित किया है। इस तरह, मैं स्पष्ट रूप से उस प्रकार का चयन करता हूं जिसका उपयोग मैं लिंमैट्रिक्स के प्रकार के द्वारा कर रहा हूं। यह समझाने में आसान बनाता है कि विश्वास नेटवर्क बाद में क्या कर रहा है और साथ ही गणना को सरल रखता है।

कोई भी उपवर्ग या परिवर्तन जो मैं मूल BeliefNode में करूँगा, निरंतर प्रसार नियमों या नोड संघों को बदलने के बजाय निरंतर चर को कम करने के लिए होगा।

मैंने BeliefNode के अंदर सभी डेटा रखने का फैसला किया है, और केवल LinkedMatrix में निश्चित डेटा। यह सुनिश्चित करने के साथ करना है कि मैं न्यूनतम नेटवर्क गतिविधि के साथ स्वच्छ विश्वास अपडेट बनाए रखता हूं। इसका मतलब यह है कि मेरा BeliefNode स्टोर:

  • बच्चों के संदर्भों की एक सरणी, प्रत्येक बच्चे से आने वाले फ़िल्टर किए गए संभावित कारणों और उस बच्चे के लिए फ़िल्टरिंग करने वाले लिंक मैट्रिक्स के साथ
  • माता-पिता के संदर्भों की एक सरणी, प्रत्येक माता-पिता से आने वाले फ़िल्टर किए गए पूर्व बाधाओं और लिंक मैट्रिक्स के साथ जो उस माता-पिता के लिए फ़िल्टरिंग कर रहा है
  • नोड की संयुक्त संभावना
  • नोड के संयुक्त पूर्व बाधाओं
  • गणना की गई धारणा, या बाद की संभावना
  • विशेषताओं की एक क्रमबद्ध सूची जो सभी पूर्ववर्ती बाधाओं और संभावनाओं का पालन करती है

LinkMatrix का निर्माण नोड्स के बीच संबंधों की प्रकृति के आधार पर कई अलग-अलग एल्गोरिदम के साथ किया जा सकता है। आपके द्वारा बताए जा रहे सभी मॉडल बस अलग-अलग वर्ग होंगे जिन्हें आप नियोजित करेंगे। संभवतः करने के लिए सबसे आसान चीज एक-गेट के लिए डिफ़ॉल्ट है, और फिर नोडमैट्स के बीच एक विशेष संबंध होने पर लिंकमैट्रिक्स को संभालने के लिए अन्य तरीके चुनें।

मैं दृढ़ता और कैशिंग के लिए MongoDB का उपयोग करता हूं। मैं गति और अतुल्यकालिक पहुंच के लिए एक इवेंट मॉडल के अंदर इस डेटा का उपयोग करता हूं। यह नेटवर्क को काफी अच्छा प्रदर्शन करता है, जबकि अगर यह होने की जरूरत है तो बहुत बड़ा होने का अवसर भी देता है। इसके अलावा, चूंकि मैं इस तरह से मैंगो का उपयोग कर रहा हूं, इसलिए मैं समान ज्ञान आधार के लिए एक नया संदर्भ आसानी से बना सकता हूं। इसलिए, उदाहरण के लिए, यदि मेरे पास एक नैदानिक ​​पेड़ है, तो निदान के लिए नैदानिक ​​सहायता में से कुछ रोगी के लक्षणों और परीक्षणों से आएंगे। मैं जो कुछ करता हूं वह उस रोगी के लिए एक संदर्भ बनाता है और फिर उस विशेष रोगी के साक्ष्य के आधार पर मेरी मान्यताओं का प्रचार करता है। इसी तरह, अगर एक डॉक्टर ने कहा कि एक मरीज को दो या अधिक बीमारियों का सामना करने की संभावना थी, तो मैं विश्वास अपडेट को अलग तरीके से प्रचारित करने के लिए अपने कुछ लिंक मैट्रिसेस को बदल सकता था।

यदि आप अपने सिस्टम के लिए मानगो जैसी किसी चीज़ का उपयोग नहीं करना चाहते हैं, लेकिन आप ज्ञान के आधार पर काम करने वाले एक से अधिक उपभोक्ता होने की योजना बना रहे हैं, तो आपको यह सुनिश्चित करने के लिए कि आप नए सिरे से काम कर रहे हैं, किसी प्रकार के कैशिंग सिस्टम को अपनाने की आवश्यकता होगी। - हर समय नोड्स का टूटना।

मेरा काम खुला स्रोत है, इसलिए यदि आप चाहें तो आप इसका अनुसरण कर सकते हैं। यह सब रूबी है, इसलिए यह आपके पायथन के समान होगा, लेकिन जरूरी नहीं कि यह एक ड्रॉप-इन प्रतिस्थापन हो। एक चीज जो मुझे अपने डिजाइन के बारे में पसंद है, वह यह है कि परिणाम की व्याख्या करने के लिए मनुष्यों के लिए आवश्यक सभी जानकारी कोड में नहीं बल्कि स्वयं नोड्स में पाई जा सकती है। यह गुणात्मक विवरण में, या नेटवर्क की संरचना में किया जा सकता है।

तो, यहाँ कुछ महत्वपूर्ण अंतर हैं जो मैंने आपके डिज़ाइन के साथ दिए हैं:

  • मैं वर्ग के अंदर संभावना मॉडल की गणना नहीं करता, बल्कि नोड्स के बीच, लिंक मैट्रिक्स के अंदर। इस तरह, मुझे एक ही वर्ग के अंदर कई संभावना कार्यों के संयोजन की समस्या नहीं है। मेरे पास एक मॉडल बनाम दूसरे की समस्या नहीं है, मैं सिर्फ एक ही ज्ञान के आधार के लिए दो अलग-अलग संदर्भों का उपयोग कर सकता हूं और परिणामों की तुलना कर सकता हूं।
  • मैं मानव निर्णयों को स्पष्ट करके बहुत अधिक पारदर्शिता जोड़ रहा हूं। यानी, अगर मैं दो नोड्स के बीच एक डिफ़ॉल्ट या गेट का उपयोग करने का निर्णय लेता हूं, तो मुझे पता है कि मैंने कब जोड़ा और यह सिर्फ एक डिफ़ॉल्ट निर्णय था। यदि मैं बाद में वापस आता हूं और लिंक मैट्रिक्स को बदल देता हूं और ज्ञान के आधार की फिर से गणना करता हूं, तो मेरे पास एक नोट है कि मैंने ऐसा क्यों किया, न कि केवल एक आवेदन के बजाय जिसने एक विधि को दूसरे पर चुना। आप अपने उपभोक्ताओं को इस तरह की चीज़ों के बारे में जानकारी दे सकते हैं। हालाँकि आप इसका समाधान करते हैं, शायद विश्लेषक से चरण-वार संवाद प्राप्त करना एक अच्छा विचार है कि वे चीजों को दूसरे तरीके से क्यों स्थापित कर रहे हैं।
  • मैं पूर्व बाधाओं और संभावना के बारे में अधिक स्पष्ट हो सकता हूं। मुझे इस पर यकीन नहीं है, मैंने सिर्फ यह देखा है कि आप अपनी संभावना संख्या को बदलने के लिए विभिन्न मॉडलों का उपयोग कर रहे थे। जो मैं कह रहा हूं, उसमें से बहुत कुछ पूरी तरह से अप्रासंगिक हो सकता है अगर आपके मॉडल के पीछे की मान्यताओं को इस तरह से तोड़ना नहीं है। मुझे तीन अतुल्यकालिक चरण बनाने में सक्षम होने का लाभ है जो किसी भी क्रम में कहे जा सकते हैं: नेटवर्क में बदलाव की संभावनाएं पास करें, नेटवर्क से पहले पूर्व में परिवर्तित बदलाव पास करें, और नोड के संयुक्त विश्वास (पीछे की संभावना) की फिर से गणना करें। ।

एक बड़ा चेतावनी: मैं जो बात कर रहा हूं, उसमें से कुछ अभी तक जारी नहीं हुई है। मैंने आज सुबह लगभग 2:00 बजे तक जिस सामान के बारे में बात कर रहा था, उस पर काम किया, इसलिए यह निश्चित रूप से चालू है और निश्चित रूप से मुझे नियमित रूप से ध्यान आ रहा है, लेकिन अभी तक जनता के लिए सभी उपलब्ध नहीं है। चूँकि यह मेरा एक जुनून है, इसलिए यदि आप चाहें तो किसी भी सवाल का जवाब देने या किसी परियोजना पर एक साथ काम करने में मुझे खुशी होगी।


मुझे लगता है कि आपको एक युगल से सवाल पूछने की ज़रूरत है जो डिज़ाइन को प्रभावित करते हैं।

  1. आप कितनी बार मॉडल जोड़ेंगे?
  2. क्या आपके पुस्तकालय के उपभोक्ताओं को नए मॉडल जोड़ने की उम्मीद है?
  3. कितने प्रतिशत उपयोगकर्ता मौजूदा मॉडल का उपयोग कर रहे हैं?

यदि अधिकांश समय मौजूदा मॉडल के साथ बिताया जाएगा और नए मॉडल कम सामान्य होंगे, तो विरासत शायद वह डिजाइन है जिसका मैं उपयोग करूंगा। यह प्रलेखन को संरचना के लिए आसान बनाता है और इसका उपयोग करने वाले कोड को समझना आसान होगा।

यदि लाइब्रेरी का प्रमुख उद्देश्य विभिन्न मॉडलों के साथ प्रयोग करने के लिए एक मंच प्रदान करना है, तो मैं उन गुणों के साथ ग्राफ ले लूंगा जो माता-पिता पर आधारित चीजों की गणना के लिए फंक्शंस के लिए मैपर्स के साथ होते हैं। लाइब्रेरी अधिक जटिल होगी और ग्राफ़ निर्माण अधिक जटिल होगा, लेकिन यह कहीं अधिक शक्तिशाली होगा क्योंकि यह आपको हाइब्रिड ग्राफ़ करने की अनुमति देगा जो नोड्स के आधार पर कम्प्यूटेशन फ़ाइटर को बदल देगा।

चाहे आप किस अंतिम डिजाइन की ओर काम करते हैं, मैं एक साधारण एक वर्ग-एक कार्यान्वयन डिजाइन के साथ शुरू करूंगा। इसे स्वचालित परीक्षणों के एक सेट से गुजारें, फिर उसके बाद अधिक पूर्ण डिजाइन में रिफैक्टर करें। इसके अलावा, संस्करण नियंत्रण को मत भूलना ;-)







bayesian-networks