<?xml version="1.0"?>
<!-- name="generator" content="blosxom/2.0" -->
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
  <channel>
    <title>Notebooks   </title>
    <link>http://bactra.org/notebooks</link>
    <description>Cosma's Notebooks</description>
    <language>en</language>

  <item>
    <title>Complexity, Entropy and the Physics of &lt;tt&gt;gzip&lt;/tt&gt;</title>
    <link>http://bactra.org/notebooks/2003/12/02#cep-gzip</link>
    <description>




&lt;P&gt;Recently, a lot of papers have been published in the physics literature
where people try to use standard file-compression algorithms, particularly the
&lt;tt&gt;gzip&lt;/tt&gt; implementation of the Lempel-Ziv algorithm, to estimate the
algorithmic information content (a.k.a. Kolmogorov complexity) of data-sources,
and/or their entropy rates.  These are both very bad ideas. [I will add
references to the offending papers later.]  My apologies, before we go any
further, to the actual &amp;quot;complexity, entropy and physics of
information&amp;quot; group, which knows better than this!&lt;/P&gt;

&lt;P&gt;I wrote a dead-simple program which uses an additive pseudo-random number
generator to produce a sequence of ASCII characters, either 0 or 1.  The size
of the program, compiled on my desktop Linux box, was 15574 bytes.  This
includes a particular &lt;em&gt;fixed&lt;/em&gt; seed for the random number generator.  The
program took one input, which was the number of characters N to output, which
can be encoded in (approximately) log(N) bits.  So the algorithmic information
content of the output is at most 15574 + (1/8)log(N) bytes.  (All logarithms
are of course to base 2.)&lt;/P&gt;

&lt;P&gt;Having generated pseudo-random strings from this program, I then ran
&lt;tt&gt;gzip&lt;/tt&gt; on them.  One would hope for a compression ratio of approximately
1/8, at least for large strings, because ASCII uses eight bits per character,
whereas there are really only two possibilities in the output.  (A better
comparison would've been for me to write directly to a binary file, without
using ASCII, but I'm lazy; I'll get to that later.)  The original data can then
be regenerated from the combination of the compressed file and the
&lt;tt&gt;gunzip&lt;/tt&gt; program.  On my system, that program is 53716 bytes in size.
So the &quot;zipper&quot; estimate of the algorithmic information content of the output
of my pseudo-random number generator is as follows.  (I have rounded up all
fractions to the next largest byte, to try and reduce the advantage of the
actual generating program.)&lt;/p&gt;

&lt;center&gt; &lt;table&gt;
&lt;tr&gt;&lt;td align=center&gt;N&lt;/td&gt;&lt;td align=center&gt;gzip&lt;/td&gt;&lt;td&gt;generator&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^1&lt;/td&gt; &lt;td align=right&gt;53,760&lt;/td&gt; &lt;td align=right&gt;15,575&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^2&lt;/td&gt; &lt;td align=right&gt;53,793&lt;/td&gt; &lt;td align=right&gt;15,575&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^3&lt;/td&gt; &lt;td align=right&gt;53,959&lt;/td&gt; &lt;td align=right&gt;15,576&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^4&lt;/td&gt; &lt;td align=right&gt;55,409&lt;/td&gt; &lt;td align=right&gt;15,576&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^5&lt;/td&gt; &lt;td align=right&gt;69,686&lt;/td&gt; &lt;td align=right&gt;15,577&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^6&lt;/td&gt; &lt;td align=right&gt;212,641&lt;/td&gt; &lt;td align=right&gt;15,577&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^7&lt;/td&gt; &lt;td align=right&gt;1,643,233&lt;/td&gt; &lt;td align=right&gt;15,577&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^8&lt;/td&gt; &lt;td align=right&gt;15,949,691&lt;/td&gt; &lt;td align=right&gt;15,578&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;

&lt;P&gt;I didn't run it beyond that size, because my sysadmins would not be
especially happy with my producing a a gigabyte of garbage to prove this point;
some other time.&lt;/P&gt;

&lt;P&gt;What this shows is that, even with a hundred million data points,
&lt;tt&gt;gzip&lt;/tt&gt; is not very good &lt;em&gt;at all&lt;/em&gt; at finding a short compression
of what is, after all, a linear dynamical system with some fairly simply
nonlinearities added on top.  As an estimator of the Kolmogorov complexity, it
sucks rocks.&lt;/P&gt;

