Naive Bayes में लॉग-सम-एक्सप ट्रिक कैसे काम करती है, इसका उदाहरण


14

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

इस चाल का उपयोग करके संख्यात्मक अंडरफ़्लो की समस्या से वास्तव में कैसे बचा जा सकता है?


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

ओवरफ्लो की तुलना में समस्या कम होने की संभावना है।
हेनरी

मेरा सुझाव है कि आप अंडरफ़्लो पर एक खोज का प्रयास करें , और फिर अपने प्रश्न को अधिक विशेष रूप से पते पर अपडेट करें जो पहले से ही कवर नहीं है।
Glen_b -Reinstate मोनिका

क्या आप यह भी स्पष्ट कर सकते हैं - यह बर्नोली-मॉडल भोला बेयस है? शायद कुछ और?
Glen_b -Reinstate Monica

यहां उदाहरण देखें , दाईं ओर नीचे ('इससे ​​पहले भी देखें' जहां वे लॉग लेते हैं; दोनों पक्षों को घातांक करते हुए लेकिन आरएचएस को "जैसा है" छोड़कर (लॉग के योग के रूप में) लॉग का एक उदाहरण होगा -सुम-एक्सप ट्रिक। क्या इससे आपको और अधिक विशिष्ट प्रश्न पूछने के लिए
नाइव बेज़

जवाबों:


26

में

p(Y=C|x)=p(x|Y=C)p(Y=C) k=1|C|p(x|Y=Ck)p(Y=Ck)

दोनों भाजक और अंश बहुत छोटे हो सकते हैं, आमतौर पर क्योंकि 0 के करीब हो सकता है और हम उनमें से कई को एक दूसरे के साथ गुणा करते हैं। अंडरफ्लो को रोकने के लिए, व्यक्ति केवल अंश के लॉग को ले सकता है, लेकिन हर को भाजक के लिए लॉग-सम-एक्सप-ट्रिक का उपयोग करने की आवश्यकता होती है।p(xi|Ck)


अधिक विशेष रूप से, ताकि अंडरफ्लो को रोका जा सके:

  • यदि हम केवल यह जानने की परवाह करते हैं कि कौन सी कक्षा इनपुट सबसे अधिक संभावना एक पोस्टीरियर (एमएपी) निर्णय नियम के साथ है, तो हम नहीं करते हैं लॉग-सम-एक्सप-ट्रिक लागू करना होगा, क्योंकि हमें उस मामले में हर की गणना नहीं करनी है । अंश के लिए कोई केवल अंडरफ्लो को रोकने के लिए लॉग ले सकता है: । अधिक विशेष रूप से:( एक्स = एक्स 1 , ... , एक्स एन ) एल जी ( पी ( एक्स | Y = सी ) पी ( Y = सी ) )(y^)(x=x1,,xn)log(p(x|Y=C)p(Y=C))

    y^=argmaxk{1,,|C|}p(Ck|x1,,xn)=argmaxk{1,,|C|} p(Ck)i=1np(xi|Ck)

    जो लॉग लेने के बाद बन जाता है:

y^=argmaxk{1,,|C|}log(p(Ck|x1,,xn))=argmaxk{1,,|C|}log( p(Ck)i=1np(xi|Ck))=argmaxk{1,,|C|}(log(p(Ck))+ i=1nlog(p(xi|Ck)))
  • यदि हम वर्ग संभाव्यता गणना करना चाहते हैं , तो हमें हर को गणना करने की आवश्यकता होगी:p(Y=C|x)

    log(p(Y=C|x))=log(p(x|Y=C)p(Y=C) k=1|C|p(x|Y=Ck)p(Y=Ck))=log(p(x|Y=C)p(Y=C)numerator)log( k=1|C|p(x|Y=Ck)p(Y=Ck)denominator)

    तत्व अंडरफ्लो हो सकता है: बहुत छोटा हो सकता है: यह एक ही समस्या है जैसे कि अंश में, लेकिन इस बार हमारे पास लघुगणक के अंदर एक योग है, जो हमें को बदलने से रोकता है जो करीब हो सकता है 0) in (नकारात्मक और 0 के करीब नहीं, क्योंकि )। इस समस्या को दरकिनार करने के लिए, हम इस तथ्य का उपयोग कर सकते हैं कि को प्राप्त करने के लिए:log( k=1|C|p(x|Y=Ck)p(Y=Ck))p(xi|Ck)p(xi|Ck)log(p(xi|Ck))0p(xi|Ck)1p(xi|Ck)=exp(log(p(xi|Ck)))

    log( k=1|C|p(x|Y=Ck)p(Y=Ck))=log( k=1|C|exp(log(p(x|Y=Ck)p(Y=Ck))))

    उस बिंदु पर, एक नया मुद्दा उठता है: काफी नकारात्मक हो सकता है, जिसका अर्थ है कि 0 के बहुत करीब हो सकता है, अर्थात अंडरफ्लो हो सकता है। यह वह जगह है जहाँ हम लॉग-सम-एक्सप-ट्रिक का उपयोग करते हैं :log(p(x|Y=Ck)p(Y=Ck))exp(log(p(x|Y=Ck)p(Y=Ck)))

    logkeak=logkeakeAA=A+logkeakA

    साथ में:

    • ak=log(p(x|Y=Ck)p(Y=Ck)) ,
    • A=maxk{1,,|C|}ak.

    हम देख सकते हैं कि वेरिएबल अवॉइड करने वाले वेरिएबल को पेश करता है । जैसे , हमारे पास है:Ak=2,a1=245,a2=255

    • exp(a1)=exp(245)=3.96143×10107
    • exp(a2)=exp(255)=1.798486×10111

    लॉग-सम-एक्सप-ट्रिक का उपयोग करके हम अंडरफ्लो से बचते हैं, : A=max(245,255)=245logkeak=logkeakeAA=A+logkeakA=245+logkeak+245=245+log(e245+245+e255+245)=245+log(e0+e10)

    हमने बाद से अंडरफ्लो को टाला, यह 0 से या से बहुत दूर है ।e103.96143×101071.798486×10111


