Tôi có tài liệu văn bản chứa chủ yếu danh sách các mục.
Mỗi Mục là một nhóm gồm nhiều mã thông báo từ các loại khác nhau: FirstName, LastName, BirthDate, PhoneNumber, City, Nghề nghiệp, v.v ... Mã thông báo là một nhóm từ.
Các mặt hàng có thể nằm trên một số dòng.
Các mục từ một tài liệu có cùng một cú pháp mã thông báo, nhưng chúng không nhất thiết phải giống hệt nhau.
Chúng có thể là một số ít hơn / ít mã thông báo giữa các Mục, cũng như trong các Mục.
FirstName LastName BirthDate PhoneNumber
Occupation City
FirstName LastName BirthDate PhoneNumber PhoneNumber
Occupation City
FirstName LastName BirthDate PhoneNumber
Occupation UnrecognizedToken
FirstName LastName PhoneNumber
Occupation City
FirstName LastName BirthDate PhoneNumber
City Occupation
Mục tiêu là xác định ngữ pháp được sử dụng, vd
Occupation City
và cuối cùng xác định tất cả các Mục, thậm chí nghĩ rằng chúng không khớp chính xác.
Để ngắn gọn và dễ đọc, thay vào đó hãy sử dụng một số bí danh A, B, C, D, ... để chỉ định các loại mã thông báo đó.
ví dụ
A B C
D F
A B C
D E F
F
A B C
D E E F
A C B
D E F
A B D C
D E F
A B C
D E F G
Ở đây chúng ta có thể thấy rằng cú pháp Item là
A B C
D E F
bởi vì nó là cái phù hợp nhất với chuỗi.
Cú pháp (loại mã thông báo và đơn đặt hàng) có thể thay đổi rất nhiều từ tài liệu này sang tài liệu khác. ví dụ: một tài liệu khác có thể có danh sách đó
D A
D A
D
D A
B
D A
Mục tiêu là tìm ra cú pháp mà không có kiến thức trước về nó .
Từ bây giờ, một dòng mới cũng được coi là một mã thông báo. Sau đó, một tài liệu có thể được trình bày dưới dạng chuỗi mã thông báo 1 chiều:
Ở đây trình tự lặp lại sẽ là A B C B
vì nó là mã thông báo tạo ra ít xung đột nhất.
Hãy phức tạp hóa nó một chút. Từ bây giờ mỗi mã thông báo không có loại xác định. Trong thế giới thực, chúng tôi không phải lúc nào cũng chắc chắn 100% về một số loại mã thông báo. Thay vào đó, chúng tôi cung cấp cho nó một xác suất có một loại nhất định.
A 0.2 A 0.0 A 0.1
B 0.5 B 0.5 B 0.9 etc.
C 0.0 C 0.0 C 0.0
D 0.3 D 0.5 D 0.0
Đây là một hình ảnh trừu tượng về những gì tôi muốn đạt được:
Giải pháp được coi là A: Kết hợp một miếng token
Giải pháp này bao gồm việc áp dụng tích chập với một số bản vá mã thông báo và lấy mã tạo ra ít xung đột nhất.
Phần khó ở đây là tìm các bản vá tiềm năng để cuộn dọc theo chuỗi quan sát. Vài ý tưởng cho cái này, nhưng không có gì rất thỏa mãn:
Xây dựng mô hình Markov về quá trình chuyển đổi giữa các mã thông báoNhược điểm: vì một mô hình Markov không có bộ nhớ, chúng tôi sẽ mất các lệnh chuyển đổi. ví dụ: Nếu chuỗi lặp lại là A B C B D
, chúng ta sẽ mất thực tế là A-> B xảy ra trước C-> B.
Điều này dường như được sử dụng rộng rãi trong sinh học để phân tích nucleobase (GTAC) trong DNA / RNA. Nhược điểm: Cây Suffix rất phù hợp để kết hợp chính xác các mã thông báo chính xác (ví dụ: ký tự). Chúng tôi không có trình tự chính xác, cũng không có mã thông báo chính xác.
Lực lượng vũ phuHãy thử mọi sự kết hợp của mọi kích cỡ. Thực sự có thể làm việc, nhưng sẽ mất một thời gian (dài (dài)).
Giải pháp được coi là B: Xây dựng bảng khoảng cách Levenshtein của hậu tố
Trực giác là có thể tồn tại một số cực tiểu địa phương khi tính toán khoảng cách từ mọi hậu tố đến mọi hậu tố.
Hàm khoảng cách là khoảng cách Levenshtein, nhưng chúng ta sẽ có thể tùy chỉnh nó trong tương lai để tính đến xác suất của một loại nhất định, thay vì có một loại cố định cho mỗi mã thông báo.
Để đơn giản trong phần trình diễn đó, chúng tôi sẽ sử dụng mã thông báo loại cố định và sử dụng Levenshtein cổ điển để tính khoảng cách giữa các mã thông báo.
ví dụ: Hãy có chuỗi đầu vào ABCGDEFGH ABCDEFGH ABCDNEFGH
.
Chúng tôi tính khoảng cách của mọi hậu tố với mọi hậu tố (được cắt thành kích thước bằng nhau):
for i = 0 to sequence.lengh
for j = i to sequence.lengh
# Create the suffixes
suffixA = sequence.substr(i)
suffixB = sequence.substr(j)
# Make the suffixes the same size
chunkLen = Math.min(suffixA.length, suffixB.length)
suffixA = suffixA.substr(0, chunkLen)
suffixB = suffixB.substr(0, chunkLen)
# Compute the distance
distance[i][j] = LevenshteinDistance(suffixA, suffixB)
Chúng tôi nhận được ví dụ như kết quả sau (màu trắng là khoảng cách nhỏ, màu đen là lớn):
Bây giờ, rõ ràng là bất kỳ hậu tố so với chính nó sẽ có một khoảng cách null. Nhưng chúng tôi không quan tâm bằng hậu tố (chính xác hoặc một phần) phù hợp với chính nó, vì vậy chúng tôi cắt phần đó.
Vì các hậu tố được cắt theo cùng kích thước, so sánh chuỗi dài sẽ luôn mang lại khoảng cách lớn hơn so với các chuỗi nhỏ hơn.
Chúng ta cần bù lại bằng một hình phạt mượt mà bắt đầu từ bên phải (+ P), mờ dần theo tuyến tính sang bên trái.
Tôi không chắc chắn làm thế nào để chọn một chức năng hình phạt tốt sẽ phù hợp với tất cả các trường hợp.
Ở đây chúng tôi áp dụng hình phạt (+ P = 6) ở cực bên phải, mờ dần về 0 sang trái.
Bây giờ chúng ta có thể thấy rõ 2 đường chéo rõ ràng xuất hiện. Có 3 Mục (Mục 1, Mục2, Mục 3) trong chuỗi đó. Dòng dài nhất đại diện cho sự phù hợp giữa Item1 vs Item2 và Item2 vs Item3. Dài thứ hai đại diện cho sự phù hợp giữa Item1 so với Item3.
Bây giờ tôi không chắc chắn về cách tốt nhất để khai thác dữ liệu đó. Có đơn giản như lấy các đường chéo cao nhất?
Hãy giả sử nó là.
Hãy tính giá trị trung bình của đường chéo bắt đầu từ mỗi mã thông báo. Chúng ta có thể thấy kết quả trên hình ảnh sau (vectơ bên dưới ma trận):
Rõ ràng có 3 cực tiểu địa phương, khớp với phần đầu của mỗi Mục. Trông tuyệt vời!
Bây giờ, hãy thêm một số khiếm khuyết nữa trong chuỗi:
ABCGDEFGH ABCDEFGH TROLL ABCDEFGH
Rõ ràng bây giờ, vectơ trung bình đường chéo của chúng ta đã bị rối và chúng ta không thể khai thác nó nữa ...
Giả định của tôi là điều này có thể được giải quyết bằng một hàm khoảng cách tùy chỉnh (thay vì Levenshtein), trong đó việc chèn toàn bộ một khối có thể không bị phạt quá nhiều. Đó là những gì tôi không chắc chắn.
Phần kết luận
Không có giải pháp dựa trên tích chập nào được khám phá có vẻ phù hợp với vấn đề của chúng tôi.
Giải pháp dựa trên khoảng cách Levenshtein có vẻ đầy hứa hẹn, đặc biệt vì nó tương thích với các mã thông báo loại dựa trên xác suất. Nhưng tôi không chắc chắn về cách khai thác kết quả của nó.
Tôi sẽ rất biết ơn nếu bạn có kinh nghiệm trong một lĩnh vực liên quan và một vài gợi ý hay để cung cấp cho chúng tôi hoặc các kỹ thuật khác để khám phá. Cảm ơn bạn rất nhiều trước.