2013-04-09 52 views
11

Tôi đang cố tạo ma trận tài liệu thuật ngữ với NLTK và gấu trúc. tôi đã viết các chức năng sau:Thuật ngữ tài liệu thuật ngữ hiệu quả với NLTK

def fnDTM_Corpus(xCorpus): 
    import pandas as pd 
    '''to create a Term Document Matrix from a NLTK Corpus''' 
    fd_list = [] 
    for x in range(0, len(xCorpus.fileids())): 
     fd_list.append(nltk.FreqDist(xCorpus.words(xCorpus.fileids()[x]))) 
    DTM = pd.DataFrame(fd_list, index = xCorpus.fileids()) 
    DTM.fillna(0,inplace = True) 
    return DTM.T 

để chạy nó

import nltk 
from nltk.corpus import PlaintextCorpusReader 
corpus_root = 'C:/Data/' 

newcorpus = PlaintextCorpusReader(corpus_root, '.*') 

x = fnDTM_Corpus(newcorpus) 

Nó hoạt động tốt cho vài file nhỏ ở corpus nhưng mang lại cho tôi một MemoryError khi tôi cố gắng chạy nó với một corpus trong số 4000 tệp (khoảng 2 kb).

Tôi có thiếu gì đó không?

Tôi đang sử dụng một con trăn 32 bit. (sáng trên cửa sổ 7, hệ điều hành 64 bit, CPU lõi tứ, RAM 8 GB). Tôi có thực sự cần phải sử dụng 64 bit cho kho văn bản này không?

+1

bạn đã thử 'gensim' hoặc các thư viện tương tự đã tối ưu hóa mã của chúng cho tf-idf chưa? http://radimrehurek.com/gensim/ – alvas

+0

