[PYTHON] Trouvez la «note de passage minimale» à partir de la «note moyenne des candidats», de la «note moyenne des candidats retenus» et de «l'agrandissement» de l'examen d'entrée

Objectif

Lors de la résolution des questions des examens d'entrée au collège, au lycée, à l'université, etc., le "score moyen des candidats", le "score moyen des candidats retenus" et le "multiplicateur (nombre de candidats retenus / nombre de candidats)" sont divulgués, mais le "score minimum de réussite" Peut être privé. Ici, nous envisageons de prédire la note de passage minimale.

Méthode

J'ai utilisé les données du concours d'entrée (2013-2019) du lycée M publiées sur le site suivant. Examen du lycée Gorogoro https://www.goro-goro.net/2019-musashi

Pour les données de chaque année, les opérations suivantes ont été effectuées avec le score moyen des candidats étant $ \ mu_a $, le score moyen des candidats retenus étant $ \ mu_p $ et le grossissement étant $ r $. (Chaque opération sera expliquée en détail dans la section suivante.)

  1. Déterminez la valeur de $ \ sigma $. Supposons que les scores du candidat suivent une distribution normale avec une moyenne de $ \ mu_a $ et un écart type de $ \ sigma $.
  2. Dans la distribution normale, $ b $ tel que l'aire de $ x> b $ soit $ \ frac {1} {r} $ est la note de passage minimale provisoire.
  3. Calculez la moyenne de la partie $ x> b $ de la distribution et définissez-la comme score moyen provisoire des candidats retenus $ {\ mu_p} ^ {\ prime} $.
  4. Mettez à jour l'écart type $ \ sigma $ à partir de la relation d'amplitude entre $ {\ mu_p} ^ {\ prime} $ et $ \ mu_p $, et revenez à 1. Répétez ceci.
  5. Lorsque $ {\ mu_p} ^ {\ prime} = \ mu_p $, le score de passage minimum $ b $ à ce moment-là est utilisé comme valeur prédite.

Après cela, la valeur prédite du score de réussite le plus bas et la valeur réelle ont été tracées, et la précision a été comparée au cas de la prédiction simple (). () Prédiction que la note de passage minimale = (note moyenne des candidats + note moyenne des candidats retenus) / 2

Détails de la méthode

1. Déterminez la valeur de $ \ sigma $. Supposons que les scores du candidat suivent une distribution normale avec une moyenne de $ \ mu_a $ et un écart type de $ \ sigma $. </ font> </ b>

Cette hypothèse était considérée comme valide lorsque le nombre de candidats était suffisamment élevé et qu'aucun candidat n'avait obtenu un plein ou zéro point. Bien sûr, la vraie distribution des scores est une distribution discrète, mais nous la considérons comme une distribution continue. Le premier $ \ sigma $ peut enfin être décidé, et sera mis à jour plus tard pour se rapprocher de la valeur optimale. Si vous regardez le graphique ci-dessus comme "distribution de probabilité des scores pour un élève", l'axe $ y $ est "densité de probabilité (qui devient probabilité une fois intégrée)", et si vous regardez "répartition des scores pour tous les élèves" L'axe $ y $ est "densité de probabilité x nombre de personnes (une fois intégré, il devient le nombre de personnes)".
2. Dans une distribution normale, $ b $ tel que l'aire de $ x> b $ soit $ \ frac {1} {r} $ est le score de passage minimum provisoire. .. </ font> </ b>

Cela peut être exprimé sous forme de formule

\int^{b}_{\infty} \frac{1}{\sqrt{2\pi{\sigma}^2}}\exp{\left(-\frac{(x-\mu_a)^2}{2\sigma^2}\right)} \mathrm{d}x = 1-\frac{1}{r}

Équivaut à trouver $ b $ qui satisfait. Le côté gauche est la fonction de distribution cumulative de cette distribution normale avec $ b $ substitué. Cette formule est ne peut pas être résolue analytiquement </ b>, j'ai donc utilisé la programmation (Python) cette fois (le code sera décrit plus tard). La ligne droite $ x = b $ est une image qui sépare les passants et les échecs par la distribution des scores.
3. Calculez la moyenne de la partie $ x> b $ de la distribution et définissez-la comme score moyen provisoire des candidats retenus $ {\ mu_p} ^ {\ prime} $. </ font> </ b>