2

मान लें कि हम यह पहचानना चाहते हैं कि दो डेटाबेसों में से कौन सा वाक्यांश उत्पन्न होने की अधिक संभावना है (उदाहरण के लिए, कौन सा उपन्यास इस वाक्यांश से आने की संभावना है)। हम डेटाबेस (Naive Bayes धारणा) पर सशर्त शब्दों की स्वतंत्रता मान सकते हैं।

अब आपके द्वारा पोस्ट की गई दूसरी लिंक को देखें। वहाँ वाक्य एक डेटाबेस और दिए गए अवलोकन के संयुक्त संभाव्यता का प्रतिनिधित्व करते हैं रों वाक्य में शब्दों में से प्रत्येक को देख की संभावना का प्रतिनिधित्व करते हैं।aebt


1

हम इस जवाब से देख सकते हैं कि पायथन में सबसे छोटी संख्या (उदाहरण के लिए इसे लें) IEEE754 के5e-324 कारण है , और हार्डवेयर कारण अन्य भाषाओं पर भी लागू होता है।

In [2]: np.nextafter(0, 1)
Out[2]: 5e-324

और इससे छोटा कोई भी फ्लोट 0 की ओर ले जाएगा।

In [3]: np.nextafter(0, 1)/2
Out[3]: 0.0

और with discrete features and two classesआप के रूप में आवश्यक है बेवे के कार्य को देखते हैं :

p(S=1|w1,...wn)=p(S=1)i=1np(wi|S=1) s={0,1}p(S=s)i=1np(wi|S=s)

मुझे एक सरल एनएलपी टास्क के द्वारा उस फंक्शन को तुरंत करने दें।

