Kerekítési hibák az átmenet során

Bajorországban a \(2{,}33\) átlagos osztályzat igazolja a gimnáziumba \(2{,}34\) nem. Ennél az éles határvonalnál két kerekítési művelet sorrendje határozhatja meg, hogy egy gyermek melyik oldalra kerül. Günther Felbinger egy blogbejegyzésben tárgyalja ennek a kerekítési hatásnak a lehetséges következményeit . Pusztán érdeklődésből én magam is kiszámítottam a hatásokat a modellben megengedett összes évfolyam-kombinációra.


A központi kérdésem a következő: Milyen gyakran vezet a teljes tantárgyi jegyekre kerekítés korai változata eltérő iskolai számításokhoz, mint a kerekítetlen tantárgyi átlagokat használó számítások? Továbbá érdekes lenne látni, hogy mi változik, ha az egyes tantárgyak átlagait (ahogyan ott javasolták) kezdetben csak egy tizedesjegyre kerekítik.

A bajor általános iskolai szabályzat 6. szakasza szerint az átlagjegyet a német, a matematika, valamint a helyi és általános tanulmányok jegyeiből számítják ki. A végrehajtási rendeletek \(2{,}33\) , \(2{,}66\) ban határozzák meg a határértékeket. A következő számítási modellben minden összesített átlagot két tizedesjegyre csonkolnak, és nem kerekítenek újra. Így például...

\[
\frac{2{,}33+2{,}34+2{,}34}{3}=2{,}3366\ldots \longrightarrow 2{,}33.
\]

Ez kulcsfontosságú az osztályozás szempontjából: \(2{,}3366\ldots\) nem \(2{,}34\) lesz, hanem \(2{,}33\) , és ezért továbbra is elegendő a gimnázium számára.

A kezdeti bejegyzés a korai kerekítést szemlélteti a feltételezett tantárgyspecifikus átlagértékekkel: \(1{,}6\) , \(2{,}6\) és \(2{,}6\) . Ezekből először a teljes jegyeket származtatjuk: \(2\) , \(3\) és \(3\) . Ezek átlaga:

\[
\frac{2+3+3}{3}=2{,}6666\ldots \longrightarrow 2{,}66,
\]

ami azt jelenti, hogy a diák nem jogosult közvetlen felvételre a gimnáziumba. Egész osztályzatokra kerekítés nélkül azonban a hipotetikus példában az eredmény a következő lenne...

\[
\frac{1{,}6+2{,}6+2{,}6}{3}=2{,}2666\ldots \longrightarrow 2{,}26.
\]

A második példában a kerekítés fordított irányban működik: \(2{,}4\) , \(3{,}4\) és \(2{,}4\) a teljes hangjegyértékek lesznek, \(2\) , \(3\) és \(2\) , hivatalosan \(2{,}33\) . A kerekítetlen értékek azonban \(2{,}73\) -at eredményeznek. A példák világosan bemutatják a hatást. Azonban még nem mutatják meg, hogy milyen gyakran fordul elő, vagy milyen következményekkel járna egy másik kerekítési módszer.

Ezért a számításomhoz egy tiszta eredményteret használok. Minden egyes átlag lehet az abban található \(501\) értékek egyike.

\[
1{,}00,\, 1{,}01,\, 1{,}02,\, \ldots, \, 5{,}99, \, 6{,}00
\]

Tegyük fel. A német, a matematika, valamint a helyi és általános tanulmányok rendezett kombinációit egyenlően súlyozom. Így vannak

\[
501^3=125\,751\,501
\]

Esetek. A modell tehát egyértelmű, de mesterséges: egyenlően elosztott tantárgyi átlagokat, a három tantárgy függetlenségét és pontosan százados lépésközöket feltételez. Nem tükrözi a bajor általános iskolás gyerekek tényleges eloszlását.

Három alany esetén \(d,m,h\) -t írunk

\[
A(d,m,h)=\frac{\left\lfloor 100\cdot\frac{d+m+h}{3}\right\rfloor}{100}
\]

a két tizedesjegyre csonkolt összesített átlaghoz. Most összehasonlítunk három számítási módszert.:

\[
igazítva
A_0 &= A(\operátornév{kör}(d),\operátornév{kör}(m),\operátornév{kör}(h)),\\
A_1 &= A(\operátornév{kör}_1(d),\operátornév{kör}_1(m),\operátornév{kör}_1(h)),\\
A_\mathrm{hivatkozás} &= A(d,m,h).
igazítva
\]

