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

मेरे पास एक नेस्टेड तानाशाही है, जो इस के समान है:

example_dictionary = {'I want to eat peach and egg.':{'apple':3, 'orange':2, 'banana':5},\
                   'Peach juice is so delicious.':{'apple':3, 'orange':5, 'banana':2}, \
'Goddamn monkey ate my banana.':{'rice':4, 'apple':6, 'monkey':2}, \
'They say apple is good for health.':{'grape':10, 'monkey':5, 'peach':5, 'egg':8}}

मैं जो करने की कोशिश कर रहा हूं वह कुछ नियमों का पालन करके एक आसन्न मैट्रिक्स का निर्माण कर रहा है। नियम हैं:

१) यदि किसी भी आंतरिक ताना-बाना में कोई शब्द किसी भी वाक्य (बाहरी तानाशाही की) में मौजूद है, तो संबंधित वाक्यों के बीच शब्द के मूल्य के रूप में एक भार जोड़ें।

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

अतिरिक्त नोट: आंतरिक डिक्ट्स की अलग-अलग लंबाई हो सकती है, एक ही आंतरिक ताना कुंजी (शब्द) में अलग-अलग मान हो सकते हैं। मैं चाहता हूं कि उन्हें केवल इस मामले में गुणा किया जाए, यदि उनके समान मूल्य हैं जिन्हें मैं ध्यान में नहीं रखना चाहता हूं।

उदाहरण:

Sentence1(0): I want to eat peach and egg. {'apple':3, 'orange':2, 'banana':5}

Sentence2(1): Peach juice is so delicious. {'apple':3, 'orange':5, 'banana':2}

Sentence3(2): Goddamn monkey ate my banana.{'rice':4, 'apple':6, 'monkey':2}

Sentence4(3): They say apple is good for health. {'grape':10, 'monkey':5, 'peach':5, 'egg':8}

0 और 1: 5*2+5*2=20 के बीच (क्योंकि, उनके सेब का एक ही मान होता है, बस नारंगी और केले के मानों को गुणा किया जाता है। और किसी भी वाक्य में कोई भी शब्द मौजूद नहीं है। )

