Giới thiệu một trong những hack tốt nhất trong học máy: Thủ thuật băm

Năm 2018 đã được ca ngợi bởi nhiều cửa hàng khác nhau khi năm spam sẽ bắt đầu chết vì thuật toán học máy sẽ trở nên gần như hoàn hảo trong việc tìm ra đâu là thư thật và thư nào không. Tôi không tin điều đó sẽ xảy ra (những tiến bộ trong học máy cắt giảm cả hai cách), nhưng tôi muốn chia sẻ một vài suy nghĩ chung về cách phân loại thư rác đơn giản dựa trên ML và cách khắc phục một vấn đề quan trọng, vượt qua bộ lọc, sử dụng một trong những cách hack tốt nhất trong học máy: thủ thuật băm. Nó cũng hữu ích phát hiện thư rác bên ngoài.

Xây dựng một trình phân loại thư rác đơn giản

Đối với các tác vụ phân loại tài liệu, bao gồm phân loại thư rác, người ta thường bắt đầu bằng cách xây dựng những gì được biết đến như là một đại diện cho các từ (BOW). Đưa ra một tập hợp các email spam và không spam, mỗi từ duy nhất được thêm vào một từ vựng và được gán một chỉ mục duy nhất, thường bắt đầu từ 0. Giả sử, vì lý do ngắn gọn, chúng ta có một bộ gồm hai ví dụ văn bản ngắn, một ví dụ đó là thư rác và một thứ khác hợp pháp:

tôi kiếm được mười nghìn đô la mỗi tuần chỉ bằng cách lướt web! (Thư rác)
Bạn có rảnh cho một cuộc họp vào đầu tuần tới không? (không phải thư rác)

Nếu chúng tôi quét tập dữ liệu và bắt đầu xây dựng vốn từ vựng của mình, chúng tôi có thể kết thúc với một cái gì đó như thế này:

tôi: 0
thực hiện: 1
mười: 2
nghìn: 3
đô la: 4
mỗi: 5
tuần: 6
chỉ: 7
lướt web: 8
cái: 9
web: 10
là: 11
bạn: 12
miễn phí: 13
cho: 14
a: 15
cuộc họp: 16
sớm: 17
tiếp theo: 18

Tổng cộng có 19 từ duy nhất và mỗi từ được gán một chỉ mục duy nhất (lưu ý rằng tuần từ xuất hiện trong cả hai ví dụ). Bước tiếp theo là tạo các vectơ đặc trưng cho mô hình học máy của chúng tôi. Chúng tôi bắt đầu bằng cách tạo một vectơ cột không cho mỗi ví dụ, với cùng số lượng phần tử như có các từ trong từ vựng của chúng tôi (19):

tôi kiếm được mười nghìn đô la mỗi tuần chỉ bằng cách lướt web! (Thư rác)
-> [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Bạn có rảnh cho một cuộc họp vào đầu tuần tới không? (không phải thư rác)
-> [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

Sau đó, với mỗi từ trong mỗi ví dụ, chúng tôi thực hiện tra cứu từ vựng để lấy chỉ mục và tăng giá trị tại chỉ mục đó lên một:

tôi kiếm được mười nghìn đô la mỗi tuần chỉ bằng cách lướt web! (Thư rác)
-> [1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0]
Bạn có rảnh cho một cuộc họp vào đầu tuần tới không? (không phải thư rác)
-> [0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1]

Các vectơ đặc trưng kết quả là biểu diễn bag-of-words. Các đại diện của BOW thường đưa ra thông tin về dấu câu và trật tự từ, nhưng đối với nhiều vấn đề, đây không phải là vấn đề. Các biểu diễn BOW tinh vi hơn sử dụng trọng số TF-IDF và / hoặc n-gram thay vì đếm từ thô, nhưng ý tưởng cơ bản là như nhau.

Khi chúng ta có các vectơ tính năng BOW, chúng ta có thể đào tạo một trình phân loại nhị phân để xây dựng bộ lọc thư rác. Có nhiều sự lựa chọn liên quan đến các thuật toán học tập, nhưng các nghi phạm phổ biến nhất là Naïve Bayes, các khu rừng ngẫu nhiên, hồi quy logistic và, ngày càng, các mạng lưới thần kinh. Đưa ra một mô hình được đào tạo, chúng ta có thể sử dụng từ vựng để cung cấp trong một email mới dưới dạng vector BOW và dự đoán xem ví dụ đó có phải là thư rác hay không. Lưu ý rằng để suy luận theo thời gian thực, chúng ta cần giữ từ vựng trong RAM càng nhanh càng tốt.

Vấn đề: lách lọc

Kẻ gửi thư rác là xảo quyệt. Một cách phổ biến để đảm bảo thư rác không được lọc ra là trộn lẫn các từ không có trong từ vựng được sử dụng để học phân loại. Xem xét, ví dụ, sau đây, câu hơi khó hiểu:

Tôi có thể là bạn miễn phí cho một cuộc họp lướt web của $$$ vào đầu tuần tới

Rõ ràng, đây không phải là điều mà bất cứ ai cũng sẽ xem xét một email hợp pháp. Nhưng điều gì xảy ra nếu chúng ta sử dụng vốn từ vựng của mình để xây dựng một vectơ BOW cho ví dụ này? Tám từ đầu tiên không có từ vựng trong từ vựng của chúng tôi, và won đã làm cho nó thành. Phần còn lại là, dẫn đến các vectơ sau:

Tôi có thể là bạn miễn phí cho một cuộc họp lướt web của $$$ vào đầu tuần tới
-> [0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1]

Vectơ này giống như vectơ cho ví dụ hợp pháp, bạn có rảnh cho cuộc họp vào đầu tuần tới không? . Bất kỳ phân loại nào được đào tạo về các ví dụ của chúng tôi đều có thể nghĩ rằng thư rác này là hợp pháp. Đây là một vấn đề quan trọng và không dễ giải quyết như người ta nghĩ. Chúng ta có thể thêm các từ mới vào vốn từ vựng của mình, nhưng điều đó có nghĩa là các vectơ đặc trưng kết quả Kích thước sẽ thay đổi, cũng như từ vựng. Các mô hình học máy thường học trên các ví dụ đào tạo có kích thước cố định, vì vậy chúng ta sẽ cần phải đào tạo lại mô hình của mình từ đầu. Điều đó cần có thời gian và trong khi chúng tôi làm điều đó, trình phân loại cũ sẽ tiếp tục chấp nhận thư rác. Chúng tôi cần một giải pháp mà a) có thể xử lý các từ không có từ vựng, b) doesn đòi hỏi chúng tôi phải kiểm tra lại các mô hình của mình từ đầu mỗi khi chúng tôi gặp một từ mới hoặc sai chính tả và c) càng chính xác càng tốt. Nếu chúng ta có thể thoát khỏi mà không giữ một lượng từ vựng lớn trong RAM, thậm chí còn tốt hơn.

