Magic Bookof Algorithms EN

StatistikSTA-01

Benfords Gesetz

Echte Zahlen fangen viel öfter mit einer 1 an, als man denkt. Wer welche erfindet, weiß das nicht.

Laufzeit
O(n)
Formel
P(d) = log10(1 + 1/d)
Führende 1
30,1 % statt 11,1 %
Prüfgröße
Chi-Quadrat, Grenze 15,51

01Worum es geht

Man würde erwarten, dass jede Ziffer gleich oft am Anfang einer Zahl steht, also jede in etwa 11 Prozent der Fälle. Bei Zahlen, die gewachsen sind — Rechnungsbeträge, Einwohnerzahlen, Flusslängen, Aktienkurse — stimmt das nicht. Dort führt die 1 in gut 30 Prozent der Fälle und die 9 in weniger als 5. Das ist Benfords Gesetz, und es ist kein Kuriosum: Es ist eine der wenigen Regeln, die aus einer bloßen Zahlenliste etwas über ihre Entstehung verraten.

Aufgefallen ist das zuerst Simon Newcomb im Jahr 1881, und zwar an abgegriffenem Papier: Die vorderen Seiten der Logarithmentafeln in der Bibliothek waren deutlich stärker benutzt als die hinteren. Frank Benford hat es 1938 an 20 Datensätzen mit über 20 000 Zahlen nachgemessen, von Molekulargewichten bis zu Hausnummern.

Praktisch wird das Gesetz, weil sich niemand ausdenken kann, was er nicht weiß. Wer Beträge erfindet, verteilt sie gleichmäßig — und fällt damit auf.

130,1 %
217,6 %
312,5 %
49,7 %
57,9 %
66,7 %
75,8 %
85,1 %
94,6 %
Die erwartete Verteilung der führenden Ziffer, berechnet mit derselben Formel wie im Code unten.

02So funktioniert es

Die Formel

Die erwartete Häufigkeit der führenden Ziffer d ist

P(d) = log10(1 + 1/d)

Das ergibt 30,1 % für die 1, 17,6 % für die 2 und so weiter bis 4,6 % für die 9. Die neun Werte ergeben zusammen genau 1, denn die Summe der Logarithmen teleskopiert zu log10(10/1).

Warum ausgerechnet der Logarithmus

Der eigentliche Grund heißt Skaleninvarianz. Eine Verteilung von Beträgen sollte nicht davon abhängen, ob in Euro oder in Dollar gerechnet wird. Rechnet man alle Zahlen mit einem festen Faktor um, verschieben sich ihre führenden Ziffern — und es gibt genau eine Verteilung, die dabei unverändert bleibt: die logarithmische von oben.

Anschaulich: Trägt man die Zahlen auf einer logarithmischen Achse auf, dann liegen sie dort gleichmäßig. Auf dieser Achse ist der Abschnitt von 1 bis 2 aber viel länger als der von 9 bis 10 — genau um den Faktor, den die Formel angibt.

Dazu kommt ein zweiter Effekt: Produkte mehrerer unabhängiger Faktoren landen von selbst bei Benford. Multiplizieren heißt auf der logarithmischen Achse addieren, und Summen vieler Zufallsgrößen verteilen sich immer breiter — je breiter, desto genauer stimmt das Gesetz. Deshalb passen Rechnungsbeträge (Menge mal Preis mal Aufschlag) so gut, während Körpergrößen es nie tun.

Zählen und vergleichen

Der Rest ist Buchhaltung. LeadingDigit schiebt eine Zahl so lange um Zehnerpotenzen, bis sie zwischen 1 und 10 liegt, Count zählt die neun Ziffern durch. Was fehlt, ist ein Maß dafür, ob eine Abweichung noch Zufall sein kann.

Chi-Quadrat

Das leistet der Chi-Quadrat-Anpassungstest: Jede Abweichung zwischen gezählt und erwartet wird quadriert (damit wenige große mehr wiegen als viele kleine) und durch den Erwartungswert geteilt (damit seltene Ziffern nicht überbewertet werden).

X² = Summe (beobachtet − erwartet)² / erwartet

Bei neun Ziffern hat der Test acht Freiheitsgrade. Die Grenzen dort:

  • Acht Freiheitsgrade, also die Ziffern 1 bis 9: 15,51 bei 95 %, 20,09 bei 99 %.
  • Neun Freiheitsgrade, also die Ziffern 0 bis 9: 16,92 bei 95 %, 21,67 bei 99 %.

Ein Wert unter 15,51 ist bei neun Ziffern also unauffällig: So viel Abweichung erzeugt der reine Zufall in 19 von 20 Fällen. Wichtig dabei: Chi-Quadrat wächst mit der Anzahl der Zahlen. Bei 100 000 Datensätzen schlägt schon eine winzige, harmlose Schieflage aus.

03Ausprobieren

04Implementierung