\(A_0\) az egész jegyekkel számított számításnak, \(A_1\) az egy tizedesjegyre kerekített ajánlatnak, \(A_\mathrm{ref}\) pedig a modellen belüli kerekítés nélküli hivatkozásnak felel meg. A számítás közvetlenül megvalósítható például a Rustban .:

const SCHOOL_GYMNASIUM: i32 = 0;
const SCHOOL_REALSCHULE: i32 = 1;
const SCHOOL_MITTELSCHULE: i32 = 2;
const FLOAT_TOLERANCE: f64 = 1e-9;

#[derive(Clone, Copy, Default)]
struct Statistic {
    conflict_count: u64,
    total_count: u64,
}

fn determine_school(average: f64) -> i32 {
    if average <= 2.33 {
        return SCHOOL_GYMNASIUM;
    }
    if average <= 2.66 {
        return SCHOOL_REALSCHULE;
    }
    SCHOOL_MITTELSCHULE
}

fn calculate_average(note_deutsch: f64, note_mathe: f64, note_hsu: f64) -> f64 {
    let average = (note_deutsch + note_mathe + note_hsu) / 3.0;
    ((average + FLOAT_TOLERANCE) * 100.0).floor() / 100.0
}

fn round_to_whole_grade(grade: f64) -> f64 {
    grade.round()
}

fn round_to_one_decimal(grade: f64) -> f64 {
    (grade * 10.0).round() / 10.0
}

fn normalize_grade(grade: f64) -> f64 {
    (grade * 100.0).round() / 100.0
}

fn percentage(count: u64, total: u64) -> f64 {
    count as f64 / total as f64 * 100.0
}

fn main() {
    let mut combination_count = 0;
    let mut official_reference_conflicts = 0;
    let mut official_proposal_conflicts = 0;
    let mut proposal_reference_conflicts = 0;
    let mut statistics = [Statistic::default(); 4];

    let mut note_deutsch = 1.0;
    while note_deutsch <= 6.0 {
        let mut note_mathe = 1.0;
        while note_mathe <= 6.0 {
            let mut note_hsu = 1.0;
            while note_hsu <= 6.0 {
                combination_count += 1;

                let official_average = calculate_average(
                    round_to_whole_grade(note_deutsch),
                    round_to_whole_grade(note_mathe),
                    round_to_whole_grade(note_hsu),
                );
                let proposed_average = calculate_average(
                    round_to_one_decimal(note_deutsch),
                    round_to_one_decimal(note_mathe),
                    round_to_one_decimal(note_hsu),
                );
                let reference_average =
                    calculate_average(note_deutsch, note_mathe, note_hsu);
                let official_school = determine_school(official_average);
                let proposed_school = determine_school(proposed_average);
                let reference_school = determine_school(reference_average);

                if official_average == 3.0 {
                    statistics[0].total_count += 1;
                    if reference_school != SCHOOL_MITTELSCHULE {
                        statistics[0].conflict_count += 1;
                    }
                }
                if official_average == 2.66 {
                    statistics[1].total_count += 1;
                    if reference_school == SCHOOL_GYMNASIUM {
                        statistics[1].conflict_count += 1;
                    }
                }
                if official_average == 2.33 {
                    statistics[2].total_count += 1;
                    if reference_school != SCHOOL_GYMNASIUM {
                        statistics[2].conflict_count += 1;
                    }
                }
                if official_average == 2.66 {
                    statistics[3].total_count += 1;
                    if reference_school == SCHOOL_MITTELSCHULE {
                        statistics[3].conflict_count += 1;
                    }
                }

                if official_school != reference_school {
                    official_reference_conflicts += 1;
                }
                if official_school != proposed_school {
                    official_proposal_conflicts += 1;
                }
                if proposed_school != reference_school {
                    proposal_reference_conflicts += 1;
                }

                note_hsu = normalize_grade(note_hsu + 0.01);
            }
            note_mathe = normalize_grade(note_mathe + 0.01);
        }
        note_deutsch = normalize_grade(note_deutsch + 0.01);
    }

    println!(
        "official/reference: {}%",
        percentage(official_reference_conflicts, combination_count)
    );
    println!(
        "official/proposal: {}%",
        percentage(official_proposal_conflicts, combination_count)
    );
    println!(
        "proposal/reference: {}%",
        percentage(proposal_reference_conflicts, combination_count)
    );
    for (index, statistic) in statistics.iter().enumerate() {
        println!(
            "#{}: {}% ({}/{})",
            index + 1,
            percentage(statistic.conflict_count, statistic.total_count),
            statistic.conflict_count,
            statistic.total_count
        );
    }
}

