Gensim

2015-02-12 8 views
8

में आईडी द्वारा दस्तावेज़ के स्ट्रिंग संस्करण को पुनर्प्राप्त करें मैं कुछ विषय मॉडलिंग के लिए जेनसिम का उपयोग कर रहा हूं और मुझे उस बिंदु तक पहुंच गया है जहां मैं एलएसआई और टीएफ-आईडीएफ मॉडल का उपयोग कर समानता प्रश्न कर रहा हूं। मैं आईडी और समानताओं का सेट वापस प्राप्त करता हूं, उदाहरण के लिए। (299501, 0.64505910873413086)Gensim

मैं इस मामले में 2 9 5 9 01 में आईडी से संबंधित टेक्स्ट दस्तावेज़ कैसे प्राप्त करूं?

मैंने कॉर्पस, डिक्शनरी, इंडेक्स और मॉडल के लिए दस्तावेज़ों को देखा है और इसे ढूंढ नहीं सकते हैं।

उत्तर

3

अफसोस की बात है, जहां तक ​​मैं कह सकता हूं, आपको विश्लेषण की शुरुआत से ही शुरुआत करना होगा जानना कि आप आईडी द्वारा दस्तावेजों को पुनर्प्राप्त करना चाहते हैं। इसका मतलब है कि आपको आईडी और मूल दस्तावेजों के बीच अपना खुद का मानचित्रण बनाना होगा और सुनिश्चित करें कि आईडी gensim उपयोग पूरे प्रक्रिया में संरक्षित हैं। जैसा कि, मुझे नहीं लगता कि gensim ऐसी मैपिंग आसान रखता है।

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

1

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

देखें gensim.corpora.textcorpus.TextCorpus#get_texts, जो या तो पाठ या "LineNumber" मेटाडेटा का एक सरल एकल आइटम यदि metadata ध्वज सक्षम किया गया है देता है:

def get_texts(self): 
    """Iterate over the collection, yielding one document at a time. A document 
    is a sequence of words (strings) that can be fed into `Dictionary.doc2bow`. 
    Each document will be fed through `preprocess_text`. That method should be 
    overridden to provide different preprocessing steps. This method will need 
    to be overridden if the metadata you'd like to yield differs from the line 
    number. 
    Returns: 
     generator of lists of tokens (strings); each list corresponds to a preprocessed 
     document from the corpus `input`. 
    """ 
    lines = self.getstream() 
    if self.metadata: 
     for lineno, line in enumerate(lines): 
      yield self.preprocess_text(line), (lineno,) 
    else: 
     for line in lines: 
      yield self.preprocess_text(line) 

मैं पहले से ही एक कस्टम make_corpus.py स्क्रिप्ट लागू किया गया था, और एक परीक्षण क्लासिफायरफायर स्क्रिप्ट जो एक खोज दस्तावेज़ में संबंधित दस्तावेजों को खोजने के लिए समानता का उपयोग करती है।

make_corpus स्क्रिप्ट में, मैं अपने TextCorpus बेटी वर्ग के लिए निर्माता में मेटाडाटा सक्षम: इस प्रकार परिवर्तन मैं उस बिंदु से मेटाडाटा का उपयोग करने के लिए बनाया थे

corpus = SysRevArticleCorpus(inp, lemmatize=lemmatize, metadata=True) 

मैं भी मेटाडाटा serialise करने की जरूरत , जैसा कि मैंने नहीं (उदाहरण के कुछ करते हैं) तुरंत कोष पीढ़ी के बाद प्रसंस्करण कर रहा हूँ, ताकि आप भी serialise चरण में मेटाडाटा चालू करने की आवश्यकता:

MmCorpus.serialize(outp + '_bow.mm', corpus, progress_cnt=10000, metadata=True) 

यह बनाता है gensim.matutils.MmWriter#write_corpus एक “xxx_bow.mm.metadata.cpickle” फ़ाइल वाई बचाने आपकी कॉर्पस .mm फाइलें।

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

निर्माता मेटाडेटा फ़्लैग उदा .:

