2014-04-01 34 views
5

Tôi muốn tiền xử lý một tập hợp tài liệu bằng Python theo cùng cách mà tôi có thể trong R. Ví dụ: được cung cấp một tập dữ liệu ban đầu, corpus, tôi muốn kết thúc bằng tiền tố corpus tương ứng với sản phẩm được sản xuất bằng mã R sau:Tái tạo chính xác tiền xử lý văn bản R trong 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) 

Có phương pháp đơn giản hay đơn giản - được xây dựng sẵn trong Python? Có cách nào để đảm bảo chính xác kết quả tương tự không?


Ví dụ, tôi muốn preprocess

kén tai @Apple là AMAZING! Âm thanh tốt nhất từ ​​tai nghe trong tai tôi đã từng có!

vào

tai pod amaz âm thanh tốt nhất inear bịt tai ive bao giờ

+0

Sử dụng NLTK cho xử lý ngôn ngữ tự nhiên bằng Python. – ramcdougal

+0

@ramcdougal: Tôi đã tập hợp nhiều, nhưng tôi đang phải vật lộn với tài liệu. – orome

+0

Xem [hướng dẫn] này (http://nbviewer.ipython.org/urls/gist.githubusercontent.com/kljensen/9662971/raw/4628ed3a1d27b84a3c56e46d87146c1d08267893/NewHaven.io+NLP+tutorial.ipynb?create=1). Nó bao gồm tokenization, ngừng từ, và bắt nguồn. – ramcdougal

Trả lời

3

Có vẻ như khó khăn để có được những điều giống hệt nhau giữa nltktm về các bước tiền xử lý, vì vậy tôi nghĩ rằng cách tiếp cận tốt nhất là sử dụng rpy2 để chạy tiền xử lý trong R và kéo kết quả vào python:

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)''')] 

Sau đó, bạn có thể tải nó vào scikit-learn - điều duy nhất bạn sẽ cần phải làm gì để có được những điều để phù hợp giữa CountVectorizerDocumentTermMatrix là để loại bỏ các điều khoản có độ dài ít hơn 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> 

Hãy xác minh điều này khớp với 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) 
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) 

Như bạn có thể thấy, số lượng phần tử và cụm từ được lưu khớp chính xác giữa hai phương pháp hiện tại.

+0

Có cách nào để truyền điều này cho constructor 'CountVectorizer' của' scikit-learn'. Các tài liệu làm cho nó có vẻ như thế này nên có thể, nhưng tôi không thể tìm ra cách. – orome

+1

@raxacoricofallapatorius được cập nhật để bao gồm 'Bộ đếm ngược '. Thật tuyệt khi thấy ai đó làm việc thông qua nội dung 15.071x trong python! – josliber

+0

Cảm ơn. Tôi mới đến R (mà tôi không thích) Python (đó là tuyệt vời) và phân tích, do đó, nó sẽ khó khăn. Tôi muốn khóa học được giảng dạy bằng Python! – orome

1

CountVectorizerTfidfVectorizer có thể được tùy chỉnh như được mô tả trong docs. Cụ thể, bạn sẽ muốn viết một trình mã thông báo tùy chỉnh, là một hàm nhận một tài liệu và trả về một danh sách các thuật ngữ. Sử dụng 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: (. Ví dụ tôi liên kết với thực tế sử dụng một lớp học để bộ nhớ cache lemmatizer, nhưng một chức năng làm việc quá)

>>> 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

Điều này không xử lý dấu chấm câu hoặc từ tùy chỉnh (như "táo" trong [câu trả lời của josilber] (http://stackoverflow.com/a/22798822/656912)). – orome

+0

@raxacoricofallapatorius Nó chỉ là một ví dụ. Vấn đề là bạn có thể viết một hàm Python và cắm nó vào; những gì chức năng đó là hoàn toàn tùy thuộc vào bạn. Bạn có thể cắm nhiều chức năng của josilber. –

Các vấn đề liên quan