Cela équivaut à trouver la moyenne (valeur attendue) de la distribution normale de coupe </ b>.

{\mu_p}^{\prime} = \mu_a + \sigma\frac{\phi\left(\frac{b - \mu_a}{\sigma}\right)}{1-\Phi\left(\frac{b - \mu_a}{\sigma}\right)}

($ \ Phi (\ cdot) $ représente la fonction de densité de probabilité de la distribution normale standard, et $ \ Phi (\ cdot) $ représente sa fonction de distribution cumulative). Référence: https://bellcurve.jp/statistics/blog/18075.html
4. Mettez à jour l'écart type $ \ sigma $ à partir de la relation d'amplitude entre $ {\ mu_p} ^ {\ prime} $ et $ \ mu_p $, et revenez à 1. Répétez ceci. </ font> </ b>

Comme le montre la figure ci-dessus, plus l'écart-type $ \ sigma $ déterminé au début est grand, plus $ {\ mu_p} ^ {\ prime} $ (croissant monotone) est grand, utilisez donc la dichotomie . , $ {\ mu_p} ^ {\ prime} = \ mu_p $ Trouver $ \ sigma $. Comme le montre la figure ci-dessus, la plage de recherche est réduite de moitié à chaque fois, donc si vous la répétez environ 100 fois, vous atteindrez la valeur cible avec une précision suffisante. (Note) En fait, $ \ sigma $ et $ {\ mu_p} ^ {\ prime} $ sont dans une relation de fonction linéaire comme le montre la figure ci-dessus. Par conséquent, il est possible de trouver $ \ sigma $ tel que $ {\ mu_p} ^ {\ prime} = \ mu_p $ sans utiliser réellement la dichotomie. Je l'ai remarqué après l'analyse, mais comme la précision du calcul et le temps de calcul sont presque les mêmes, j'ai posté l'analyse par la dichotomie telle quelle.
5. Lorsque $ {\ mu_p} ^ {\ prime} = \ mu_p $, le score de passage minimum $ b $ à ce moment-là est utilisé comme valeur prédite.

Code et résultats

La «prédiction en utilisant la distribution normale» ci-dessus a été réalisée, et la précision a été comparée à la «prédiction que le score de réussite minimum = (score moyen des candidats + score moyen des candidats retenus) / 2».

import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score, mean_absolute_error

# 2013-Données 2019 de https://www.goro-goro.net/2019-musashi
jukensya = [433, 556, 519, 590, 577, 541, 569]
goukakusya = [177, 177, 185, 183, 187, 185, 186]
juken_heikin = [138.5, 173.3, 172.9, 167.0, 165.5, 186.9, 170.5]
goukaku_heikin = [166.5, 210.7, 210.3, 202.0, 197.0, 221.5, 205.2]
goukaku_saitei = [146, 192, 188, 184, 180, 201, 185]

goukaku_saitei_pred = []

for i in range(7):  # 2013-Analyser 7 fois en 2019
    r = jukensya[i] / goukakusya[i]  #grossissement
    mu_a = juken_heikin[i]  #Note moyenne des candidats
    mu_p = goukaku_heikin[i]  #Note moyenne des candidats retenus
    
    sigma_l = 0.1
    sigma_r = 1000
    sigma = (sigma_l + sigma_r) / 2  #Écart type, 0.Recherche dans la plage de 1 à 1000
    
    for i in range(100):  #Répétez la dichotomie 100 fois
        b = norm.isf(1 / r, mu_a, sigma)  #Note de passage minimale provisoire
        mu_p_prime = mu_a + sigma * norm.pdf((b - mu_a) / sigma) \
                     / (1 - norm.cdf((b - mu_a) / sigma))  #Note moyenne provisoire des candidats retenus
        if mu_p_prime < mu_p:
            sigma_l = sigma
        else:
            sigma_r = sigma
        sigma = (sigma_l + sigma_r) / 2
    
    goukaku_saitei_pred.append(b)

#Prédiction que le point médian entre le score moyen des candidats et le score moyen des candidats retenus est le score de réussite le plus bas
goukaku_saitei_pred_rough = [(goukaku_heikin[i] + juken_heikin[i]) / 2 for i in range(7)]

## R^Confirmation de 2 et MAE##