Giới thiệu thủ thuật băm

Các hàm băm là nền tảng cho khoa học máy tính. Có rất nhiều loại hàm băm khác nhau, nhưng tất cả chúng đều làm cùng một việc: ánh xạ dữ liệu có kích thước tùy ý sang dữ liệu có kích thước cố định. Thông thường, họ phun ra một số (được gọi là hàm băm):

"John Doe" -> hàm băm -> 34
"Jane Doe" -> hàm băm -> 48

Logic mà theo đó một hàm băm được tính toán phụ thuộc vào chính hàm băm, nhưng tất cả các hàm băm đều có chung các đặc điểm chung:

  • Nếu chúng ta cung cấp cùng một đầu vào cho hàm băm, nó sẽ luôn cung cấp cùng một đầu ra.
  • Lựa chọn hàm băm xác định phạm vi đầu ra có thể, nghĩa là phạm vi luôn được cố định (ví dụ: các số từ 0 đến 1024).
  • Các hàm băm là một chiều: được cung cấp một hàm băm, chúng ta có thể thực hiện tra cứu ngược lại để xác định đầu vào là gì.
  • Các hàm băm có thể xuất ra cùng một giá trị cho các đầu vào khác nhau (xung đột).

Các hàm băm cực kỳ hữu ích trong bất kỳ lĩnh vực khoa học máy tính nào, nhưng làm thế nào chúng có thể được sử dụng để khắc phục vấn đề ngoài từ vựng của trình phân loại thư rác của chúng tôi? Câu trả lời là ngay lập tức rõ ràng, nhưng bước đầu tiên là loại bỏ hoàn toàn vốn từ vựng của chúng tôi. Thay vào đó, khi xây dựng các biểu diễn BOW của chúng tôi, chúng tôi sẽ bắt đầu bằng cách tạo một vectơ cột bằng không với một số lượng lớn (giả sử, 2²⁸) các phần tử cho mỗi ví dụ đào tạo của chúng tôi:

tôi kiếm được mười nghìn đô la mỗi tuần chỉ bằng cách lướt web! (Thư rác)
-> [0 0 0 0 ... 0 0 0 0] (2 ^ 28 yếu tố)
Bạn có rảnh cho một cuộc họp vào đầu tuần tới không? (không phải thư rác)
-> [0 0 0 0 ... 0 0 0 0] (2 ^ 28 yếu tố)

Tiếp theo, chúng tôi sẽ chọn một hàm băm f ăn chuỗi và xuất giá trị trong phạm vi [0, 2²⁸). Nói cách khác, chúng tôi đảm bảo rằng hàm băm của chúng tôi sẽ không bao giờ xử lý một chỉ mục bên ngoài các vectơ đặc trưng của chúng tôi.