4000 tệp là một kho nhỏ. Bạn cần một đại diện [thưa thớt] (https://en.wikipedia.org/wiki/Sparse_matrix). Pandas có những thứ như Gensim và scikit-learn. –

+0

Tôi nghĩ 'pd.get_dummies (df_column)' có thể thực hiện công việc. Có lẽ tôi đang thiếu một cái gì đó về ma trận thuật ngữ tài liệu –

Trả lời

19

Nhờ Radim và Larsmans. Mục tiêu của tôi là có DTM giống như DTM bạn nhận được trong R tm. Tôi quyết định sử dụng scikit-learn và một phần lấy cảm hứng từ this blog entry. Mã này tôi đã đưa ra.

Tôi đăng nó ở đây với hy vọng một người khác sẽ thấy nó hữu ích.

import pandas as pd 
from sklearn.feature_extraction.text import CountVectorizer 

def fn_tdm_df(docs, xColNames = None, **kwargs): 
    ''' create a term document matrix as pandas DataFrame 
    with **kwargs you can pass arguments of CountVectorizer 
    if xColNames is given the dataframe gets columns Names''' 

    #initialize the vectorizer 
    vectorizer = CountVectorizer(**kwargs) 
    x1 = vectorizer.fit_transform(docs) 
    #create dataFrame 
    df = pd.DataFrame(x1.toarray().transpose(), index = vectorizer.get_feature_names()) 
    if xColNames is not None: 
     df.columns = xColNames 

    return df 

sử dụng nó trên một danh sách các văn bản trong một thư mục

DIR = 'C:/Data/' 

def fn_CorpusFromDIR(xDIR): 
    ''' functions to create corpus from a Directories 
    Input: Directory 
    Output: A dictionary with 
      Names of files ['ColNames'] 
      the text in corpus ['docs']''' 
    import os 
    Res = dict(docs = [open(os.path.join(xDIR,f)).read() for f in os.listdir(xDIR)], 
       ColNames = map(lambda x: 'P_' + x[0:6], os.listdir(xDIR))) 
    return Res 

để tạo ra các dataframe

d1 = fn_tdm_df(docs = fn_CorpusFromDIR(DIR)['docs'], 
      xColNames = fn_CorpusFromDIR(DIR)['ColNames'], 
      stop_words=None, charset_error = 'replace') 
22

Tôi biết OP muốn tạo ra một TDM trong NLTK, nhưng gói textmining (pip install textmining) làm cho nó chết đơn giản:

import textmining 

def termdocumentmatrix_example(): 
    # Create some very short sample documents 
    doc1 = 'John and Bob are brothers.' 
    doc2 = 'John went to the store. The store was closed.' 
    doc3 = 'Bob went to the store too.' 
    # Initialize class to create term-document matrix 
    tdm = textmining.TermDocumentMatrix() 
    # Add the documents 
    tdm.add_doc(doc1) 
    tdm.add_doc(doc2) 
    tdm.add_doc(doc3) 
    # Write out the matrix to a csv file. Note that setting cutoff=1 means 
    # that words which appear in 1 or more documents will be included in 
    # the output (i.e. every word will appear in the output). The default 
    # for cutoff is 2, since we usually aren't interested in words which 
    # appear in a single document. For this example we want to see all 
    # words however, hence cutoff=1. 
    tdm.write_csv('matrix.csv', cutoff=1) 
    # Instead of writing out the matrix you can also access its rows directly. 
    # Let's print them to the screen. 
    for row in tdm.rows(cutoff=1): 
      print row 

termdocumentmatrix_example() 

Output:

['and', 'the', 'brothers', 'to', 'are', 'closed', 'bob', 'john', 'was', 'went', 'store', 'too'] 
[1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0] 
[0, 2, 0, 1, 0, 1, 0, 1, 1, 1, 2, 0] 
[0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1] 

Ngoài ra, người ta có thể sử dụng gấu trúc và sklearn [source]:

import pandas as pd 
from sklearn.feature_extraction.text import CountVectorizer 

docs = ['why hello there', 'omg hello pony', 'she went there? omg'] 
vec = CountVectorizer() 
X = vec.fit_transform(docs) 
df = pd.DataFrame(X.toarray(), columns=vec.get_feature_names()) 
print(df) 

Output:

hello omg pony she there went why 
0  1 0  0 0  1  0 1 
1  1 1  1 0  0  0 0 
2  0 1  0 1  1  1 0 
+1

Tôi gặp lỗi khi chạy mã của bạn: nhập khẩu stemer ImportError: Không có mô-đun có tên 'stemmer' Làm cách nào để khắc phục? Tôi đã thử pip cài đặt gốc. –

+0

Bạn đang sử dụng phiên bản Python nào? Có thể có một mô-đun nhập khẩu mô-đun gốc trong gói textmining đó là flailing.Tôi chỉ chạy 'pip install textmining' rồi chạy đoạn mã trên 2.7.9 và nhận được kết quả mong đợi. – duhaime

+0

Tôi sử dụng python 3.5, anaconda, windows 10. Tôi chạy 'pip install textmining'. Tôi đã sao chép và chạy mã như vậy. –

0

Một cách tiếp cận thay thế sử dụng thẻ và Frame dữ liệu

import nltk 
comment #nltk.download() to get toenize 
from urllib import request 
url = "http://www.gutenberg.org/files/2554/2554-0.txt" 
response = request.urlopen(url) 
raw = response.read().decode('utf8') 
type(raw) 

tokens = nltk.word_tokenize(raw) 
type(tokens) 

tokens[1:10] 
['Project', 
'Gutenberg', 
'EBook', 
'of', 
'Crime', 
'and', 
'Punishment', 
',', 
'by'] 

tokens2=pd.DataFrame(tokens) 
tokens2.columns=['Words'] 
tokens2.head() 


Words 
0 The 
1 Project 
2 Gutenberg 
3 EBook 
4 of 

    tokens2.Words.value_counts().head() 
,     16178 
.     9589 
the    7436 
and    6284 
to     5278 
Các vấn đề liên quan