पायथन में केएल डाइवर्जेंस की गणना


22

मैं इसके लिए नया हूँ और यह नहीं कह सकता कि मुझे इसके पीछे सैद्धांतिक अवधारणाओं की पूरी समझ है। मैं पायथन में कई सूचियों के बीच केएल डाइवर्जेंस की गणना करने की कोशिश कर रहा हूं। मैं यह प्रयास करने और करने के लिए http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html का उपयोग कर रहा हूं । जो समस्या मैं चला रहा हूं, वह यह है कि लौटाया गया मान किसी भी 2 संख्याओं की सूची के लिए समान है (इसका 1.386294361119890990)। मुझे लगता है कि मैं यहाँ किसी प्रकार की सैद्धांतिक गलती कर रहा हूँ, लेकिन इसे हाजिर नहीं कर सकता।

values1 = [1.346112,1.337432,1.246655]
values2 = [1.033836,1.082015,1.117323]
metrics.mutual_info_score(values1,values2)

यह एक उदाहरण है जो मैं चला रहा हूं - बस यही कि मैं किसी भी 2 इनपुट के लिए एक ही आउटपुट प्राप्त कर रहा हूं। किसी भी सलाह / मदद की सराहना की जाएगी!


केएल द्वारा, क्या आपका मतलब कुल्लबैक-लिबलर विचलन है?
Dawny33

हाँ, बिलकुल!
नंद

दौड़ने sklearn.metrics.mutual_info_score([1.346112,1.337432,1.246655], [1.033836,1.082015,1.117323])से मुझे मूल्य मिलता है 1.0986122886681096
Dawny33

क्षमा करें, मैं मानों 1 का उपयोग [1, 1.346112,1.337432,1.246655] और मान 2 के रूप में मानों [1,1.033836,1.082015,1.117323] के रूप में कर रहा था और इसलिए अंतर मूल्य।
नंद

जवाबों:


18

सबसे पहले, क्लस्टरिंग परिणामों के मूल्यांकन के लिए पारस्परिक जानकारी को sklearn.metrics.mutual_info_scoreलागू करता है , न कि शुद्ध कुल्बैक-लीब्लर डाइवर्जेंस!

यह मार्जिन के उत्पाद वितरण के साथ संयुक्त वितरण के कुल्बैक-लीब्लर विचलन के बराबर है।

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

यह भी ध्यान दें कि बेस 2 लॉगरिदम का उपयोग करना आम है। यह केवल अंतर में एक निरंतर स्केलिंग कारक पैदा करता है, लेकिन आधार 2 लघुगणक व्याख्या करने के लिए आसान होते हैं और अधिक सहज पैमाने होते हैं (0 से log2 = 0.69314 के बजाय 0 से 1 ..., नट्स के बजाय बिट्स में जानकारी को मापते हुए)।

> sklearn.metrics.mutual_info_score([0,1],[1,0])
0.69314718055994529

जैसा कि हम स्पष्ट रूप से देख सकते हैं, स्केलेर का एमआई परिणाम log2 के बजाय प्राकृतिक लघुगणक का उपयोग करके बढ़ाया जाता है। यह एक दुर्भाग्यपूर्ण विकल्प है, जैसा कि ऊपर बताया गया है।

Kullback-Leibler विचलन नाजुक है, दुर्भाग्य से। उपरोक्त उदाहरण पर यह अच्छी तरह से परिभाषित नहीं है: KL([0,1],[1,0])शून्य से एक विभाजन का कारण बनता है, और अनंत को जाता है। यह असममित भी है


ध्यान दें कि जब scipy.stats.entropyउपयोग किया जाता है, तो यह संभावनाओं को सामान्य कर देगा। डॉक्स ( scipy.github.io/devdocs/generated/scipy.stats.entropy.html ) से: "यह दिनचर्या pk और qk को सामान्य कर देगा यदि वे 1. का योग नहीं करते हैं।"
इटाराम मुश्किन

15

अगर दो वैक्टर p और q को खिलाया जाए तो स्कैपी का एन्ट्रापी फंक्शन KL डायवर्जन की गणना करेगा, प्रत्येक एक संभाव्यता वितरण का प्रतिनिधित्व करता है। यदि दो वैक्टर pdfs नहीं हैं, तो यह पहले सामान्य हो जाएगा।

आपसी जानकारी से संबंधित है, लेकिन केएल डायवर्जेंस के समान नहीं है

"यह भारित आपसी जानकारी भारित KL-Divergence का एक रूप है, जिसे कुछ इनपुटों के लिए नकारात्मक मान लेने के लिए जाना जाता है, और ऐसे उदाहरण हैं जहां भारित पारस्परिक जानकारी नकारात्मक मान भी लेती है"


6

