Stránka 1 z 2

Benfordův zákon

Napsal: 24 črc 2012, 14:21
od DRAKE
Na wikipedii jsem objevil zajímavý statistický zákon.

Čtěte:
http://cs.wikipedia.org/wiki/Benford%C5%AFv_z%C3%A1kon

Rozhodl jsem se, že tvrzení ověřím, a tak jsem napsal kód v Csharpu, který generuje náhodná čísla a dívá se čím začínají. Vyšlo mi, že 51 procent všech náhodně generovaných čísel začínalo jedničkou. Velmi zajímavé a těžko vysvětlitelné.

Kód:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BenfordsLaw
{
class Program
{

static private bool StartsWithOne(int i)
{
string str = i.ToString();
if (str[0] == '1') return true;
return false;
}

static private void CountBenford()
{
const int count = 100000000;
int onecount = 0;
Random r = new Random();


for (int i = 0; i < count; i++)
{
if (StartsWithOne(r.Next())) onecount++;
}

Console.WriteLine(((double)onecount/count * 100).ToString());
}


static void Main(string[] args)
{
CountBenford();
Console.ReadKey();
}
}
}

Napsal: 24 črc 2012, 14:30
od DRAKE
Tak tady mám kompletní výsledky:

1-> 51,906%
2-> 12,115%
3-> 5,15%
4-> 5,113%
5-> 5,186%
6-> 5,297%
7-> 5,129%
8-> 5,196%



Generující kód:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BenfordsLaw
{
class Program
{

static private bool StartsWithOne(int i, int x)
{
string str = i.ToString();
if (str[0] == (char)(x+0x30)) return true;
return false;
}

static private void CountBenford(int x)
{
const int count = 100000000;
int onecount = 0;
Random r = new Random();


for (int i = 0; i < count; i++)
{
if (StartsWithOne(r.Next(),x)) onecount++;
}

Console.WriteLine(x.ToString() + "-> " +((double)onecount/count * 100).ToString()+"%");
}


static void Main(string[] args)
{
for (int i = 1; i < 9; i++)
{
CountBenford(i);
}

Console.ReadKey();
}
}
}

Napsal: 24 črc 2012, 14:49
od rnbw
Dokazal si velky nezmysel. Bud mas chybu v programe (aky je rozsah generovanych cisel?) alebo ma M$ blby generator nahodnych cisel.

Kód: Vybrat vše

$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    srandom(1234);

    for (int i = 0; i < 10000000; i++) {
        int n = (float)random() / RAND_MAX * 1000000;
        printf("%d\n", n);
    }

    return 0;
}
$ cc --std=gnu99 -Wall test.c -o test
$ ./test >asdf
$ grep ^1 asdf | wc -l
1111613
$ grep ^2 asdf | wc -l
1111853
$ grep ^3 asdf | wc -l
1110788
$ grep ^4 asdf | wc -l
1111027
$ grep ^5 asdf | wc -l
1111112
$ grep ^6 asdf | wc -l
1110697
$ grep ^7 asdf | wc -l
1110756
$ grep ^8 asdf | wc -l
1112192
$ grep ^9 asdf | wc -l
1109942

Napsal: 24 črc 2012, 14:58
od Andrea
To máš nějaký divný generátor náhodných čísel. V matlabu to vychází rovnoměrně.

Napsal: 24 črc 2012, 14:59
od DRAKE
to platí pro normální rozdělení, ne pro rovnoměrné

Napsal: 24 črc 2012, 15:03
od DRAKE
je to C# na 64 bitovým intelu

Napsal: 24 črc 2012, 15:04
od DRAKE
rnbw

Ty tam násobíš a dělíš, já ne.

Napsal: 24 črc 2012, 15:57
od Andrea
DRAKE píše:rnbw

Ty tam násobíš a dělíš, já ne.
Stejnak to máš blbě ty, generuješ náhodná čísla od 0 do 255, tak to by bylo, aby tam 1 na začátku nebyla nejčastějc, pak dvojka a všechno ostatní stejně často. :roll:

Napsal: 24 črc 2012, 16:22
od gombik
Andrea: pokud narážíš na metodu Random.Next(), kterou použil DRAKE, tak ta generuje čísla od 0 po Int32.MaxValue

http://msdn.microsoft.com/en-us/library/9b3ta19y.aspx

Napsal: 24 črc 2012, 16:53
od DRAKE
Tak ten program je blbě, protože int.MaxValue je 2147483647. Čísla začínající na 1čku tvoří největší část prostoru.

Tento zákon platí pro normální rozdělní. PC generátor generuje rovnoměrné.

Skusím to s generátorem normálního rozdělení.

Napsal: 24 črc 2012, 16:55
od tomasjedno
DRAKE píše: Rozhodl jsem se, že tvrzení ověřím, a tak jsem napsal kód v Csharpu
Jediné, co takovým způsobem můžeš ověřit, je, zda takto generovaný soubor patří mezi ty, pro které ten "zákon" platí.
Kdybys volný čas věnoval přečtení téhož hesla na anglické Wiki, dozvěděl by ses tam, proč mezi ně nepatří.
Ten zákon platí pro soubory čísel, která jsou rovnoměrně rozeseta přes několik řádů na logaritmické škále.

Hezký příklad souboru, pro který neplatí Benfordův zákon, jsou čísla ve dvojkové soustavě. S výjimkou nuly všechna ostatní čísla začínají jedničkou :D

Edit: to jsem to zkonil - právě že pro ta dvojková čísla platí (Benfordův zákon zobecněný pro nedesítkové číselné soustavy).

Napsal: 24 črc 2012, 17:02
od DRAKE
Tak u dvojkový je to jasný. Ale proč to u desítkové je zrovna jednička. Proč né třeba sedmička?

Napsal: 24 črc 2012, 17:14
od tomasjedno
Protože na logaritmické škále je úsečka 1-2 mnohem delší, než úsečka 7-8 :D

Mimochodem k tvému tvrzení o platnosti pro normální rozdělení - citace z Wiki:
Neither the normal distribution and the ratio distribution of two normal distributions (the Cauchy distribution) obey Benford's law.

Když už si budeš hrát s tím normálním rozdělením, doporučil bych ti třeba normální rozdělení se střední hodnotou 5,5 a rozptylem 1. Možná, že tu a tam na nějaké číslo začínající 1 narazíš.

Napsal: 24 črc 2012, 20:33
od mtajovsky
DRAKE píše:Na wikipedii jsem objevil zajímavý statistický zákon.
Tak tohle je spíš zákon sociologický nebo nějaký biologický než statistický. To nemůžete ověřovat generátorem náhodných čísel. Trochu jsem se s tím v minulosit zábýval a dobré generátory náhodných čísel (fyzikální) mají odchylky od ideálního náhodného signálu řádu 10^-7. Testuje se to na rozdělení bitů mezi 0 a 1, na výskyt bitových posloupností délky 2-9 bitů a tak podobně.

Napsal: 24 črc 2012, 20:40
od Andrea
Co je to ideální náhoda? Nezáleží ten ideál trochu na tom, jestli jde o náhodu výhry ve Sportce nebo o náhodu zásahu meteoritem? :twisted: :twisted: :twisted: