2016-01-14 28 views
6

Tôi đang tìm một cách hiệu quả để xây dựng Ma trận Tài liệu Thuật ngữ bằng Python có thể được sử dụng cùng với dữ liệu bổ sung.Xử lý văn bản Python: NLTK và gấu trúc

Tôi có một số dữ liệu văn bản với một vài thuộc tính khác. Tôi muốn chạy một số phân tích về văn bản và tôi muốn có khả năng tương quan các tính năng được trích xuất từ ​​văn bản (chẳng hạn như mã thông báo riêng lẻ hoặc chủ đề LDA) với các thuộc tính khác.

Gói của tôi đã tải dữ liệu dưới dạng khung dữ liệu gấu trúc và sau đó mỗi câu trả lời sẽ đại diện cho một tài liệu. Rất tiếc, tôi gặp phải sự cố:

import pandas as pd 
import nltk 

pd.options.display.max_colwidth = 10000 

txt_data = pd.read_csv("data_file.csv",sep="|") 
txt = str(txt_data.comment) 
len(txt) 
Out[7]: 71581 

txt = nltk.word_tokenize(txt) 
txt = nltk.Text(txt) 
txt.count("the") 
Out[10]: 45 

txt_lines = [] 
f = open("txt_lines_only.txt") 
for line in f: 
    txt_lines.append(line) 

txt = str(txt_lines) 
len(txt) 
Out[14]: 1668813 

txt = nltk.word_tokenize(txt) 
txt = nltk.Text(txt) 
txt.count("the") 
Out[17]: 10086 

Lưu ý rằng trong cả hai trường hợp, văn bản được xử lý theo cách chỉ có bất kỳ thứ gì nhưng không gian, chữ cái và,.?! đã bị xóa (để đơn giản).

Như bạn có thể thấy trường gấu trúc được chuyển đổi thành chuỗi trả về ít kết quả phù hợp hơn và độ dài của chuỗi cũng ngắn hơn.

Có cách nào để cải thiện mã trên không?

Ngoài ra, str(x) tạo 1 chuỗi lớn trong số các nhận xét trong khi [str(x) for x in txt_data.comment] tạo đối tượng danh sách không thể chia thành một nhóm từ. Cách tốt nhất để tạo ra một đối tượng nltk.Text sẽ giữ lại các chỉ mục tài liệu là gì? Nói cách khác, tôi đang tìm cách tạo một Ma trận Tài liệu Thuật ngữ, R tương đương với TermDocumentMatrix() từ gói tm.

Rất cám ơn.

+1

không chắc chắn câu hỏi của bạn là gì, nhưng có các thư viện khác cho NLP có thể giúp bạn, thư viện như mẫu, textblob, C & C, nếu bạn đã đến đích, bạn cũng có thể thử các thư viện đó, mỗi thư viện có lợi thế riêng hơn những người khác. – mid

+0

Cảm ơn @mid, tôi biết về gensim, nhưng tôi chưa bao giờ nghe nói về textblob trước đây, nó thực sự trông hữu ích mặc dù! Tôi khá mới với Python (tôi thường làm việc trong R) và tôi thực sự nghi ngờ rằng tôi đã đạt đến một kết thúc chết với NLTK, xem xét các gói phổ biến như thế nào, tôi chắc chắn rằng tôi chỉ thiếu một cái gì đó. – IVR

Trả lời

9

Lợi ích của việc sử dụng một pandasDataFrame sẽ được áp dụng các chức năng nltk cho mỗi row như vậy:

word_file = "/usr/share/dict/words" 
words = open(word_file).read().splitlines()[10:50] 
random_word_list = [[' '.join(np.random.choice(words, size=1000, replace=True))] for i in range(50)] 

df = pd.DataFrame(random_word_list, columns=['text']) 
df.head() 

               text 
0 Aaru Aaronic abandonable abandonedly abaction ... 
1 abampere abampere abacus aback abalone abactor... 
2 abaisance abalienate abandonedly abaff abacina... 
3 Ababdeh abalone abac abaiser abandonable abact... 
4 abandonable abandon aba abaiser abaft Abama ab... 

len(df) 

50 

txt = df.text.apply(word_tokenize) 
txt.head() 

0 [Aaru, Aaronic, abandonable, abandonedly, abac... 
1 [abampere, abampere, abacus, aback, abalone, a... 
2 [abaisance, abalienate, abandonedly, abaff, ab... 
3 [Ababdeh, abalone, abac, abaiser, abandonable,... 
4 [abandonable, abandon, aba, abaiser, abaft, Ab... 

txt.apply(len) 

0  1000 
1  1000 
2  1000 
3  1000 
4  1000 
.... 
44 1000 
45 1000 
46 1000 
47 1000 
48 1000 
49 1000 
Name: text, dtype: int64 

Kết quả là, bạn sẽ có được .count() cho mỗi row nhập:

txt = txt.apply(lambda x: nltk.Text(x).count('abac')) 
txt.head() 

0 27 
1 24 
2 17 
3 25 
4 32 

Sau đó, bạn có thể tổng hợp kết quả bằng cách sử dụng:

txt.sum() 

1239 
+0

Cảm ơn @Stefan, đó chỉ là giải quyết vấn đề của tôi, tuy nhiên đối tượng 'txt' vẫn là đối tượng khung dữ liệu gấu trúc, có nghĩa là tôi chỉ có thể sử dụng một số hàm NLTK sử dụng các vòng lặp' apply', 'map' hoặc' for'. Tuy nhiên, nếu tôi muốn làm một cái gì đó như 'nltk.Text (txt) .concordance (" the ")' Tôi sẽ gặp vấn đề. Để giải quyết điều này, tôi vẫn sẽ cần phải chuyển đổi toàn bộ biến văn bản thành một chuỗi và như chúng ta đã thấy trong ví dụ đầu tiên của tôi, chuỗi đó sẽ bị cắt bớt vì một lý do nào đó. Bất kỳ suy nghĩ về cách vượt qua điều này? Cảm ơn nhiều! – IVR

+0

Bạn có thể chuyển đổi toàn bộ 'văn bản'' cột thành một danh sách các từ bằng cách sử dụng: '[t cho t trong df.text.tolist()]' - hoặc sau khi tạo hoặc sau '.tokenize()'. – Stefan

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