MagicBook.Algorithms/Statistics/Benford.csC#
// Zahlen, die von selbst gewachsen sind - Rechnungsbeträge, Einwohnerzahlen, Aktienkurse -
// fangen nicht mit allen neun Ziffern gleich oft an. Die 1 führt in etwa 30 Prozent der
// Fälle, die 9 in weniger als 5. Der Grund: Solche Zahlen liegen gleichmäßig auf einer
// logarithmischen Skala, und dort ist der Abschnitt von 1 bis 2 viel länger als der
// von 9 bis 10. Wer Zahlen erfindet, weiß das nicht.
public static class Benford
{
    // Wie oft die Ziffer erwartungsgemäß führt. Das ist das ganze Gesetz.
    public static double Share(int digit)
    {
        ArgumentOutOfRangeException.ThrowIfLessThan(digit, 1);
        ArgumentOutOfRangeException.ThrowIfGreaterThan(digit, 9);

        return Math.Log10(1 + 1.0 / digit);
    }

    // Die neun erwarteten Anteile in einer Reihe, bereit zum Vergleich mit einer Zählung.
    public static double[] Shares() => [.. Enumerable.Range(1, 9).Select(Share)];

    // Die führende Ziffer einer Zahl. Größe und Vorzeichen spielen keine Rolle: 0,00734 und
    // -73400 fangen beide mit einer 7 an.
    public static int LeadingDigit(double number)
    {
        var value = Math.Abs(number);

        if (value == 0 || double.IsNaN(value) || double.IsInfinity(value))
            throw new ArgumentOutOfRangeException(nameof(number), "This number has no leading digit.");

        while (value >= 10)
            value /= 10;

        while (value < 1)
            value *= 10;

        return (int)value;
    }

    // Wie oft jede Ziffer von 1 bis 9 führt. Der erste Eintrag gehört zur 1.
    // Nullen haben keine führende Ziffer und bleiben außen vor.
    public static int[] Count(IEnumerable<double> numbers)
    {
        var counts = new int[9];

        foreach (var number in numbers)
        {
            if (number != 0)
                counts[LeadingDigit(number) - 1]++;
        }

        return counts;
    }

    // Chi-Quadrat misst, wie weit eine Zählung von der Erwartung entfernt ist: Jede Abweichung
    // wird quadriert, damit wenige große mehr wiegen als viele kleine, und dann durch den
    // Erwartungswert geteilt, damit seltene Ziffern nicht zu streng bewertet werden.
    // Null heißt perfekte Übereinstimmung, je größer der Wert, desto verdächtiger die Daten.
    public static double ChiSquare(int[] counts, double[] shares)
    {
        if (counts.Length != shares.Length)
            throw new ArgumentException("There has to be one expected share per count.", nameof(shares));

        var total = counts.Sum();
        var sum = 0.0;

        for (var i = 0; i < counts.Length; i++)
        {
            var expected = total * shares[i];
            var difference = counts[i] - expected;

            sum += difference * difference / expected;
        }

        return sum;
    }
}

05Zahlen, die niemand erfunden hat

MagicBook.Console/Examples/BenfordExample.csC#
// Zwei Reihen, die niemand erfunden hat: die Zweierpotenzen und die Fibonacci-Zahlen.
// Beide wachsen durch Multiplikation, und genau um solche Zahlen geht es in dem
// Gesetz.
var powers = new List<double>();
var fibonacci = new List<double>();

var power = 1.0;
double previous = 1, current = 1;

for (var i = 0; i < 500; i++)
{
    powers.Add(power);
    power *= 2;

    fibonacci.Add(previous);
    (previous, current) = (current, previous + current);
}

var powerCounts = Benford.Count(powers);
var fibonacciCounts = Benford.Count(fibonacci);

Console.WriteLine("digit  expected  powers of two  fibonacci");

for (var digit = 1; digit <= 9; digit++)
{
    Console.WriteLine(
        $"{digit,5}  {Benford.Share(digit),7:0.0%}  " +
        $"{powerCounts[digit - 1] / 500.0,12:0.0%}  {fibonacciCounts[digit - 1] / 500.0,9:0.0%}");
}

// Chi-Quadrat sagt in einer Zahl, wie weit eine Zählung von der Erwartung abweicht.
// Unter 15,51 ist die Abweichung das, was der reine Zufall in 19 von 20 Fällen erzeugt.
Console.WriteLine();
Console.WriteLine($"chi-square, powers of two: {Benford.ChiSquare(powerCounts, Benford.Shares()),6:0.00}");
Console.WriteLine($"chi-square, fibonacci:     {Benford.ChiSquare(fibonacciCounts, Benford.Shares()),6:0.00}");
Ausgabe der Konsole
digit  expected  powers of two  fibonacci
    1    30.1%         30.2%      30.2%
    2    17.6%         17.6%      17.6%
    3    12.5%         12.4%      12.6%
    4     9.7%          9.8%       9.4%
    5     7.9%          7.8%       8.0%
    6     6.7%          6.8%       6.6%
    7     5.8%          5.6%       5.8%
    8     5.1%          5.2%       5.4%
    9     4.6%          4.6%       4.4%