2 और 3 के बीच (2*5=10 (बंदर अलग-अलग मान वाली एक ही कुंजी है) +

6 (वाक्य3 की कुंजी 'सेब' वाक्य में मौजूद है) +

5 (वाक्य4 की कुंजी 'बंदर' वाक्य में मौजूद है)= 21

0 और 3 के बीच: 3+5+8=16 (वाक्य1 कुंजी 'सेब' वाक्य 4 में मौजूद है, और वाक्य 4 कुंजी 'अंडा' और 'पीच' वाक्य 1 में मौजूद हैं।

मुझे आशा है कि ये उदाहरण इसे स्पष्ट करते हैं।

मैंने जो कोशिश की है (नेस्टेड संरचना और संयोजनों के कारण यह मेरे लिए काफी भ्रमित था):

from itertools import combinations, zip_longest
import networkx as nx

def compare_inner_dicts(d1,d2):
#this is for comparing the inner dict keys and multiplying them
#if they have the same key but different value
    values = []
    inner_values = 0
    for common_key in d1.keys() & d2.keys():
        if d1[common_key]!= d2[common_key]:
            _value = d1[common_key]*d2[common_key]
            values.append(_value)
            inner_values = sum([p for p in values])

    inner_dict_values = inner_values
    del inner_values  

    return inner_dict_values


def build_adj_mat(a_dict):
    gr = nx.Graph()
    for sentence, words in a_dict.items():

        sentences = list(a_dict.keys())
        gr.add_nodes_from(sentences)
        sentence_pairs = combinations(gr.nodes, 2)
        dict_pairs = combinations(a_dict.values(), 2)
        for pair, _pair in zip_longest(sentence_pairs, dict_pairs):
            numbers = []
            x_numbers = []
            #y_numbers = []
            sentence1 = pair[0]
            sentence2 = pair[1]
            dict1 = _pair[0]
            dict2 = _pair[1]

            inner_dict_numbers = compare_inner_dicts(dict1, dict2)
            numbers.append(inner_dict_numbers)

            for word, num in words.items():
                if sentence2.find(word)>-1:
                    x = words[word]
                    x_numbers.append(x)
                    numbers.extend(x_numbers)
#                if sentence1.find(word)>-1: #reverse case
#                    y = words[word]
#                    y_numbers.append(y)
#                    numbers.extend(y_numbers)

                    total = sum([p for p in numbers if len(numbers)>0])

                    if total>0:
                        gr.add_edge(sentence1, sentence2, weight=total)
                        del total
                    else: del total
                else: 
                    continue
                    numbers.clear()
                    x_numbers.clear()
                   #y_numbers.clear()

    return gr

G = build_adj_mat(example_dictionary)
print(nx.adjacency_matrix(G))

अपेक्षित परिणाम:

(0, 1) 5*2+5*2=20
(0, 2) 3*6=18+5=23
(0, 3) 3+5+8=16
(1, 0) 20
(1, 2) 3*6=18+2=20
(1, 3) 3+5=8
(2, 0) 23
(2, 1) 20
(2, 3) 2*5=10+5+6=21
(3, 0) 16
(3, 1) 8
(3, 2) 21

आउटपुट:

  (0, 2)        23
  (0, 3)        6
  (1, 2)        23
  (1, 3)        6
  (2, 0)        23
  (2, 1)        23
  (2, 3)        16
  (3, 0)        6
  (3, 1)        6
  (3, 2)        16

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

2
mulaixi 20 अक्टूबर 2019, 22:39

1 उत्तर

सबसे बढ़िया उत्तर

आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:

from collections import defaultdict
import itertools as it
import re


def compute_scores(sentence_dict):
    scores = defaultdict(int)
    for (j, (s1, d1)), (k, (s2, d2)) in it.combinations(enumerate(sentence_dict.items()), 2):
        shared_keys = d1.keys() & d2.keys()
        scores[j, k] += sum(d1[k]*d2[k] for k in shared_keys if d1[k] != d2[k])
        scores[j, k] += sum(d1[k] for k in d1.keys() & get_words(s2))
        scores[j, k] += sum(d2[k] for k in d2.keys() & get_words(s1))
    return scores


def get_words(sentence):
    return set(map(str.lower, re.findall(r'(?<=\b)\w+(?=\b)', sentence)))

परिणाम निश्चित रूप से इस बात पर निर्भर करता है कि आप एक शब्द के रूप में क्या परिभाषित करते हैं, इसलिए आपको फ़ंक्शन get_words में अपनी परिभाषा भरनी होगी। डिफ़ॉल्ट कार्यान्वयन आपके उदाहरण डेटा के अनुरूप प्रतीत होता है। चूंकि आपकी परिभाषा के अनुसार वाक्य युग्म के लिए स्कोर सममित है, इसलिए रिवर्स पेयरिंग पर भी विचार करने की कोई आवश्यकता नहीं है (इसका स्कोर समान है); यानी (0, 1) का स्कोर (1, 0) के बराबर है। इसलिए कोड itertools.combinations का उपयोग करता है।

उदाहरण डेटा चल रहा है:

from pprint import pprint

example_dictionary = {
    'I want to eat peach and egg.': {'apple':3, 'orange':2, 'banana':5},
    'Peach juice is so delicious.': {'apple':3, 'orange':5, 'banana':2},
    'Goddamn monkey ate my banana.': {'rice':4, 'apple':6, 'monkey':2},
    'They say apple is good for health.': {'grape':10, 'monkey':5, 'peach':5, 'egg':8}}

pprint(compute_scores(example_dictionary))

निम्नलिखित अंक देता है:

defaultdict(<class 'int'>,
            {(0, 1): 20,
             (0, 2): 23,
             (0, 3): 16,
             (1, 2): 20,
             (1, 3): 8,
             (2, 3): 21})

यदि डिक्ट्स में न केवल शब्द हो सकते हैं, बल्कि वाक्यांश (यानी कई शब्द) भी हो सकते हैं, मूल कार्यान्वयन का थोड़ा सा संशोधन (एकल शब्दों के लिए भी काम करता है) करेगा:

scores[j, k] += sum(weight for phrase, weight in d1.items() if phrase in s2.lower())
scores[j, k] += sum(weight for phrase, weight in d2.items() if phrase in s1.lower())
2
a_guest 21 अक्टूबर 2019, 00:37