&lt;P&gt;Another purported use of &lt;tt&gt;gzip&lt;/tt&gt; is to estimate the entropy rate of
the source.  This is done either by dividing the length of the &lt;tt&gt;gzip&lt;/tt&gt;ped
output by N (call this the division methd), or as the incremental increase in
the length of the compressed file when increasing N by 1 (call this the
marginal method).  To be fair to the marginal method, one should really look at
the increase for an additional m characters, divided by m, so I do this for m =
10, m = 100 and m = 1000.  My pseudo-random number generator is periodic, so
its entropy rate is exactly 0.  Here is how both of these methods (&quot;division&quot;
and &quot;marginal&quot;, respectively) did at estimating 0 bytes per character (to three
decimal places, rounded):
&lt;/P&gt;


&lt;center&gt;&lt;table&gt;
&lt;tr&gt;&lt;td align=center&gt;N&lt;/td&gt; &lt;td align=center&gt;division&lt;/td&gt; &lt;td align=center&gt;marginal (m=10)&lt;/td&gt; &lt;td align=center&gt;(m=100)&lt;/td&gt; &lt;td align=center&gt;(m=1000)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^1&lt;/td&gt; &lt;td align=left&gt; 4.400&lt;/td&gt; &lt;td align=left&gt; 1.000&lt;/td&gt; &lt;td align=left&gt;0.400&lt;/td&gt; &lt;td align=left&gt;0.206&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^2&lt;/td&gt; &lt;td align=left&gt; 0.770&lt;/td&gt; &lt;td align=left&gt; 0.600&lt;/td&gt; &lt;td align=left&gt;0.250&lt;/td&gt; &lt;td align=left&gt;0.188&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^3&lt;/td&gt; &lt;td align=left&gt; 0.243&lt;/td&gt; &lt;td align=left&gt; 0.500&lt;/td&gt; &lt;td align=left&gt;0.210&lt;/td&gt; &lt;td align=left&gt;0.175&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^4&lt;/td&gt; &lt;td align=left&gt; 0.169&lt;/td&gt; &lt;td align=left&gt; 0.500&lt;/td&gt; &lt;td align=left&gt;0.210&lt;/td&gt; &lt;td align=left&gt;0.163&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^5&lt;/td&gt; &lt;td align=left&gt; 0.160&lt;/td&gt; &lt;td align=left&gt; 0.400&lt;/td&gt; &lt;td align=left&gt;0.200&lt;/td&gt; &lt;td align=left&gt;0.166&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^6&lt;/td&gt; &lt;td align=left&gt; 0.159&lt;/td&gt; &lt;td align=left&gt; 0.100&lt;/td&gt; &lt;td align=left&gt;0.200&lt;/td&gt; &lt;td align=left&gt;0.165&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^7&lt;/td&gt; &lt;td align=left&gt; 0.159&lt;/td&gt; &lt;td align=left&gt; 0.600&lt;/td&gt; &lt;td align=left&gt;0.180&lt;/td&gt; &lt;td align=left&gt;0.163&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^8&lt;/td&gt; &lt;td align=left&gt; 0.159&lt;/td&gt; &lt;td align=left&gt; 0.200&lt;/td&gt; &lt;td align=left&gt;0.160&lt;/td&gt; &lt;td align=left&gt;0.161&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;/center&gt;

&lt;P&gt;Note that even if one pretended this was a genuine source of independent,
identically-distributed coin flips, the entropy rate should be 0.125 bytes per
character, not approximately 0.16 bytes.  It is exceedingly improbably that
I've generated a sample which happens to look like it has an entropy rate that
high.  (Back of the envelope large deviations calculation: the entropy of the
empirical distribution relative to the true one would be on the order of
0.159-0.125 = 0.034 bytes per symbol, or 0.272 bits, so the probability would
be approximately 2^(-0.272 N) = 10^(-0.082 N) for large N.  This is a little
dodgy because I should really search for the relative-entropy-minimizing
distribution, but, again, this is a first cut.)  Now, Lempel-Ziv did prove
that, asymptotically, the compressed length divided by the number of characters
will be no larger than the entropy rate.  So the division method, at least,
should asymptote to the entropy rate, and you can persuade yourself that this
means the marginal method then should converge too.  But the key word here,
again and again, is &lt;em&gt;asymptotically&lt;/em&gt;: we have here a hundred million
data points, but are evidently very, very far from the asymptote.  I for one do
not find it plausible that vastly smaller empirical data sets reach the
asymptotic regime.&lt;/P&gt;