मैं ScikitLearn के कार्यान्वयन के साथ निश्चित नहीं हूं, लेकिन यहां Python में KL विचलन का त्वरित कार्यान्वयन है:

import numpy as np

def KL(a, b):
    a = np.asarray(a, dtype=np.float)
    b = np.asarray(b, dtype=np.float)

    return np.sum(np.where(a != 0, a * np.log(a / b), 0))


values1 = [1.346112,1.337432,1.246655]
values2 = [1.033836,1.082015,1.117323]

print KL(values1, values2)

आउटपुट: 0.775279624079

कुछ पुस्तकालयों में कार्यान्वयन का संघर्ष हो सकता है , इसलिए उपयोग करने से पहले सुनिश्चित करें कि आपने उनके डॉक्स पढ़े हैं।


1
मैंने यह भी करने की कोशिश की लेकिन यह नकारात्मक मान लौटा रहा है, जो मुझे लगता है कि एक वैध मूल्य नहीं है। अनुसंधान का थोड़ा सा तो मुझे इस परिणाम के लिए गया है mathoverflow.net/questions/43849/… जो इनपुट की संभावना वितरण होने के तरीके के बारे में बात करता है। लगता है कि जहाँ मैं अपनी गलती है।
नंद

@ नंदा लिंक के लिए धन्यवाद। 0.775279624079आपके इनपुट के लिए खान रिटर्न और स्केलेर मेट्रिक्स रिटर्न 1.3862943611198906। अभी भी उलझन में है! लेकिन, स्क्रिप्ट में, qn के अनुसार उन मूल्य के चेक सहित करना चाहिए :) की तरह लगता है
Dawny33

1
मैं जानता हूँ कि आपका मतलब क्या है! मैंने 3 अलग-अलग फ़ंक्शंस की कोशिश की है कि उनके बीच केवल एक ही चीज़ के साथ 3 अलग-अलग मूल्य प्राप्त किए जा रहे हैं, जिसके परिणामस्वरूप परिणाम "सही" महसूस नहीं हुआ। इनपुट मान निश्चित रूप से एक तार्किक त्रुटि है जिससे मेरा दृष्टिकोण पूरी तरह से बदल गया है!
नंद

@Nanda आह, कि अब स्पष्ट है :) समझा के लिए धन्यवाद
Dawny33

2

यह चाल सशर्त कोड से बचती है और इसलिए बेहतर प्रदर्शन प्रदान कर सकती है।

import numpy as np

def KL(P,Q):
""" Epsilon is used here to avoid conditional code for
checking that neither P nor Q is equal to 0. """
     epsilon = 0.00001

     # You may want to instead make copies to avoid changing the np arrays.
     P = P+epsilon
     Q = Q+epsilon

     divergence = np.sum(P*np.log(P/Q))
     return divergence

# Should be normalized though
values1 = np.asarray([1.346112,1.337432,1.246655])
values2 = np.asarray([1.033836,1.082015,1.117323])

# Note slight difference in the final result compared to Dawny33
print KL(values1, values2) # 0.775278939433

अच्छी चाल! मुझे यह देखने में रुचि होगी कि यह एक समय बेंचमार्क पर अन्य समाधान के साथ तुलना कैसे करता है।
निश्चित रूप से

0

एक वितरण (ओं) से निम्नलिखित तीन नमूनों पर विचार करें।

values1 = np.asarray([1.3,1.3,1.2])
values2 = np.asarray([1.0,1.1,1.1])
values3 = np.array([1.8,0.7,1.7])

स्पष्ट रूप से, मान 1 और मान 2 करीब हैं, इसलिए हम मान 3 की surpriseतुलना में कम या अधिक होने की उम्मीद करते हैं ।

from scipy.stats import entropy
print("\nIndividual Entropy\n")
print(entropy(values1))
print(entropy(values2))
print(entropy(values3))

print("\nPairwise Kullback Leibler divergence\n")
print(entropy(values1, qk=values2))
print(entropy(values1, qk=values3))
print(entropy(values2, qk=values3))

हम निम्नलिखित आउटपुट देखते हैं:

Individual Entropy

1.097913446793334
1.0976250611902076
1.0278436769863724 #<--- this one had the lowest, but doesn't mean much.

Pairwise Kullback Leibler divergence

0.002533297351606588
0.09053972625203921 #<-- makes sense
0.09397968199352116 #<-- makes sense

हम देखते हैं कि यह समझ में आता है क्योंकि मान 1 और मान 3 और मान 2 और मान 3 के बीच के मूल्य मान 1 से मानों की तुलना में परिवर्तन में अधिक कठोर हैं। यह केएल-डी और इसके लिए लीवरेज किए जा सकने वाले पैकेज को समझने के लिए मेरी मान्यता है।

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