def __init__(self, fname, processes=None, lemmatize=utils.has_pattern(), 
    dictionary=None, metadata=False, 
... 
    self.metadata = metadata 

    if dictionary is None: 
     # temporarily disable metadata to make internal dict 
     metadata_setting = self.metadata 
     self.metadata = False 
     self.dictionary = Dictionary(self.get_texts()) 
     self.metadata = metadata_setting 
    else: 
     self.dictionary = dictionary 

मैं वास्तव में एक JSON कोष तो मैं पहले से ही एक कस्टम पार्सर लिखा था से में पढ़ रहा हूँ प्राप्त करने के लिए की जरूरत है। मेरे लेखों में एक "कोड" संपत्ति है जो मेरी कैननिकल दस्तावेज़ आईडी है। मैं "शीर्षक" को भी स्टोर करना चाहता हूं, और दस्तावेज़ निकाय "टेक्स्ट" संपत्ति में है।(यह विकी उदाहरण में एक्सएमएल पार्सिंग को प्रतिस्थापित करता है)।

def extract_articles(f, filter_namespaces=False): 
    """ 
    Extract article from a SYSREV article export JSON = open file-like object `f`. 

    Return an iterable over (str, str, str) which generates (title, content, pageid) triplets. 
    """ 
    elems = (elem for elem in f) 
    for elem in elems: 
     yield elem["title"], elem["text"] or "", elem["code"] 

यह ओवरराइड get_texts के भीतर से कहा जाता है (मूल वर्ग में यह आप कस्टम मेटाडाटा का उपयोग करने से ओवरराइड करने की आवश्यकता का उल्लेख है)। संक्षेप में:

def get_texts(self): 
... 
    with open(self.fname) as data_file:  
     corpusdata = json.load(data_file) 
    texts = \ 
     ((text, self.lemmatize, title, pageid) 
     for title, text, pageid 
     in extract_articles(corpusdata['docs'], self.filter_namespaces)) 

... (skipping pool processing stuff for clarity) 

    for tokens, title, pageid in pool.imap(process_article, group): 

     if self.metadata: 
      yield (tokens, (pageid, title)) 
     else: 
      yield tokens 

तो यह आपको अपने कॉर्पस.एमएम फाइलों के साथ मेटाडेटा को सहेजना चाहिए। जब आप इसे बाद की लिपि में फिर से पढ़ना चाहते हैं, तो आपको पिकल फ़ाइल को वापस पढ़ने की आवश्यकता होगी - मेटाडेटा को फिर से पढ़ने के लिए कोई भी अंतर्निहित तरीकों से प्रतीत नहीं होता है। सौभाग्य से यह केवल जेनसिम-जेनरेट की गई दस्तावेज़ आईडी द्वारा अनुक्रमित एक शब्दकोश है, इसलिए लोड करना और उपयोग करना आसान है। (See wiki-sim-search)

उदा। मेरे परीक्षण वर्गीकरण में, मैंने अभी मूल सामग्री को खोजने के लिए दो चीजें जोड़े: metadata = pickle.load() और metadata[docID]

# re-load everything... 
dictionary = corpora.Dictionary.load_from_text(datapath+'/en_wordids.txt') 
    corpus = corpora.MmCorpus(datapath +'/xxx_bow.mm') 
metadata = pickle.load(open(datapath + 'xxx_bow.mm.metadata.cpickle', 'rb')) 

lsiModel = models.LsiModel(corpus, id2word=dictionary, num_topics=4) 
index = similarities.MatrixSimilarity(lsiModel[corpus]) 

# example search 
doc = "electronic cognitive simulation" 
vec_bow = dictionary.doc2bow(doc.lower().split()) 
vec_lsi = lsiModel[vec_bow] # convert the query to LSI space 

# perform a similarity query against the corpus 
sims = index[vec_lsi] 
sims = sorted(enumerate(sims), key=lambda item: -item[1]) 

# Look up the original article metadata for the top hit 
(docID, prob) = sims[0] 
print(metadata[docID]) 

# Prints (CODE, TITLE) 
('ShiShani2008ProCarNur', 'Jordanian nurses and physicians learning needs for promoting smoking cessation.') 

मुझे पता है आप से पूछा इस मूल पाठ प्रदान नहीं करता है (मैं इसे अपने आप की जरूरत नहीं है), लेकिन आप बहुत आसानी से, हालांकि इस बल्कि ("मेटाडेटा" करने के लिए पाठ जोड़ सकते हिस्सों मेटाडाटा की परिभाषा और बहुत बड़ा हो सकता है!)। मुझे लगता है कि जेन्सिम मानता है कि आपके पास पहले से ही आपके मूल दस्तावेज़ों का कुछ डेटाबेस होगा, और इसलिए यह दायरे से बाहर होगा। हालांकि मुझे लगता है कि जेनसिम-जेनरेट की गई आईडी और मूल दस्तावेज़ पहचानकर्ताओं के बीच मैपिंग होने की आवश्यकता है, जो मेटाडेटा सुविधा काफी अच्छी तरह से पूरा करती है।

संबंधित मुद्दे