Tại sao mã hóa Huffman loại bỏ entropy mà Lempel-Ziv không?


13

Thuật toán DEFLATE phổ biến sử dụng mã hóa Huffman trên đầu trang Lempel-Ziv.

Nói chung, nếu chúng ta có một nguồn dữ liệu ngẫu nhiên (= 1 bit entropy / bit), thì không có mã hóa, kể cả Huffman, có khả năng nén nó trung bình. Nếu Lempel-Ziv là "hoàn hảo" (mà nó tiếp cận với hầu hết các loại nguồn, khi chiều dài đến vô cùng), thì mã hóa bài đăng với Huffman sẽ không giúp ích gì. Tất nhiên, Lempel-Ziv không hoàn hảo, ít nhất là với chiều dài hữu hạn, và do đó, một số dư thừa vẫn còn.

Chính sự dư thừa còn lại này mà mã hóa Huffman đã loại bỏ một phần và do đó cải thiện khả năng nén.

Câu hỏi của tôi là: Tại sao sự dư thừa còn lại này được loại bỏ thành công bởi mã hóa Huffman mà không phải LZ? Tính chất nào của Huffman so với LZ làm cho điều này xảy ra? Chỉ đơn giản là chạy lại LZ (nghĩa là mã hóa dữ liệu nén LZ bằng LZ lần thứ hai) có thực hiện được điều tương tự không? Nếu không, tai sao không? Tương tự như vậy, đầu tiên sẽ nén với Huffman và sau đó với LZ hoạt động, và nếu không, tại sao?

CẬP NHẬT: Rõ ràng là ngay cả sau LZ, một số dư thừa sẽ vẫn còn. Một số người đã đưa ra quan điểm đó. Điều không rõ ràng là: Tại sao sự dư thừa còn lại được Huffman giải quyết tốt hơn LZ? Có gì độc đáo về nó trái ngược với sự dư thừa nguồn gốc, nơi LZ hoạt động tốt hơn Huffman?

Câu trả lời:


13

Đây ban đầu là một bình luận, nhưng nó đã quá dài.

Nếu bạn nhìn vào DEFLATE, những gì đang được Huffman nén là đầu ra của LZ77; LZ77 hoạt động bằng cách (khi việc này mất ít bit hơn dữ liệu thô) gửi một con trỏ trước đó vào chuỗi được nén và độ dài khớp cho biết có bao nhiêu ký hiệu sẽ lấy sau con trỏ. Lý thuyết cho thấy rằng, ngay cả khi không nén thêm, kỹ thuật này cuối cùng cũng hội tụ vào entropy nguồn. Tuy nhiên, trong nén dữ liệu, bất cứ khi nào bạn có phân phối không hoàn toàn ngẫu nhiên, bạn cũng có thể nén nó. Không có lý do gì để tin rằng đầu ra của LZ77, các con trỏ và độ dài trận đấu là hoàn toàn ngẫu nhiên. Chúng phải hội tụ để hoàn thành ngẫu nhiên trong giới hạn tiệm cận, vì LZ77 là tối ưu không có triệu chứng, nhưng trong thực tế, bạn chỉ sử dụng một từ điển hữu hạn, vì vậy họ có lẽ ở đủ xa để hoàn toàn ngẫu nhiên mà bạn giành chiến thắng bằng cách nén thêm vào chúng. Đương nhiên, bạn sử dụng một mã Huffman cho các con trỏ và một mã khác cho độ dài khớp, vì hai quy trình này có số liệu thống kê khác nhau.

Tại sao sử dụng Huffman chứ không phải LZ cho vòng nén thứ hai? Lợi thế lớn mà LZ có được so với Huffman là xử lý sự phụ thuộc giữa các biểu tượng. Trong tiếng Anh, nếu một chữ cái là 'q', thì chữ cái tiếp theo cực kỳ có khả năng là 'u', v.v. Nếu các biểu tượng là các sự kiện độc lập, thì Huffman đơn giản hơn và hoạt động tốt hơn hoặc tốt hơn cho các chuỗi ngắn. Đối với đầu ra của LZ77, trực giác của tôi là các biểu tượng nên khá độc lập, vì vậy Huffman nên hoạt động tốt hơn.


