2017-12-11 7 views
1

zu erstellen Ich arbeite gerade dachte, die Text-Tutorials mit Daten außerhalb des Datasets-Moduls für die Arbeit. Ich erhalte einige Textdaten von einem Datenrahmen und ich habe dies als String-Variable für die Arbeit gespeichert.Textacy nicht in der Lage, Korpus aus einer Textacy.doc.Doc Klasse

def mergeText(df): 
    content = '' 
    for i in df['textColumn']: 
     content += (i + '. ') 
    #print(content) 
    return content 


    txt = mergeText(df) 

Ich habe mit spacigen ein wenig gearbeitet, und ich weiß, das ist der normale Weg ist ein Dokument-Objekt

nlp = spacy.load('en') 
doc1 = nlp(txt) 
print(type(doc1)) 

die

class 'spacy.tokens.doc.Doc 

So gibt zu schaffen, sollte ich in der Lage sein generieren Sie ein Korpus aus dieser Dokumentdatei, wie in der Dokumentation

corpus = textacy.corpus.Corpus('en', docs=doc1) 

Aber ich bekomme diese Fehlermeldung, obwohl ich auf die Funktion den richtigen Typen bin vorbei

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-8-c6f568014162> in <module>() 
----> 1 corpus = textacy.corpus.Corpus('en', docs=doc1, metadatas=None) 

~/anaconda3/envs/nlp/lib/python3.6/site-packages/textacy/corpus.py in __init__(self, lang, texts, docs, metadatas) 
    156    else: 
    157     for doc in docs: 
--> 158      self.add_doc(doc) 
    159 
    160  def __repr__(self): 

~/anaconda3/envs/nlp/lib/python3.6/site-packages/textacy/corpus.py in add_doc(self, doc, metadata) 
    337    msg = '`doc` must be {}, not "{}"'.format(
    338     {Doc, SpacyDoc}, type(doc)) 
--> 339    raise ValueError(msg) 
    340 
    341  ################# 

ValueError: `doc` must be {<class 'textacy.doc.Doc'>, <class 'spacy.tokens.doc.Doc'>}, not "<class 'spacy.tokens.token.Token'>" 

ich versucht habe, ein textacy Objekt in der gleichen Art und Weise zu schaffen, aber ohne Glück

doc = textacy.Doc(txt) 
print(type(doc)) 

<class 'spacy.tokens.doc.Doc'> 

I auch versucht, die Texte für die Paramater Korpus zu verwenden, um es den Rohtext vorbei, aber diese gibt

corpus[:10] 

[Doc(1 tokens; "D"), 
Doc(1 tokens; "e"), 
Doc(1 tokens; "a"), 
Doc(1 tokens; "r"), 
Doc(1 tokens; " "), 
Doc(1 tokens; "C"), 
Doc(1 tokens; "h"), 
Doc(1 tokens; "r"), 
Doc(1 tokens; "i"), 
Doc(1 tokens; "s")] 

Alle Ideen, wie dieses Problem beheben?

EDIT Um docs viele Zeilen bilden zu bekommen und dies einen Korpus hier vorbei ist der Datenrahmen mit denen ich arbeite für einen Thread

chat1 = df[(df['chat_hash']=='121418-456986')] 

So ist der Text für jeden Text unter gespeichert eine "Text" -Spalte und jede von diesen könnte bei Bedarf über eine Lautsprechersäule an einen Sprecher gebunden sein.

Momentan schaue ich mir das capitol words Beispiel an, aber es ist nicht ganz klar, wie man das mit einem Dataframe aufteilt.

records = cw.records(speaker_name={'Hillary Clinton', 'Barack Obama'}) 
text_stream, metadata_stream = textacy.fileio.split_record_fields(records, 'text') 
corpus = textacy.Corpus('en', texts=text_stream, metadatas=metadata_stream) 
corpus 

Wäre es einen Fall von Rekorden in diesem Fall die Filter für den Chat-Hash seine

thread = df[(df['chat_hash']=='121418-456986')] 
text_stream, metadata_stream = textacy.fileio.split_record_fields(thread, 'text') 
corpus = textacy.Corpus('en', texts=text_stream, metadatas=metadata_stream) 
corpus 

Antwort

1

Die docs Parameter eine iterable erwartet, und die Elemente des iterable zu sein, die verschiedenen Typen. Sie übergeben ein einzelnes Dokument, das beim Iterieren Tokens zurückgibt - daher der Fehler. Sie können Ihren doc=doc1 Parameter mit doc=[doc1] umhüllen, und das sollte Ihnen ermöglichen, den Korpus zu erstellen.

Dies ist jedoch ein Korpus mit einem einzigen Dokument - das ist unwahrscheinlich sehr nützlich. Möchten Sie für jede Zeile Ihres Dataframes ein Dokument erstellen, anstatt es miteinander zu verketten?

EDIT: Der Umgang mit Datenrahmen

Wenn Sie jeden Chat wollen ein Dokument sein, eine davon zu tun, ist der Datenrahmen durch die chat_hash zu gruppieren und concatonate den gesamten Text zusammen.Erstellen Sie dann für die ein Dokument für jeden Chat und Korpus:

import pandas as pd 
import spacy 
import textacy 

nlp = spacy.load('en') 

df = pd.DataFrame([['Ken', 'aaaa', 1, 'This is a thing I said'], 
        ['Peachy', 'aaaa', 2, 'This was a response'], 
        ['Ken', 'aaaa', 3, 'I agree!'], 
        ['Ken', 'bbbb', 1, 'This is a thing I said'], 
        ['Peachy', 'bbbb', 2, 'You fool!']], columns=['speaker', 'chat_hash', 'sequence_number', 'text']) 

chat_concat = (df 
       .sort_values(['chat_hash', 
          'sequence_number']) 
       .groupby('chat_hash')['text'] 
       .agg(lambda col: '\n'.join(col))) 

docs = list(chat_concat.apply(lambda x: nlp(x))) 

corpus = textacy.corpus.Corpus(nlp, docs=docs) 

corpus 

So werden die Schritte in diesem sind:

  • Legen Sie das Modell (und Dummy-Datenrahmen in diesem Fall erstellen)
  • Sortieren nach Hash und einige Sequenz (also in der richtigen Reihenfolge chatten), dann gruppieren nach dem Chat-Hash und den gesamten Text zusammen (ich benutze neue Zeilen zwischen Text, kann ein beliebiges Trennzeichen
  • Wenden Sie eine Funktion für jeden Textblock an Erstellen Sie ein Dokument daraus
  • Erstellen Sie das Korpus wie zuvor.
+0

Nun, ich arbeite mit Sätzen in einem Thread, der mehrere Zeilen ja ist. Also nehme ich an, dass ich die Daten entsprechend diesem Beispiel hier mit [Großbuchstaben] teilen muss (http://textacy.readthedocs.io/en/stable/index.html) – PeachyDinosaur

+0

Also, was bedeuten Zeilen in Ihrem Dataframe? Ist jeder ein Satz aus einem Thread oder jeder ein Beitrag aus einem Thread? –

+0

Jede Zeile enthält eine Konversation für die Spalte 'text'. – PeachyDinosaur