&lt;P&gt;There are, of course, other ways of measuring quantities like the entropy
rate.  As it happens, I was involved in writing a program (&lt;a
href=&quot;http://bactra.org/CSSR/&quot;&gt;CSSR&lt;/a&gt;) for building hidden Markov models from
sequential data, and part of the output of the program is a calculation of the
entropy rate.  Here is what CSSR gives when it's configured to just fit a
simple Markov chain to the data (Lmax = 1); results aren't notably different if
I allow it to seek higher-order models.&lt;/P&gt;

&lt;center&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td align=center&gt;N&lt;/td&gt; &lt;td align=center&gt;CSSR&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^1&lt;/td&gt; &lt;td align=left&gt; 0.118682&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^2&lt;/td&gt; &lt;td align=left&gt; 0.123229&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^3&lt;/td&gt; &lt;td align=left&gt; 0.124990&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^4&lt;/td&gt; &lt;td align=left&gt; 0.124999&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^5&lt;/td&gt; &lt;td align=left&gt; 0.125000&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^6&lt;/td&gt; &lt;td align=left&gt; 0.125000&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^7&lt;/td&gt; &lt;td align=left&gt; 0.125000&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10^8&lt;/td&gt; &lt;td align=left&gt; 0.125000&lt;/td&gt;&lt;/tr&gt;	
&lt;/table&gt;
&lt;/center&gt;

&lt;P&gt;The point, of course, is not that Lempel-Ziv is a bad compression algorithm
--- it's not! --- but that it was never designed to be used to estimate entropy
rates (which can be done better using other tools) or algorithmic complexities
(which in generally cannot be done).  The best screwdriver in the world makes
a very bad butter-knife.&lt;/P&gt;

&lt;P&gt;A possible objection is that a pseudorandom number generator is, of course,
hard, and gives a much more convincing appearance of having no structure
than one might expect from typical data-sets.  So, at some convenient
later time, I'm going to try to supplement these (elementary) results with
ones from some non-trivial dynamical system, and show that &lt;tt&gt;gzip&lt;/tt&gt;
doesn't do any better there, either.&lt;/P&gt;

&lt;P&gt;&lt;strong&gt;Update, 2 December 2003:&lt;/strong&gt; There has been a surprisingly
large (and positive) response to this.  Matthew Berryman points out that
&lt;tt&gt;gzip&lt;/tt&gt; includes some metadata in its compressed files, which presumably
should be discounted; very true, but it won't affect the results substantially.
More seriously, he reminds me that the Lempel-Ziv convergence result requires
not just that the length of the data set grow without bound, but that the
length of the phrases into which it is parsed must be unbounded, and that
&lt;tt&gt;gzip&lt;/tt&gt; is implemented with a fixed maximum phrase length, considerably
smaller than 10^8.  I hadn't realized there was a limit on the phrase length,
and suspect this is why the large-N entropy rate is so bad.  A different
implementation of Lempel-Ziv, without that limit, would do better at that, but
that doesn't help the published papers using &lt;tt&gt;gzip&lt;/tt&gt;, and it's still a
dumb thing to do.  Derek Abbott suggests that the whole issue could be avoided
by replacing Shannon entropy with gz entropy, defined as the result of applying
&lt;tt&gt;gzip.&lt;/tt&gt; This elegant suggestion &amp;quot;has all the advantages of theft
over honest toil&amp;quot;, and accordingly I urge Derek to submit it to
&lt;cite&gt;Physical Review Letters&lt;/cite&gt; before somebody beats him to this prize.
Kirk Stork wants to know what kind of results I'd get on the random bytes
available from &lt;a href=&quot;http://www.random.org/&quot;&gt;random.org&lt;/a&gt;, produced by
sampling actual atmospheric noise; I'll post those here once I do that.
Several people suggested using the logistic map at parameter settings where the
true entropy rate is known (to some accuracy); this will be easy.  Finally, a
number of people, whose names I elide out of courtesy, suggested replicating
this analysis on the output of the &lt;a
href=&quot;http://www.elsewhere.org/cgi-bin/postmodern/&quot;&gt;postmodernism
generator&lt;/a&gt;.&lt;/P&gt;


&lt;ul&gt;To read:
	&lt;li&gt;Pau Amengual and Raul Toral, &quot;Parrondo's games and the zipping
algorithm&quot;,
&lt;a href=&quot;http://arxiv.org/abs/cond-mat/0402515&quot;&gt;cond-mat/0402515&lt;/a&gt;
	&lt;/ul&gt;
</description>
  </item>
  </channel>
</rss>