Cách tốt nhất để tìm kiếm một tài liệu tương tự cho ngram


7

Tôi có một cơ sở dữ liệu gồm khoảng 200 tài liệu mà tôi đã trích xuất. Tôi muốn tìm tài liệu trong cơ sở dữ liệu của mình tương tự như tài liệu truy vấn. Nói cách khác, tôi muốn tìm tài liệu trong cơ sở dữ liệu chia sẻ số lượng ngrams nhiều nhất với tài liệu truy vấn. Ngay bây giờ, tôi có thể đi qua từng cái một và so sánh từng cái một, nhưng điều này sẽ mất thời gian O (N) và tốn kém nếu N rất lớn. Tôi đã tự hỏi nếu có bất kỳ cấu trúc dữ liệu hoặc phương pháp hiệu quả trong việc thực hiện tìm kiếm tương tự hiệu quả. Cảm ơn


Làm thế nào bạn sẽ tìm thấy ngrams nhất nếu bạn không tính ngrams? So sánh từng cái một? Đó là truy vấn duy nhất khá đơn giản.
paparazzo

Các ngrams cho các tài liệu đều được tính toán cũng như truy vấn. Vấn đề là bây giờ tôi muốn xem tài liệu nào trong cơ sở dữ liệu giống với truy vấn nhất. Hay đúng hơn, lấy 10 tài liệu hàng đầu tương tự như truy vấn, dựa trên ngrams của họ.
okebz

Câu hỏi đã nêu là ngram đã được trích xuất. Bây giờ bạn đang nói họ được tính toán. Truy vấn tài liệu với tôi là tài liệu. Câu trả lời chỉ tốt như câu hỏi. Cơ sở dữ liệu nào? Cú pháp khác nhau.
paparazzo

Tôi có nghĩa là trích xuất. Dù bằng cách nào, ngrams được lấy từ mỗi tài liệu nên tôi chỉ làm việc với chính ngrams. Bạn có một cơ sở dữ liệu ngrams đại diện cho mỗi tài liệu trong cơ sở dữ liệu. Bạn có một tài liệu truy vấn mà bạn muốn tìm, hãy nói 10 tài liệu hàng đầu xuất hiện tương tự như truy vấn của bạn. Theo cơ sở dữ liệu, hãy nói rằng có một danh sách rất lớn về mô hình ngram đại diện cho tài liệu
okebz

Và bạn có một câu trả lời từ tôi. Một cơ sở dữ liệu với thiết kế bảng không được nêu không thực sự thu hẹp nó.
paparazzo

Câu trả lời:


3

Bạn có thể sử dụng một vectorizer băm trên tài liệu của bạn. Kết quả sẽ là một danh sách các vectơ. Sau đó, vector hóa ngrams của bạn theo cùng một cách và tính toán hình chiếu của vectơ mới này trên những cái cũ. Điều này tương đương với cơ sở dữ liệu tham gia vào một chỉ mục, nhưng có thể có ít chi phí hơn.


1

Cấu trúc dữ liệu thường sử dụng là chỉ mục đảo ngược (ví dụ: trong cơ sở dữ liệu).

Xin lưu ý rằng khớp tất cả ngram là một heuristic tốt nhưng bạn có thể muốn cải thiện nó.

Có tính đến xác suất của mỗi thuật ngữ và xuất phát là những hướng bạn có thể được hưởng lợi.


1

bàn

ngram
docID

PK (khóa chính) ngram, docID

tùy thuộc vào cơ sở dữ liệu có thể thay đổi một chút nhưng đây là TSQL
x là tài liệu bạn phù hợp

select top(1) with ties *    
from 
(  select tm.docID, count(*) as count 
     from table td
     join table tm
       on tm.docID <> td.docID 
      and tm.ngram = td.ngram 
      and td.docID = x
    group by tm.docID 
) tt 
order by count desc

Việc tham gia là trên một chỉ mục (PK) vì vậy điều này rất nhanh. Tôi làm điều này trên một triệu tài liệu chỉ trong vài giây (với các điều kiện nâng cao hơn).

Điều này sẽ ủng hộ các tài liệu lớn hơn nhưng đó là những gì bạn yêu cầu.

Câu hỏi dường như đang thay đổi

declare table @query (varchar ngram);
insert into @query values ('ng1'), ('ng2'), ('ng3');
select top(10) with ties *    
from 
(  select tm.docID, count(*) as count 
     from table td
     join @query
       on tm.ngram = @query.ngram
    group by tm.docID 
) tt 
order by count desc

1

Từ sự làm rõ của bạn -