print("Pred 1:Résultats de la prédiction utilisant la distribution normale")
print("R^2: {:.4f}".format(r2_score(goukaku_saitei, goukaku_saitei_pred)))
print("MAE: {:.4f}".format(mean_absolute_error(goukaku_saitei, goukaku_saitei_pred)))
print("")
print("Pred 2: (Note moyenne des candidats+Note moyenne des candidats retenus) /Le résultat de la prédiction qu'il est 2")
print("R^2: {:.4f}".format(r2_score(goukaku_saitei, goukaku_saitei_pred_rough)))
print("MAE: {:.4f}".format(mean_absolute_error(goukaku_saitei, goukaku_saitei_pred_rough)))

##La valeur de mesure-Création d'un graphique de valeur prédite##

fig = plt.figure(figsize=(10, 5))
lim = [140, 220]  #Gamme des deux axes
s = 17  #taille de police

# Pred 1:Résultats de la prédiction utilisant la distribution normale
ax0 = fig.add_subplot(1,2,1)

ax0.plot(goukaku_saitei, goukaku_saitei_pred, "o", markersize=8)
ax0.plot(lim, lim, "k-")

ax0.set_title('Pred 1', fontsize=s)
ax0.set_xlabel('True', fontsize=s)
ax0.set_ylabel('Predicted', fontsize=s)
ax0.tick_params(labelsize=s)
ax0.set_xlim(lim)
ax0.set_ylim(lim)
ax0.set_aspect('equal')

# Pred 2: (Note moyenne des candidats+Note moyenne des candidats retenus) /Le résultat de la prédiction qu'il est 2
ax1 = fig.add_subplot(1,2,2)

ax1.plot(goukaku_saitei, goukaku_saitei_pred_rough, "o", markersize=8)
ax1.plot(lim, lim, "k-")

ax1.set_title('Pred 2', fontsize=s)
ax1.set_xlabel('True', fontsize=s)
ax1.set_ylabel('Predicted', fontsize=s)
ax1.tick_params(labelsize=s)
ax1.set_xlim(lim)
ax1.set_ylim(lim)
ax1.set_aspect('equal')

#Enregistrer au format PNG
fig.tight_layout()
fig.savefig("plot.png ")

production La valeur R ^ 2 est un coefficient de détermination, et plus elle est proche de 1, meilleure est la précision. MAE est la moyenne des valeurs absolues des erreurs de prédiction, et plus elle est proche de 0, meilleure est la précision.

Pred 1:Résultats de la prédiction utilisant la distribution normale
R^2: 0.9892
MAE: 1.4670

Pred 2: (Note moyenne des candidats+Note moyenne des candidats retenus) /Le résultat de la prédiction qu'il est 2
R^2: 0.9583
MAE: 2.5571

plot.png

Considération

On peut dire que Pred 1, qui est une prédiction utilisant une distribution normale, est plus précis </ b> que Pred 2, qui est une simple prédiction. L'erreur de prédiction moyenne est d'environ 1,5 point, ce qui semble être suffisant comme guide pour une étude réelle. En outre, en regardant le graphique Pred 2, l'erreur de prédiction est importante dans les données près de 145 points en bas à gauche. C'est probablement parce que Pred 2 utilise le "point médian entre le score moyen des candidats et le score moyen des candidats retenus" quel que soit le grossissement de l'examen, il ne peut donc pas répondre aux changements de grossissement (seulement cette année). Le grossissement est aussi faible que 2,4 fois, 2,8 à 3,2 fois les autres années). D'autre part, dans Pred 1, l'erreur de prédiction est supprimée au même niveau que les autres données ou moins, et on peut dire que la méthode utilisant la distribution normale peut faire face au changement de grossissement.

Dans Pred 1, de nombreuses données ont un écart similaire à savoir que "la valeur prédite est d'environ 1 à 2 plus petite que la valeur réelle". Par conséquent, si les données sont suffisantes, il est possible que la précision soit encore meilleure en trouvant la constante correspondant à "environ 1 à 2" cette fois et en ajoutant la correction à la valeur prédite.

référence

scipy.stats --API pour les fonctions statistiques scipy - le blog dekeisuke http://kaisk.hatenadiary.com/entry/2015/02/17/192955

3-5.Distorsion et netteté|Heure des statistiques|Statistiques WEB https://bellcurve.jp/statistics/course/17950.html

Recommended Posts