A kis tűréshatár a calculate_average megakadályozza egy olyan értéket, mint \(2{,}67\) bináris float reprezentációja miatt tévesen úgy tekintették, \(2{,}669999\ldots\) el van vágva. normalize_grade Továbbá minden ciklusértéket századrendű rácsra redukál. Legalább két különböző lehetséges átlagérték létezik. \(1/300\) szétválasztva; a tolerancia \(10^{-9}\) ezért elég kicsi ahhoz, hogy ne változtasson semmilyen valós határesetet.

A program lefordítása és elindítása a következővel történik:

rustc -O calc.rs && ./calc

A program végigmegy az összes \(125\,751\,501\) kombináción, és visszaadja az eredményt.:

ÖsszehasonlításAdag
Teljes jegyek a kerekítetlen tantárgyi átlagokkal szemben\(10{,}4411\,\%\)
Egész osztályzatok a javaslathoz képest, egy tizedesjegyig\(10{,}1521\,\%\)
Egy tizedesjegyre pontosított ajánlat a kerekítetlen szakértői átlagokhoz képest\(0{,}6615\,\%\)

A központi érték számomra \(10{,}4411\,\%\): Tízből több mint egy esetben a korai, egész évfolyamokra kerekítés eltérő számított iskolatípust eredményez, mint a kerekítés nélküli referenciaérték. Ez az arány kizárólag a választott modellen belüli kerekítési hatást írja le.

Az egy tizedesjegyes szakértői átlagokra való áttérés az összes modell eset \(10{,}1521\,\%\) -ában eltérő osztályozást eredményezne az előző módszerhez képest. A harmadik összehasonlítás azonban kulcsfontosságú: a kerekítés nélküli referenciához képest az egy tizedesjegyes módszer az eltérő eseteknek csak \(0{,}6615\,\%\) hagyja. A referenciától való eltérés így csökken

\[
1-\frac{0{,}6615}{10{,}4411}\approx 93{,}7\,\%.
\]

Számomra pontosan ez a jelenlegi számítási módszer megkérdőjelezhető következménye: a feltételezett tantárgyspecifikus eredmények változatlanok maradnak; csak a kerekítés időpontja módosíthatja a kiszámított iskolatípust. Bár az egy tizedesjegyre történő számítás nem szünteti meg teljesen ezt a hatást, a modellen belül jelentősen csökkenti.

Ezek a számok azonban nem árulják el, hogy valójában hány gyermeket érint a probléma. Az osztályzatok nem feltétlenül mechanikusan kerekített átlagokként generálódnak, az akadémiai teljesítmény nem egyenletes eloszlású és nem is független, és az iskolatípus tényleges megválasztása sem kizárólag ettől a három adattól függ. Számításom egy konkrétabb kérdésre ad választ: Milyen gyakran változtatja meg a kerekítés a kiszámított osztályzatot, ha minden századérték-kombináció egyenlő valószínűséggel fordul elő?

Végül egy összehasonlítás az eredeti bejegyzéssel: Az ott említett összesített arány, körülbelül \(10\,\%\) közel van az én \(10{,}4411\,\%\) -omhoz. Számításaim azonban nem erősítik meg a négy egyedi esetet, amelyek mindegyikét \(1/6 \approx 17\,\%\) A „középiskolai tanulmányokat \(3{,}00\) -kal hagyta ki”, a „gimnáziumot \(2{,}33\) -kal mulasztotta el”, a „gimnáziumot \(2{,}66\) -kal teljesítette”, és a „középiskolai tanulmányokat \(2{,}66\) -kal teljesítette \(1{,}4615\,\%\) \(59{,}6096\,\%\) \(1{,}2023\,\%\) \(62{,}9395\,\%\) .

A négy érték feltételes valószínűség, eltérő méretű referenciacsoportokkal. Eltérően definiált mintavételi tér nélkül \(1/6\) nem származtatható belőlük. A számításom tehát megerősíti a kerekítési hatást, de nem ezeket az egyedi valószínűségeket. Mindenesetre az érintett gyermekek tényleges számára vonatkozó állításokhoz valós évfolyameloszlásokra és azok függőségeire lenne szükség.

Vissza