Theo cơ sở dữ liệu, hãy nói rằng có một danh sách rất lớn mô hình ngram đại diện cho tài liệu

Bạn sẽ làm tốt để làm một cái gì đó có cấu trúc hơn một chút và đưa dữ liệu vào cơ sở dữ liệu quan hệ. Điều này sẽ cho phép bạn thực hiện phân tích chi tiết hơn nhiều dễ dàng và nhanh chóng hơn.

Tôi đoán khi bạn nói "ngram", bạn có nghĩa là "1 gram". Bạn có thể mở rộng phân tích để bao gồm 2 gram, 3 gram, v.v., nếu bạn muốn.

Tôi sẽ có một cấu trúc bảng trông giống như thế này -

Giá trị
ID 1Gram

Tài liệu
ID
DocTitle
DocAuthor,
v.v.

Docs1Grams
1GramID
DocID
1GramCount

Vì vậy, trong bản ghi trong bảng Docs1Grams khi 1GramID trỏ đến 1gram "the" và DocID trỏ đến tài liệu "Chiến tranh và Hòa bình" thì 1GramCount sẽ giữ số lần 1 gram "the" xuất hiện trong Chiến tranh và Hòa bình.

Nếu DocID cho 'Chiến tranh và Hòa bình "là 1 và DocId cho" Chúa tể của những chiếc nhẫn "là 2 thì để tính điểm tương tự 1gram cho hai tài liệu này, bạn sẽ truy vấn này -

Select count(*) from Docs1Grams D1, Docs1Grams D2   
where D1.DocID = 1 and   
D2.DocID = 2 and   
D1.1GramID = D2.1GramID and   
D1.1GramCount > 0 and   
D2.1GramCount > 0   

Bằng cách khái quát hóa và mở rộng truy vấn, điều này có thể dễ dàng thay đổi để tự động chọn điểm / số cao nhất như vậy so sánh tài liệu bạn đã chọn với tất cả các tài liệu khác.

D1.1GramCount > 0 and D2.1GramCount > 0Ví dụ, bằng cách sửa đổi / mở rộng một phần của truy vấn, bạn có thể dễ dàng làm cho phép so sánh trở nên phức tạp hơn bằng cách thêm 2Gram, 3Grams, v.v. hoặc sửa đổi kết quả khớp đơn giản để ghi điểm theo tỷ lệ phần trăm trên mỗi ngram.

Vì vậy, nếu tài liệu chủ đề của bạn có 0,0009% trong số 1 gram là "the", tài liệu 1 có 0,001% và tài liệu 2 có 0,0015% thì tài liệu 1 sẽ đạt điểm cao hơn về "the" bởi vì mô đun của sự khác biệt (hoặc bất kỳ biện pháp nào khác bạn chọn để sử dụng) nhỏ hơn.


1

Nếu bạn muốn kiểm tra sự hiện diện của n gram của bạn trong tài liệu, bạn sẽ cần chuyển đổi tài liệu truy vấn cũng thành n gram. Để thực hiện điều này, bạn có thể sử dụng vector vector TFIDF.

from nltk.tokenize import word_tokenize               
from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer(tokenizer=word_tokenize,ngram_range=(1,2), binary=True, max_features=10000)
TFIDF=vect.fit_transform(df_lvl0['processed_cv_data'])

Để giải thích mã trên:
word_tokenize : hàm này chuyển đổi văn bản thành mã thông báo chuỗi nhưng bạn sẽ phải xóa dữ liệu tương ứng.
ngram_range : đặt số lượng ngram bạn cần. Trong trường hợp này, nó sẽ mất cả 1 từ và 2 từ.
max_features : giới hạn tổng số không. của các tính năng. Tôi khuyên bạn nên sử dụng nó nếu bạn muốn mã hóa một vài tài liệu là không. tính năng rất cao (theo thứ tự 10 ^ 6).

Bây giờ sau khi bạn phù hợp với mô hình, các tính năng được lưu trữ trong "vect". Bạn có thể xem chúng bằng cách sử dụng:

keywords=set(vect.get_feature_names())

Bây giờ bạn có gram của tài liệu truy vấn của bạn được lưu trữ trong một tập hợp, bạn có thể thực hiện các thao tác tập hợp nhanh hơn nhiều so với các vòng lặp. Ngay cả khi độ dài của mỗi bộ theo thứ tự 10 ^ 5, bạn sẽ nhận được kết quả sau vài giây. Tôi rất khuyên bạn nên thử bộ trong python.

matching_keys = keywords.intersection(all_grams)   //all_grams is the set of your collected grams

Cuối cùng, bạn sẽ nhận được tất cả các từ khóa phù hợp vào "khớp_key".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.