Tôi với bạn trên đoạn 1 của bạn: LZ vẫn để lại một số dư thừa để nén thêm. Nhưng đoạn 2 của bạn dường như vẫn nhảy, nếu không vẫy tay. Có hai xác nhận: 1. Sự dư thừa còn lại sau LZ là không có thứ tự (nghĩa là p (X_n) xấp xỉ độc lập với x_n-1; Tôi đang sử dụng thuật ngữ zero-order như trong mô hình không thứ tự, ví dụ: data-compression.com/theory.shtml ) và 2. Khi dự phòng không có thứ tự, Huffman hoạt động tốt hơn LZ; Khi dự phòng bậc cao, LZ hoạt động tốt hơn. Có lẽ những khẳng định này đều đúng, nhưng bạn cũng không có lý do
SRobertJames

2
@Robert: Tương quan bậc cao hơn không ảnh hưởng gì đến mã hóa Huffman. LZ hoạt động tối ưu không có triệu chứng đối với dự phòng đơn hàng cao hơn, nhưng yêu cầu thêm chi phí có nghĩa là nó không hoạt động tốt trên các nguồn không thứ tự có độ dài hữu hạn. Điều này phải được nghiên cứu thực nghiệm trong tài liệu ở đâu đó; có lẽ ai đó khác có thể đưa ra một con trỏ đến một tham chiếu. Đối với điểm 1, trực giác của tôi là mọi sự dư thừa bậc cao còn lại sau LZ quá phức tạp để được sử dụng trong bất kỳ sơ đồ mã hóa đơn giản nào, nhưng tôi không có cách nào tốt để biện minh cho điều này.
Peter Shor

10

Nén dữ liệu thực sự là về hai điều: mô hình hóa và mã hóa. Các thuật toán của họ LZ mô hình hóa văn bản như là sự kết hợp của các lần lặp lại chính xác, điều này là tối ưu không có triệu chứng đối với nhiều nguồn ngẫu nhiên và hợp lý tốt cho nhiều văn bản thực. Đối với một số đầu vào, mô hình này có thể khá xấu, tuy nhiên. Ví dụ, bạn không thể sử dụng LZ để nén trực tiếp một mảng hậu tố, mặc dù mảng hậu tố có thể nén như văn bản gốc.

(p,,c)pc

đăng nhậpnn

Vì vậy, trong ngắn hạn, Huffman đánh bại LZ trong việc nén các bộ dữ liệu, vì mô hình của nó (phân phối cố định so với các lần lặp lại chính xác) là một kết hợp tốt hơn cho dữ liệu.


Cảm ơn bạn, Jouni. Nghe có vẻ dư thừa chính là độ dài đại diện thường nhỏ hơn thay vì lớn hơn (không phân bố đều trên [0,2 ^ n]). Huffman thực hiện tốt tính không đối xứng bậc 0 này, trong khi LZ thực sự cần các tính năng lớn hơn để hoạt động tốt. Đúng không? Và tại sao không sử dụng Huffman để bắt đầu - tại sao lại bận tâm với LZ?
SRobertJames

3
Nếu chúng tôi nén văn bản trực tiếp với Huffman, chúng tôi không thể nén tốt hơn entropy không thứ tự. Tuy nhiên, hầu hết các văn bản thực tế có các nguồn dự phòng đáng kể không thể được mô hình hóa đầy đủ với entropy không thứ tự. Trong nhiều trường hợp, sử dụng LZ trước Huffman cho phép chúng tôi nén sự dư thừa này.
Jouni Sirén

2

Tôi tin rằng câu trả lời nằm ở kích thước từ điển tra cứu.

Dữ liệu có ý nghĩa về địa phương (nghĩa là, nếu một phần dữ liệu đã được sử dụng, có khả năng nó sẽ được sử dụng lại sớm) và thuật toán LZ tận dụng lợi thế này trong việc xây dựng từ điển tra cứu. Nó tạo ra một bộ ba với số lượng hữu hạn các nút có thể, để giữ cho việc tra cứu nhanh . Khi nó đạt đến giới hạn kích thước, nó sẽ tạo ra một trie khác, "quên" về cái trước đó. Vì vậy, nó phải xây dựng lại bảng tra cứu cho các ký tự đơn giản hơn, nhưng nếu một số từ không được sử dụng nữa, chúng sẽ không được giữ trong bộ nhớ nữa, do đó có thể sử dụng mã hóa nhỏ hơn.

Do đó, một đầu ra LZ có thể được giảm hơn nữa với mã hóa Huffman, vì sự dư thừa này trong việc tạo ra các lần thử tra cứu có thể được phát hiện bằng phân tích thống kê.