हम यह पता लगाने का निर्णय लेते हैं कि क्या आने वाला ईमेल स्पैम है ( ) या स्पैम नहीं है ( ) और हमारे पास शब्द का आकार 5,000 ( ) है और केवल एक शब्द ( ) होने पर चिंता होती है ( ईमेल में या नहीं ( ) सादगी के लिए ( बर्नोली भोली बेयस )।S=1S=0n=5,000wip(wi|S=1)1p(wi|S=1)

In [1]: import numpy as np
In [2]: from sklearn.naive_bayes import BernoulliNB
# let's train our model with 200 samples
In [3]: X = np.random.randint(2, size=(200, 5000))
In [4]: y = np.random.randint(2, size=(200, 1)).ravel()
In [5]: clf = BernoulliNB()
In [6]: model = clf.fit(X, y)

हम देख सकते हैं कि संभाव्यता के कारण बहुत छोटा होगा (दोनों और में 0 और 1) के बीच होगा , और इसलिए हमें यकीन है कि उत्पाद से छोटा होगा और हमें सिर्फ मिलता है ।p(S=s)i=1np(wi|S=s)p(wi|S=1)1p(wi|S=1)i50005e3240/0

In [7]: (np.nextafter(0, 1)*2) / (np.nextafter(0, 1)*2)
Out[7]: 1.0

In [8]: (np.nextafter(0, 1)/2) / (np.nextafter(0, 1)/2)
/home/lerner/anaconda3/bin/ipython3:1: RuntimeWarning: invalid value encountered in double_scalars
  #!/home/lerner/anaconda3/bin/python
Out[8]: nan
In [9]: l_cpt = model.feature_log_prob_
In [10]: x = np.random.randint(2, size=(1, 5000))
In [11]: cls_lp = model.class_log_prior_
In [12]: probs = np.where(x, np.exp(l_cpt[1]), 1-np.exp(l_cpt[1]))
In [13]: np.exp(cls_lp[1]) * np.prod(probs)
Out[14]: 0.0

तब समस्या उत्पन्न होती है: हम ईमेल की संभावना की गणना कैसे कर सकते हैं एक स्पैम ? या हम अंश और हर की गणना कैसे कर सकते हैं?p(S=1|w1,...wn)

हम स्कीलर्न में आधिकारिक कार्यान्वयन देख सकते हैं :

jll = self._joint_log_likelihood(X)
# normalize by P(x) = P(f_1, ..., f_n)
log_prob_x = logsumexp(jll, axis=1)
return jll - np.atleast_2d(log_prob_x).T

अंश के लिए यह संभाव्यता के उत्पाद को लॉग लाइबिलिटी के योग में बदल देता है और हर के लिए यह स्काइप में लॉगसमैक्स का उपयोग करता है जो है:

out = log(sum(exp(a - a_max), axis=0))
out += a_max

क्योंकि हम इसकी संयुक्त लॉग संभावना को जोड़कर दो संयुक्त संभावनाओं को नहीं जोड़ सकते हैं, और हमें लॉग स्पेस से प्रायिकता स्थान पर बाहर जाना चाहिए। लेकिन हम दो सच्ची संभावनाओं को नहीं जोड़ सकते क्योंकि वे बहुत छोटे हैं और हमें उन्हें स्केल करना चाहिए और इसके अलावा करना चाहिए: और परिणाम वापस डालें लॉग स्पेस में फिर इसे फिर से : लॉग स्पेस में जोड़कर ।s={0,1}ejllsmax_jlllogs={0,1}ejllsmax_jllmax_jll+logs={0,1}ejllsmax_jllmax_jll

और यहाँ व्युत्पत्ति है:

logs={0,1}ejlls=logs={0,1}ejllsemax_jllmax_jll=logemax_jll+logs={0,1}ejllsmax_jll=max_jll+logs={0,1}ejllsmax_jll

जहां है कोड में।max_jlla_max

एक बार जब हम अंश और हर दोनों को लॉग स्पेस में प्राप्त करते हैं, तो हम अंश से हर को घटाकर लॉग सशर्त प्रायिकता ( ) प्राप्त कर सकते हैं : logp(S=1|w1,...wn)

return jll - np.atleast_2d(log_prob_x).T

उम्मीद है की वो मदद करदे।

संदर्भ:
1. बर्नौली नैवे बेस क्लासिफायर
2. नैवे बेस के साथ स्पैम फिल्टरिंग - कौन सा बेव बेयर्स?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.