2014-04-01 4 views
5

Ich möchte ein Korpus von Dokumenten mit Python in der gleichen Weise wie ich in R vorprozessieren. Zum Beispiel, mit einem ersten Korpus, corpus, würde ich gerne mit einem vorverarbeiteten enden Korpus, die derjenigen entspricht, erzeugt den folgenden R Code verwendet:Exakt replizierende R-Text-Vorverarbeitung in Python

library(tm) 
library(SnowballC) 

corpus = tm_map(corpus, tolower) 
corpus = tm_map(corpus, removePunctuation) 
corpus = tm_map(corpus, removeWords, c("myword", stopwords("english"))) 
corpus = tm_map(corpus, stemDocument) 

gibt es eine einfache oder einfach - vorzugsweise vorgefertigter - Methode hierfür in Python zu tun? Gibt es eine Möglichkeit, genau die gleichen Ergebnisse zu erzielen?


Zum Beispiel würde ich Vorprozess

@Apple Ohr mögen Schoten sind unglaublich! Bester Sound von In-Ear-Kopfhörern habe ich je gehabt!

in

Ohr pod amaz besten Sound inear headphon ich je

+0

Verwenden nltk für die Verarbeitung natürlicher Sprache in Python. – ramcdougal

+0

@ramcdougal: So viel habe ich gesammelt, aber ich kämpfe mit der Dokumentation. – orome

+0

Schauen Sie sich das [Tutorial] (http://nbviewer.ipython.org/urls/gist.githubusercontent.com/kljensen/9662971/raw/4628ed3a1d27b84a3c56e46d87146c1d08267893/NewHaven.io+NLP+tutorial.ipynb?create=1) an. Es umfasst Tokenisierung, Stoppwörter und Stemming. – ramcdougal

Antwort

3

Es scheint knifflige Dinge zu bekommen genau das gleiche zwischen nltk und tm auf den Vorverarbeitungsschritten, so denke ich, die Der beste Ansatz ist, rpy2 zu verwenden, um die Vorverarbeitung in R auszuführen und die Ergebnisse in Python zu ziehen:

import rpy2.robjects as ro 
preproc = [x[0] for x in ro.r(''' 
tweets = read.csv("tweets.csv", stringsAsFactors=FALSE) 
library(tm) 
library(SnowballC) 
corpus = Corpus(VectorSource(tweets$Tweet)) 
corpus = tm_map(corpus, tolower) 
corpus = tm_map(corpus, removePunctuation) 
corpus = tm_map(corpus, removeWords, c("apple", stopwords("english"))) 
corpus = tm_map(corpus, stemDocument)''')] 

Dann können Sie es in scikit-learn laden - das einzige, was Sie tun müssen, werde die Dinge zwischen dem CountVectorizer und dem DocumentTermMatrix anzupassen ist hinsichtlich der Länge zu entfernen, weniger als 3:

from sklearn.feature_extraction.text import CountVectorizer 
def mytokenizer(x): 
    return [y for y in x.split() if len(y) > 2] 

# Full document-term matrix 
cv = CountVectorizer(tokenizer=mytokenizer) 
X = cv.fit_transform(preproc) 
X 
# <1181x3289 sparse matrix of type '<type 'numpy.int64'>' 
# with 8980 stored elements in Compressed Sparse Column format> 

# Sparse terms removed 
cv2 = CountVectorizer(tokenizer=mytokenizer, min_df=0.005) 
X2 = cv2.fit_transform(preproc) 
X2 
# <1181x309 sparse matrix of type '<type 'numpy.int64'>' 
# with 4669 stored elements in Compressed Sparse Column format> 

wir überprüfen diese mit R übereinstimmt:

tweets = read.csv("tweets.csv", stringsAsFactors=FALSE) 
library(tm) 
library(SnowballC) 
corpus = Corpus(VectorSource(tweets$Tweet)) 
corpus = tm_map(corpus, tolower) 
corpus = tm_map(corpus, removePunctuation) 
corpus = tm_map(corpus, removeWords, c("apple", stopwords("english"))) 
corpus = tm_map(corpus, stemDocument) 
dtm = DocumentTermMatrix(corpus) 
dtm 
# A document-term matrix (1181 documents, 3289 terms) 
# 
# Non-/sparse entries: 8980/3875329 
# Sparsity   : 100% 
# Maximal term length: 115 
# Weighting   : term frequency (tf) 

sparse = removeSparseTerms(dtm, 0.995) 
sparse 
# A document-term matrix (1181 documents, 309 terms) 
# 
# Non-/sparse entries: 4669/360260 
# Sparsity   : 99% 
# Maximal term length: 20 
# Weighting   : term frequency (tf) 

Wie Sie die Anzahl der gespeicherten Elemente und Bedingungen finden können, genau jetzt zwischen den beiden Ansätzen entsprechen.

+0

Gibt es eine Möglichkeit, dies an den 'CountVectorizer'-Konstruktor von' scikit-learn' zu übergeben. Die Dokumente lassen es so erscheinen, als ob das möglich wäre, aber ich kann nicht herausfinden, wie. – orome

+1

@raxacoricofallapatorius aktualisiert mit 'CountVectorizer'. Es ist großartig zu sehen, dass jemand den 15.071x-Inhalt in Python durcharbeitet! – josliber

+0

Danke. Ich bin neu in R (was ich verabscheue) Python (was großartig ist) und Analytik, also ist es schwierig. Ich wünschte, der Kurs wäre in Python gelehrt worden! – orome

1

CountVectorizer und TfidfVectorizer können wie in der docs beschrieben angepasst werden. Insbesondere sollten Sie einen benutzerdefinierten Tokenizer schreiben, bei dem es sich um eine Funktion handelt, die ein Dokument akzeptiert und eine Liste mit Begriffen zurückgibt. Mit NLTK:

import nltk.corpus.stopwords 
import nltk.stem 

def smart_tokenizer(doc): 
    doc = doc.lower() 
    doc = re.findall(r'\w+', doc, re.UNICODE) 
    return [nltk.stem.PorterStemmer().stem(term) 
      for term in doc 
      if term not in nltk.corpus.stopwords.words('english')] 

Demo: (. Das Beispiel, das ich im Zusammenhang mit tatsächlich eine Klasse verwendet die Lemmatizer zwischenzuspeichern, aber eine Funktion funktioniert auch)

>>> v = CountVectorizer(tokenizer=smart_tokenizer) 
>>> v.fit_transform([doc]).toarray() 
array([[1, 1, 1, 2, 1, 1, 1, 1, 1]]) 
>>> from pprint import pprint 
>>> pprint(v.vocabulary_) 
{u'amaz': 0, 
u'appl': 1, 
u'best': 2, 
u'ear': 3, 
u'ever': 4, 
u'headphon': 5, 
u'pod': 6, 
u'sound': 7, 
u've': 8} 

+0

Dies funktioniert nicht mit Satzzeichen oder benutzerdefinierten Wörtern (wie "Apple" in [Josilbers Antwort] (http://stackoverflow.com/a/22798822/656912)). – orome

+0

@raxacoricofallapatorius Es ist nur ein Beispiel. Der Punkt ist, dass Sie eine Python-Funktion schreiben und einstecken können; Was diese Funktion macht, liegt ganz bei Ihnen. Sie können die Funktion von josilber so gut wie einbinden. –

Verwandte Themen