Tôi chấp nhận đoạn đầu tiên: bạn giải thích tại sao LZ để lại sự dư thừa. Nhưng đoạn thứ hai dường như là một bước nhảy vọt: Tại sao Huffman lại bắt được sự dư thừa này? Tại sao không LZ nữa? Và, nếu Huffman toàn diện hơn, tại sao không bắt đầu với nó?
SRobertJames

2

Có lẽ tôi không theo dõi được ở đây, nhưng mã hóa Huffman nhìn vào toàn bộ đầu vào để xây dựng bảng mã hóa (cây), trong khi Lempel-Ziv mã hóa khi nó đi cùng. Đây vừa là lợi thế vừa là nhược điểm của Huffman. Sự không hài lòng là đáng ghét, cụ thể là chúng ta phải xem toàn bộ đầu vào trước khi chúng ta có thể bắt đầu. Ưu điểm là Huffman sẽ tính đến các số liệu thống kê xảy ra ở bất kỳ đâu trong đầu vào, trong khi Lempel-Ziv phải xây dựng dần dần. Hoặc nói theo một cách khác, Lempel-Ziv có một "hướng" mà Huffman không có.

Nhưng tất cả điều này chỉ là cách ngây thơ của tôi để tưởng tượng mọi thứ như thế nào. Chúng ta sẽ cần một bằng chứng thực sự ở đây để xem chính xác Huffman vượt trội hơn Lempel-Ziv như thế nào.


2
Mọi người đã định nghĩa mã hóa Huffman thích ứng, chỉ nhìn vào đầu vào một lần. Đối với mục đích của cuộc thảo luận này, mã hóa Huffman thích ứng và không thích ứng sẽ hoạt động khá giống nhau.
Peter Shor

2

Câu trả lời ngắn gọn là, LZ là một thuật toán "phổ quát" ở chỗ nó không cần biết phân phối chính xác của nguồn (chỉ cần giả định rằng nguồn đó là ổn định và ergodic). Nhưng Huffman thì không; nó cần biết phân phối chính xác từ đó nguồn được lấy mẫu (để tạo cây Huffman). Thông tin bổ sung này làm cho Huffman đạt được các đảm bảo nén chặt chẽ. Tuy nhiên, đối với các thuật toán nén tệp thực tế, Huffman có thể ít thuận lợi hơn vì trước tiên nó sẽ cần thu thập số liệu thống kê thực nghiệm của tệp và sau đó thực hiện nén thực tế trong nửa sau, trong khi LZ có thể được thực hiện trực tuyến.

Thông tin chi tiết có thể được tìm thấy trong các văn bản lý thuyết thông tin tiêu chuẩn, ví dụ, Các yếu tố của Lý thuyết thông tin của Cover và Thomas.


Tôi nghĩ rằng nguồn ergodic đứng yên chỉ là một giả định giúp LZ dễ dàng phân tích hơn. Rốt cuộc, việc nén dựa trên các thuộc tính tổ hợp của đầu vào, điều này xảy ra trùng khớp độc đáo với các thuộc tính thống kê trong nhiều trường hợp. Ví dụ, hãy xem xét một tập hợp các văn bản tiếng Anh ở định dạng văn bản thuần túy, theo sau là các văn bản tương tự ở định dạng HTML. LZ nén bộ sưu tập này khá độc đáo, mặc dù nó không giống như thứ gì đó được tạo ra bởi một nguồn ergodic cố định.
Jouni Sirén

@Jouni: Tôi sẽ không đồng ý với nhận xét này; Tôi nghĩ rằng ở một khía cạnh nào đó, ngôn ngữ tiếng Anh văn bản đơn giản trông rất giống một nguồn ergodic cố định, và sự giống nhau này chính xác là những gì LZ đang tận dụng.
Peter Shor

@Peter: Nhưng trong trường hợp này, trước tiên nguồn tạo ra một số văn bản ở định dạng văn bản thuần túy, sau đó chính xác là cùng một văn bản ở định dạng HTML. Sự thay đổi này từ văn bản đơn giản sang HTML tại một số điểm tùy ý dường như phá vỡ thuộc tính văn phòng phẩm. Mặt khác, kết quả nén tốt hơn nhiều so với khi nén riêng các văn bản thuần túy và văn bản HTML, vì có nhiều thông tin lẫn nhau giữa một văn bản ở định dạng văn bản thuần và cùng một văn bản ở định dạng HTML.
Jouni Sirén
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.