chi-square, powers of two:   0.07
chi-square, fibonacci:       0.17

06Ein Kassenbuch, das nicht stimmt

MagicBook.Console/Examples/BenfordCashBookExample.csC#
const int entries = 500;

var random = new Pcg(20240921);

// Ein ehrliches Kassenbuch eines Großhändlers. Jede Summe ist eine Kette von Faktoren:
// so viele Kartons, so viele Stück je Karton, ein Preis je Stück und ein Aufschlag.
// Niemand wählt die Summe, sie fällt aus der Multiplikation heraus - und Produkte
// mehrerer unabhängiger Faktoren landen von selbst bei Benford.
int[] perBox = [6, 12, 24, 48];
var honest = new List<double>();

for (var entry = 0; entry < entries; entry++)
{
    var boxes = 1 + random.Next(12);
    var pieces = perBox[random.Next(perBox.Length)];
    var price = 0.20 + random.NextDouble() * 7.80;
    var markup = 1.0 + random.NextDouble() * 0.6;

    honest.Add(Math.Round(boxes * pieces * price * markup, 2));
}

// Das andere Kassenbuch ist erfunden. Ein Mensch schreibt Beträge auf, die harmlos
// wirken: nichts zu Kleines, nichts zu Großes, und eher 47 oder 63 als eine
// runde 50, weil runde Beträge verdächtig wirken.
int[] favourites = [3, 4, 6, 7, 8];
var invented = new List<double>();

for (var entry = 0; entry < entries; entry++)
{
    var euros = (2 + random.Next(8)) * 10 + favourites[random.Next(favourites.Length)];

    invented.Add(euros + (random.Next(2) == 0 ? 0 : 0.5));
}

// Die führende Ziffer soll Benford folgen, die Euro-Ziffer soll gleichmäßig verteilt
// sein: jede der zehn Ziffern etwa ein Zehntel der Fälle.
var evenly = Enumerable.Repeat(0.1, 10).ToArray();

Console.WriteLine("cash book   leading digit   euro digit");

foreach (var (name, book) in new[] { ("honest", honest), ("invented", invented) })
{
    Console.WriteLine(
        $"{name,-9}   {Benford.ChiSquare(Benford.Count(book), Benford.Shares()),13:0.0}   " +
        $"{Benford.ChiSquare(EuroDigits(book), evenly),10:0.0}");
}

Console.WriteLine();
Console.WriteLine("chance alone stays below 15.5 and 16.9 in 19 out of 20 cases");

// Wie oft jede Ziffer direkt vor dem Komma steht.
static int[] EuroDigits(IEnumerable<double> amounts)
{
    var counts = new int[10];

    foreach (var amount in amounts)
        counts[(int)amount % 10]++;

    return counts;
}
Ausgabe der Konsole
cash book   leading digit   euro digit
honest                6.5          7.0
invented            366.6        504.6

chance alone stays below 15.5 and 16.9 in 19 out of 20 cases

07Gut zu wissen

  • Wo das Finanzamt es einsetzt. In der digitalen Betriebsprüfung (Datenzugriff nach § 147 Abs. 6 AO) läuft die Ziffernanalyse als Vorprüfung: Benford auf die führenden Ziffern, Chi-Quadrat auf die letzten Ziffern vor dem Komma, wo echte Gleichverteilung erwartet wird. Das zweite Beispiel macht genau diese beiden Tests. Wer Beträge erfindet, hat unbewusst Lieblingszahlen und meidet runde Beträge, weil die verdächtig wirken.
  • Ein Indiz, kein Beweis. Nach der Rechtsprechung von BFH und Finanzgerichten kann die Ziffernanalyse allein die Vermutung ordnungsmäßiger Buchführung (§ 158 AO) nicht erschüttern. Sie verschiebt den Prüfungsschwerpunkt, mehr nicht. Das FG Düsseldorf nennt sie ein zulässiges Indiz, das für sich genommen keine Verwerfung der Buchführung trägt.
  • Wo das Gesetz nicht gilt. Vergebene Nummern (Postleitzahlen, Kontonummern, Telefonnummern), Zahlen aus einem engen Bereich (Körpergrößen, Schuhgrößen), Beträge mit harten Grenzen (Zuschüsse bis 500 €) und Preise mit ,99-Konvention. Auch bei Wahlergebnissen ist die Methode umstritten, weil Stimmenzahlen selten genug Größenordnungen überspannen.
  • Bekannte Fälle. Mark Nigrini hat das Verfahren in der Wirtschaftsprüfung etabliert. Untersucht wurden damit unter anderem die Bilanzen von Enron und die an Brüssel gemeldeten griechischen Defizitdaten.
  • Umgekehrt gilt es nicht. Daten, die zu Benford passen, sind nicht automatisch echt — wer das Gesetz kennt, kann seine Fälschungen daran anpassen. Deshalb prüfen Forensiker zusätzlich die letzten Ziffern, Duplikate und runde Beträge.