Sau lần khởi tạo này, với mỗi ví dụ đào tạo, chúng tôi cung cấp từng từ, từng từ một, thông qua hàm băm của chúng tôi và tăng giá trị tại chỉ mục đã cho lên một - giống như trước đây. Chúng ta có thể kết thúc với các vectơ thưa thớt như thế này:

tôi kiếm được mười nghìn đô la mỗi tuần chỉ bằng cách lướt web! (Thư rác)
-> [0 ... 0 1 1 1 0 1 1 0 ... 0 1 1 1 1 0 1 1 0] (2 ^ 28 yếu tố)
Bạn có rảnh cho một cuộc họp vào đầu tuần tới không? (không phải thư rác)
-> [0 1 0 1 0 ... 0 1 0 ... 0 1 0 ... 0 1 1 0 1 1 0 1] (2 ^ 28 yếu tố)

Quá trình này được gọi là thủ thuật băm.

Bây giờ chúng tôi có đại diện BOW của chúng tôi và có thể đào tạo một trình phân loại về dữ liệu như trước đây. Đơn giản không? Chúng tôi đã bỏ qua việc sử dụng một từ vựng riêng biệt, điều đó có nghĩa là chúng tôi không thể giữ một danh sách các từ có khả năng lớn trong RAM. Nhưng đó chỉ là một hiệu ứng phụ tốt đẹp - vấn đề thực sự chúng tôi muốn giải quyết là lách lọc bằng cách sử dụng các từ không có từ vựng. Vậy làm thế nào để các thủ thuật băm giúp?

Hãy nói rằng chúng tôi có một trình phân loại thư rác được đào tạo trên một loạt các vectơ đặc trưng 2²⁸ BOW thưa thớt. Đưa ra một mẩu thư mới, chúng tôi làm như trước, khởi tạo một vectơ 2²⁸ và chuyển từng từ thông qua hàm băm của chúng tôi. Không giống như trước đây, mỗi từ đơn lẻ kết thúc tăng một số giá trị tính năng. Với vectơ BOW của chúng tôi, mọi từ - ngay cả những từ mới - đều được tính đến tại thời điểm dự đoán. Các từ mới vẫn làm xấu đi tính chính xác của trình phân loại của chúng tôi, nhưng nó không còn có thể phá vỡ hoàn toàn bộ lọc thư rác của chúng tôi bằng cách tạo ra các từ mới. Vì tất cả các vectơ BOW vẫn giữ nguyên kích thước, chúng tôi có thể tăng dần phù hợp với mô hình của chúng tôi với các ví dụ spam / không spam mới mà không cần đào tạo lại toàn bộ từ đầu. Đây là một hình thức học trực tuyến: khi người dùng đánh dấu email là thư rác, mô hình có khả năng học hỏi từ đó mà không cần khởi động lại toàn bộ quá trình. Đối với một ứng dụng thực tế như lọc thư rác, đây là một lợi ích rõ ràng của tính năng băm: chúng ta có thể phản ứng nhanh với các cuộc tấn công bằng cách học ngay khi các ví dụ spam / không spam mới xuất hiện.

Nhưng những gì về va chạm, tôi nghe bạn hỏi? Có phải là một số lỗi chính tả có thể xảy ra khi tăng cùng một chỉ mục với một số từ hợp pháp khi nó đi qua hàm băm? Có, điều đó có thể xảy ra, nhưng nếu bạn chọn kích thước vectơ của mình (làm cho nó lớn nhất có thể) và hàm băm cẩn thận, tỷ lệ xảy ra điều này là không đáng kể, và ngay cả khi nó xảy ra, nó thường không ảnh hưởng đến việc học (hoặc độ chính xác ) nhiều. Tài liệu về các hàm băm tiêu chuẩn thường bao gồm các xác suất va chạm, vì vậy hãy đảm bảo tìm kiếm chúng khi thực hiện giải pháp lừa băm của riêng bạn.

Lưu ý rằng trong một số trường hợp, bạn thậm chí có thể muốn va chạm (ví dụ: để nhóm các từ hợp pháp tương tự), trong trường hợp đó bạn có thể muốn xô chúng trước khi băm.

Một số suy nghĩ cuối cùng

Thủ thuật băm là một trong những thủ thuật gọn gàng trong học máy mà không kiếm được nhiều tình yêu như nó xứng đáng. Nhược điểm duy nhất là thực tế là việc tra cứu ngược (đầu ra thành đầu vào) có thể xảy ra, nhưng đối với nhiều vấn đề, đó không phải là một yêu cầu. Suy nghĩ một cách tổng quát hơn, thủ thuật băm cho phép bạn sử dụng các vectơ đặc trưng có kích thước thay đổi với các thuật toán học tiêu chuẩn (hồi quy, rừng ngẫu nhiên, mạng nơ ron chuyển tiếp thức ăn, SVM, hệ số ma trận, v.v.). Điều đó là đủ để làm cho hầu hết các học viên máy học ít nhất một chút phấn khích.