Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/02/2010, à 16:45

Abu

[Python] lang : Script pour déterminer la langue d'un fichier texte

Hello,
Voilà un petit truc que j'ai fait pour occuper mes vacances.
C'est un script en Python que permet de connaitre la langue d'un fichier texte (parmi l'anglais, le français, l'allemand et l'espagnol).
Je l'ai fait pour ranger mes sous-titres et ça marche vraiment bien (pour l'instant j'ai 100% de réussite et c'est assez rapide).
Donc je vous en fait profiter, si ça peut aider, c'est pas plus cher...
En plus je suis sûr qu'on peut lui trouver d'autres applications.

Si comme moi vous tâtonnez en Python, j'en ai profité pour illustrer quelques trucs sympas (passages de paramètres, sorties d'erreurs, fichiers,...).

Peut-être que ça existe déjà, surement même en mieux mais bon...

Commentaires, remarques, etc... sont bien entendu les bienvenues.
Notamment si il y a des lourdeurs ou maladresses (j'en doute pas), ou des choses à améliorer.

Abu(ntu)

Comme d'hab, copiez-collez le script dans /usr/local/bin/lang (ou ailleurs) et mettez les droits en exécution

- lang v1.01 :
Rajout d'un option -r pour renommer les fichier.
Par ex aaa.srt -> aaa.FR.srt
Attention : A TESTER avant de lancer en boucle
(a priori ça marche mais on est jamais trop prudent)

- lang v1.04 :
Changement du calcul des distances
Modifications de la fonction de renommage
Réécriture partielle du code (notamment le passage d'options)

- lang v1.06
Ajout de l'italien et du portugais
Quelques petites modifs (calculs d'indices)

- lang v1.07
Amélioration de la détection de l'espagnol
Correction de petits bugs( oublis, fautes de frappes)
Sortie debug (-d) adaptée pour étudier les résultats dans un tableur et faire des zolies stats et décider quand on peut faire confiance au résultat et quand on peut pas (A faire)

- lang v1.09
Suppression des tags et balises HTML
-> Gestion des fichiers HTML (et ouverture pour .tex et autres)

- lang v1.11
Gestion des caractères spéciaux (accents,...) avec le paramètre -x
Diverses améliorations (sortie adaptée à gnuplot)
J'espère pas trop de bugs ou coquilles rajoutés....

- lang v1.13
Nettoyage du code et des commentaires
Caractères spéciaux toujours gérés
Quelques changements dans les options (voir -h)
Versions quasi-finale

#!/usr/bin/python
# -*- coding:Utf-8 -*-

# Installation :
# Copier-coller ce script dans le fichier /usr/local/bin/lang
#
# Dans une console :
# $ cd
# $ nano lang
# (copier-coller le script)
# (CTRL+X pour quitter puis O pour Oui et valider)
# $ chmod +x lang
# $ sudo mv lang /usr/local/bin/

version="1.13"

about="""
        **************
        * lang v"""+version+""" *
        **************

 Script pour déterminer la langue d'un fichier texte.
 Pratique pour faire le ménage dans ses sous-titres.
 Peut servir aussi pour des sites web,...
 Traite l'anglais, le français, l'allemand et l'espagnol,
 l'italien et le portugais.
 C'est très facile d'ajouter d'autres langues.

 Se base sur la fréquence d'apparition théorique de chaque lettre
 dans les différente langues. 

 Astuce pour parcourir les sous-titres d'une arborescence :
 Se mettre à la racine puis :
   find ./ -name "*.srt" -exec lang {} \; > lang_ST.txt
 ou bien :
   find "/chemin absolu/"  -name "*.srt" -exec lang {} \; > lang_ST.txt
 On peut aussi rajouter | grep "ENG" pour récupérer les sous-titres en anglais :
   find ./ -name "*.srt" -exec lang  {} \; | grep "ENG" > lang_ST.txt
 
 Licence total freeride. Enjoy.
 N'hésitez pas à modifier le script à votre gout, à l'intégrer à vos projets,...

 Explications, questions, ... :

             http://forum.ubuntu-fr.org/viewtopic.php?id=381099

        Abu(ntu) - abunux at gmail point com - 24/02/2010 - 03/03/2010                               
 """

todo="""
            -----------
             A faire :
            -----------
        
    - Fonctionnalités :
    
- Ajouter d'autres langues (facile) : NL, DAN, NOR, SWE, FIN, POL, TUR
- Voir les langues non latines (Russe, Grec, langues asiatiques,...)

- Interprétation des indicateurs et mise en place de bon / pas bon
-> des tests, des tests et encore des tests sur plein de fichiers
avec plein de langues différentes

- Script bash pour parcourir un dossier et sortir les résultats dans un
fichier ou un graphique gnuplot
- Intégrer ça à nautilus (clic droit sur un sous-titre donne la langue
dans le menu contextuel). Ce serait génial ça...

    - Améliorations :
    
- Accents dans l'aide -h (optparse)
- Déterminer si un fichier est un fichier texte sans utiliser l'extension
- Fonction de renommage un peu lourde

"""


#-------------------------------------------------------------------------------
# Récupération des paramètres en ligne de commande
#-------------------------------------------------------------------------------

import sys
from optparse import OptionParser, OptionGroup

# A ajouter : NL, DAN, NOR, SWE, FIN, POL, TUR
LANG_dispo=['ENG','FR','GER','ESP','ITA','POR']

usage="%prog [OPTIONS] FICHIER"
version="%prog v"+version

parser=OptionParser(usage=usage, version=version)

# Options de sortie
groupe_sorties1=OptionGroup(parser,"Options de sortie ")
groupe_sorties1.add_option("-n","--nom",action="store_true",dest="nom",
    default=True,help="(Par defaut) Donne une sortie 'Fichier : LANG'")
groupe_sorties1.add_option("-m","--mini",action="store_true",dest="mini",
    default=False,help="Donne juste la langue(ENG,FR,...)")
groupe_sorties1.add_option("-r","--rename",action="store_true",dest="rename",
    default=False,help="Renomme le fichier en rajoutant la langue")
groupe_sorties1.add_option("-i","--interact",action="store_true",dest="interact",
    default=False,help="Demande confirmation avant de renommer")

groupe_sorties2=OptionGroup(parser,"Options de sortie d'analyse ",\
    "A terme, inutiles pour le commun des mortels")
groupe_sorties2.add_option("-c","--complet",action="store_true",dest="complet",
    default=False,help="Sortie complete (resume de toutes les valeurs)")
groupe_sorties2.add_option("-t","--table",action="store_true",dest="table",
    default=False,help="Sortie adaptee pour etudier dans un tableur : \
Resultats separes par des virgules")
groupe_sorties2.add_option("-g","--gnuplot",action="store_true",dest="gnuplot",
    default=False,help="Sortie adaptee pour tracer dans gnuplot : Resultats \
separes par des espaces. Pas de nom de fichier")

# Options de langues
groupe_lang=OptionGroup(parser,"Options de langue ")
groupe_lang.add_option("-A","--ALL",action="store_true",dest="all",
    default=False,help="Teste toutes les langues disponibles : "
                  +str(LANG_dispo)+ " (ENG et FR uniquement par defaut)")

parser.add_option_group(groupe_sorties1)
parser.add_option_group(groupe_lang)
parser.add_option_group(groupe_sorties2)

#Divers
parser.add_option("-a","--about",action="store_true",dest="about",
    default=False,help="A propos")
parser.add_option("-d","--todo",action="store_true",dest="todo",
    default=False,help="A faire")
parser.add_option("-s","--source",action="store_true",dest="source",
    default=False,help="Afficher le code source du script")

global opts
(opts,args)=parser.parse_args()

# Options diverses
if opts.source:
    source_file=open(sys.argv[0],"r")    
    print source_file.read()
    sys.exit(0)
elif opts.about:
    print about
    sys.exit(0)
elif opts.todo:
    print todo
    sys.exit(0)

# Génération de la liste de langues à tester
global LANG; LANG=[]
if opts.all:
    LANG=LANG_dispo
else:
    # Par défaut juste anglais et français pour être plus rapide
    LANG=['ENG','FR']

# Génération du nom du fichier à tester
global nom_fichier
nom_fichier="".join(args)
if nom_fichier=="":
    sys.stderr.write("Erreur : Aucun fichier passé en paramètre. \n")
    parser.print_help()
    sys.exit(2)

#-------------------------------------------------------------------------------
# Test et ouverture du fichier passé en paramètre
#-------------------------------------------------------------------------------

import os.path

# Test que le fichier existe
if not os.path.isfile(nom_fichier):
    sys.stderr.write("Erreur : %s n'existe pas.\n" % nom_fichier)
    sys.exit(2)
    
# Test que le fichier est un fichier texte
ext=os.path.splitext(nom_fichier)[1]
connu=(".srt",".txt",".htm",".html")
if ext not in connu :
    sys.stderr.write("Erreur : %s n'est pas reconnu. \
Extensions possibles : %s\n" % (nom_fichier,connu))
    sys.exit(2)

# Ouverture du fichier
try:
    fichier=open(nom_fichier,"r")
except:
    sys.stderr.write("Erreur : Erreur d'ouverture de %s.\n" % nom_fichier)
    sys.exit(2)

# Plus qu'à récupérer le contenu et fermer
texte_brut=fichier.read()
fichier.close()

#-------------------------------------------------------------------------------
# Prétraitement du texte
#-------------------------------------------------------------------------------

def suppr_tag(texte,delimitateurs=[('<script','</script>'),('{','}'),('<','>')]):
    # Supprime les parties de texte comprises entre les delimitateurs (compris)
    # Ca peut être n'importe quelle chaine de caractères
    # Exemple ici avec les balises html <script...>...</script>      
    # Mettre ('<','>') en dernier au cas où il y ait des "inférieur","supérieur"
    # On peut adapter suivant l'utilisation (par ex LaTeX ou autre)        
    for (debut,fin) in delimitateurs:        
        i0=len(texte)        
        while i0!=-1 :        
            i0=texte.rfind(debut,0,i0)    
            i1=texte.find(fin,i0)       
            if i1!=-1:
                texte=texte[:i0]+texte[i1+len(fin):]
            else:
                i0=max(-1,i0-1)        
    return texte

def suppr_HTML(texte):
    # Remplace les caractères spéciaux du HTML
    remplacement_HTML={'&nbsp;':' '} # A compléter...    
    for lettre in remplacement_HTML:
        texte=texte.replace(lettre,remplacement_HTML[lettre])
    return texte

def suppr_speciaux(texte):
    # Supprime les caractères spéciaux (ponctuation, chiffres, symboles,...)
    texte=texte.translate(None,\
                '@§^&|$€¤£µ².;,`\'\"?!¿¡#:%*+-_/><~0123456789=()[]{}\\')
                #' \n@§^&|$€¤£µ².;,`\'\"?!¿¡#:%*+-_/><~0123456789=()[]{}\\')
    return texte

def nettoyage(texte):
    # Nettoyage du texte avant traitement
    texte=suppr_tag(texte)    
    texte=suppr_HTML(texte)
    texte=suppr_speciaux(texte)
    return texte

def substitution(texte):
    texte=texte.lower()
    # Mettre toutes les lettres spéciales en minuscule    
    remplacement=\
    {'À':'à','Á':'á','Â':'â','Ä':'ä','Ã':'ã','Å':'å',
     'È':'è','É':'é','Ê':'ê','Ë':'ë',
     'Ì':'ì','Í':'í','Î':'î','Ï':'ï',
     'Ò':'ò','Ó':'ó','Ô':'ô','Ö':'ö','Õ':'õ','Ø':'ø',
     'Ù':'ù','Ú':'ú','Û':'û','Ü':'ü',
     'Ç':'ç','Œ':'œ','Æ':'æ','Ñ':'ñ'}    
    for lettre in remplacement:
        texte=texte.replace(lettre,remplacement[lettre])
    return texte

#-----------------------------------------------------------------------------
# Gestion des langues
#-----------------------------------------------------------------------------

# Fréquences théoriques d'apparition des caractères
# Source :
#   http://www.sttmedia.com/characterfrequencies
#   (stefantrost.de)
#
# Idée :
#   On stocke les fréquences théoriques pour chaque langue dans un dictionnaire
# de dictionnaires ayant pour clefs chaque lettre de l'alphabet :
# freq_theo['LANG']
#   On crée les alphabets de chaque langue sous forme d'un dictionnaire
# de listes : alpha['LANG']
# alpha['total'] regroupe toutes les lettres de toutes les langues étudiées

   
# Fréquences théoriques d'apparition de chaques lettres
# -----------------------------------------------------

global freq_theo; freq_theo={}

##freq_theo['LAN']={'a':,'b':,'c':,'d':,'e':,'f':,
##                  'g':,'h':,'i':,'j':,'k':,'l':,
##                  'm':,'n':,'o':,'p':,'q':,'r':,
##                  's':,'t':,'u':,'v':,'w':,'x':,
##                  'y':,'z':,'à':,'á':,'â':,'ä':,
##                  'ã':,'å':,'è':,'é':,'ê':,'ë':,
##                  'ì',:'í':,'î':,'ï':,'ò':,'ó':,
##                  'ô':,'ö':,'õ':,'ø':,'ù':,'ú':,
##                  'û':,'ü':,'ç':,'œ':,'æ':,'ñ':}

freq_theo['ENG']={'a':8.34,'b':1.54,'c':2.73,'d':4.14,'e':12.60,'f':2.03,
                  'g':1.92,'h':6.11,'i':6.71,'j':0.23,'k':0.87,'l':4.24,
                  'm':2.53,'n':6.80,'o':7.70,'p':1.66,'q':0.09,'r':5.68,
                  's':6.11,'t':9.37,'u':2.85,'v':1.06,'w':2.34,'x':0.20,
                  'y':2.04,'z':0.06}

freq_theo['FR']={'a':8.13,'b':0.93,'c':3.15,'d':3.55,'e':15.1,'f':0.96,
                 'g':0.97,'h':1.08,'i':6.94,'j':0.71,'k':0.16,'l':5.68,
                 'm':3.23,'n':6.42,'o':5.27,'p':3.03,'q':0.89,'r':6.43,
                 's':7.91,'t':7.11,'u':6.05,'v':1.83,'w':0.04,'x':0.42,
                 'y':0.19,'z':0.21,'œ':0.01,'à':0.54,'â':0.03,'ç':0,
                 'è':0.35,'é':2.13,'ê':0.24,'ë':0.01,'î':0.03,'ï':0,
                 'ô':0.07,'ù':0.02,'û':0.05,'ü':0.02}

freq_theo['GER']={'a':5.58,'b':1.96,'c':3.16,'d':4.98,'e':16.93,'f':1.49,
                  'g':3.02,'h':4.98,'i':8.02,'j':0.24,'k':1.32,'l':3.60,
                  'm':2.55,'n':10.53,'o':2.24,'p':0.67,'q':0.02,'r':6.89,
                  's':6.42,'t':5.79,'u':3.83,'v':0.84,'w':1.78,'x':0.05,
                  'y':0.05,'z':1.21,'ä':0.54,'ö':0.30,'ü':0.65,'ß':0.37}

freq_theo['ESP']={'a':11.72,'b':1.49,'c':3.87,'d':4.67,'e':13.72,'f':0.69,
                  'g':1.00,'h':1.18,'i':5.25,'j':0.52,'k':0.11,'l':5.24,
                  'm':3.08,'n':6.83,'o':8.44,'p':2.89,'q':1.11,'r':6.41,
                  's':7.20,'t':4.60,'u':4.55,'v':1.05,'w':0.04,'x':0.14,
                  'y':1.09,'z':0.47,'á':0.44,'é':0.36,'í':0.70,'ñ':0.17,
                  'ó':0.76,'ú':0.12,'ü':0.02}

freq_theo['ITA']={'a':10.85,'b':1.05,'c':4.30,'d':3.39,'e':11.49,'f':1.01,
                  'g':1.65,'h':1.43,'i':10.18,'j':0,'k':0,'l':5.70,
                  'm':2.87,'n':7.02,'o':9.97,'p':2.96,'q':0.45,'r':6.19,
                  's':5.48,'t':6.97,'u':3.16,'v':1.75,'w':0,'x':0,
                  'y':0,'z':0.85,'à':0.15,'è':0.42,'é':0.06,'ì':0.09,
                  'ò':0.11,'ù':0.12}

freq_theo['POR']={'a':12.21,'b':1.01,'c':3.35,'d':4.21,'e':13.19,'f':1.07,
                  'g':1.08,'h':1.22,'i':5.49,'j':0.30,'k':0.13,'l':3.00,
                  'm':5.07,'n':5.02,'o':10.22,'p':3.01,'q':1.10,'r':6.73,
                  's':7.35,'t':5.07,'u':4.46,'v':1.72,'w':0.05,'x':0.28,
                  'y':0.04,'z':0.45,'à':0.04,'á':0.41,'ã':0.83,'ç':0.40,
                  'é':0.52,'ê':0.36,'ì':0.18,'ò':0.17,'ô':0.01,'õ':0.04,
                  'ú':0.11}

# Alphabets pour chaques langues
# ------------------------------

global alpha;alpha={};

def concat(llistes):
    # Récupère une liste contenant une seule fois chaque élément présent dans
    # au moins une liste de la liste de listes llistes
    # Va permettre de créer l'aphabet total à partir des alphabets de chaques
    # langues
    sortie=[]
    for liste in llistes:
        for l in liste:
            if l not in sortie:
                sortie.append(l)
    return sortie

# On crée l'alphabet total avec les lettres de chaques langues
# alpha['ENG']=['a',....], alpha['FR']=['a',..,'é',...] ....
# alpha['total']=Alphabet total regroupant toutes les lettres
for L in LANG:
    alpha[L]=freq_theo[L].keys()
alpha['total']=concat(alpha.values())

# On complète par 0 les fréquences des lettres qui n'appartiennent
# pas à l'alphabet de la langue
# A voir : Mettre un poids négatif sur ces lettre ?
for L in LANG:
    for l in alpha['total']:
        if l not in alpha[L]:
            freq_theo[L][l]=0


#-----------------------------------------------------------------------------
# Calcul du résultat et d'indicateurs
#-----------------------------------------------------------------------------

from math import sqrt

# Traitement du texte contenu dans le fichier
# -------------------------------------------
texte_clean=nettoyage(texte_brut)
texte=substitution(texte_clean)
if texte=='':
    sys.stderr.write("Erreur : Fichier %s vide.\n" % nom_fichier)
    sys.exit(2)


# Calcul de la distance du texte avec les langues connues
# -------------------------------------------------------
# C'est la distance euclidienne dans R^(nbre de lettres dans l'alphabet total)
# d=sqrt(Somme_lettres((fréq réelle-freq théorique)²))

def compte(texte,alphabet=alpha['total']):
    # Fréquences des lettres de texte
    # Résultat dans un dictionnaire :
    # freq{'a'},...
    # total=Nombre total de lettres comptées
    nb_lettres={}
    total=0
    freq={}
    for l in alphabet:
        nb_lettres[l]=0 
    i=0
    while i<len(texte):
        # Si la lettre de rang i est dans 'abc...yz'
        if texte[i] in alphabet:        
            nb_lettres[texte[i]]+=1
            i+=1
            total+=1            
        # Les caractères spéciaux comptent pour 2 caractères
        elif i+1<len(texte) and texte[i]+texte[i+1] in alphabet :
            nb_lettres[texte[i]+texte[i+1]]+=1
            i+=2
            total+=1            
        else:
            i+=1        
    if total==0 :
        sys.stderr.write("Erreur : Aucun caractère alphabétique.\n")
        sys.exit(2)        
    for l in alphabet:
        freq[l]=float(nb_lettres[l])*100/total
    return freq,total

def dist(dict1,dict2,alphabet=alpha['total']):
    # Calcul la distance euclidienne entre 2 vecteurs (dictionnaires)
    d=0
    for l in alphabet:
        d+=(dict1[l]-dict2[l])**2
    return sqrt(d)

def calcul_distances(X):
    # Retourne un vecteur R=[d(X,ENG),d(X,FR),...]
    R=[]
    for L in LANG:
        R.append(0)        
    for L in LANG:
            R[LANG.index(L)]=dist(freq_theo[L],X)
    return R

freq,total=compte(texte)
R=calcul_distances(freq)
m=min(R)
langue=LANG[R.index(m)]    


# Calcul des indicateurs de qualité
# ---------------------------------

def somme(a):
    # Calcule la somme des éléments de la liste a
    s=0
    for i in range(len(a)):
        s+=a[i]
    return s

def dist2(a,b):
    # Calcul la distance euclidienne entre 2 vecteurs (listes)
    d=0
    for i in range(len(a)):
	    d+=(a[i]-b[i])**2
    return sqrt(d)

R0=calcul_distances(freq_theo[langue])
C=1-(len(R)*m)/somme(R)
D=dist2(R,R0)
M=(1-C)*D*m

# Stockage des résultats dans un dictionnaire
global result; result={}
result['langue']=langue
result['m']=m
result['total']=total
result['R']=R
result['R0']=R0
result['C']=C
result['D']=D
result['M']=M



#   ------  A voir  ------
# Dit si le résultat est bon en fonction des indicateurs
def est_bon(res):
    if res['C']>0.5:
        return True
    else:
        return False

def pas_bon(res):
    if res['C']<0.3:
        return True
    else:
        return False

##if pas_bon(result):
##    result['langue']='N/A'

#-------------------------------------------------------------------------------
# Sortie des résultats
#-------------------------------------------------------------------------------

# Fonction pour renommer le fichier
def renomme(old_name,new_name):    
    if opts.interact:
        try:
            fichier=open(old_name,"r")
        except:
            sys.stderr.write("Erreur : Erreur d'ouverture de %s.\n"\
                             % old_name)
            sys.exit(2)
        rep=raw_input("Voulez-vous lire les 10 premières lignes (O ou N) ?")
        while rep not in ('N','n',''):
            for i in range(10):
                print fichier.readline()
            rep=raw_input("Voulez-vous lire 10 autres lignes (O ou N) ?")
        fichier.close()
        rep=raw_input("Voulez-vous renommer le fichier %s en %s (O ou N) ?"\
                      % (old_name,new_name))     
    else:
        rep='o'
    if rep in ('O','o',''):
        try :
            os.rename(old_name,new_name)
            print "%s renommé en %s avec succès." % (old_name,new_name)            
        except:
            sys.stderr.write("Erreur : Echec pour renommer %s en %s.\n" %\
                (nom_fichier,new_nom))
            sys.exit(2)                      
    sys.exit(0)
    return

def recup_indication(nom):
    # On récupère les différentes parties du nom du fichier
    # A la recherche d'un indication de langue
                                            # Ex : Si nom='aaa.fr.srt' :
    corps=os.path.splitext(nom)[0]          #   corps='aaa.fr'
    ext=os.path.splitext(nom)[1]            #   ext='.srt'
    fin=os.path.splitext(corps)[1]          #   fin='.fr'
    indication=fin.lstrip('.')              #   indication='fr'
    
    # Compatibilité avec les sous-titres standards
    indic_remplace={'en':'ENG','fr':'FR','de':'GER','es':'ESP','it':'ITA',
               'pt':'POR','br':'POR'}
    if indication in indic_remplace.keys():
        indication=indic_remplace[indication]
    else:
        indication=indication.upper()  
    return indication

# Renommage du fichier
# --------------------
# (Un peu lourdingue. A retravailler)

if opts.rename:    
    # On vérifie qu'il n'y a pas la bonne langue déjà indiquée
    indication=recup_indication(nom_fichier)
    
    if langue=='N/A': # A implanter (voir au-dessus)
        print "Désolé, je ne connais pas cette langue."
        sys.stderr.write("%s : Langue inconnu" % nom_fichier)
        sys.exit(0)

    # Si il y a déjà une indication de langue
    # (d'autres à rajouter ?)
    if indication.upper() in \
            LANG+['VO','ANG','EN','DE','ESP','ES','FRA','VOSTF',
                  'VOSTFR','VOSTE','IT','PT']:
        # Pas bonne langue. C'est rare donc on prend des précautions.
        if indication != result['langue']:
            print "%s contient une indication de langue qui semble \
être fausse : %s au lieu de %s" % (nom_fichier,indication,langue)
            if est_bon(result):
                print "Je suis assez sûr de moi : %.2f" % result['C']
            elif pas_bon(result):
                print "Je suis sûr de me tromper : %.2f" % result['C']
                print "%s ne peut pas être en %s." %\
                      (nom_fichier,result['langue'])
                sys.exit(0)
            else:
                print "Il est possible que j'ai raison : %.2f" % result['C']
                opts.interact=True # Dans ce cas on demande confirmation
            new_nom=os.path.splitext(os.path.splitext(nom_fichier)[0])[0]+\
                     "."+langue+os.path.splitext(nom_fichier)[1]            
            renomme(nom_fichier,new_nom)            
        # Bonne langue
        else:
            print "%s est correctement nommé, rien à faire." % nom_fichier
            sys.exit(0)
            
    # Pas d'indication de langue
    else:
        if est_bon(result):
            print "Je suis assez sûr de moi : %s est en %s (%.2f)"\
                      % (nom_fichier,result['langue'],result['C'])
        else:
            print "Il semble que %s est en %s mais je ne suis pas sûr (%.2f)"\
                      % (nom_fichier,result['langue'],result['C'])
            opts.interact=True # Dans ce cas on demande confirmation        
        new_nom=os.path.splitext(nom_fichier)[0]+\
                 "."+langue+os.path.splitext(nom_fichier)[1] 
        renomme(nom_fichier,new_nom)
        sys.exit(0)
    sys.exit(0)


# Gestion des sorties texte
# -------------------------

# Sortie minimale
# ---------------
if opts.mini:
    print result['langue']
    sys.exit(0)
    
# Sortie complète
# ---------------
if opts.complet:    
    sortie=''
    sortie+="""    - Nom_fichier : %s \n""" % nom_fichier
    for L in LANG:
        sortie+="""    - d(X,%3s)    : %5.2f (%5.2f)\n"""\
                 % (L,result['R'][LANG.index(L)],result['R0'][LANG.index(L)])        
    sortie+="""    - Langue      : %s \n""" % result['langue']
    
    VectR='[';VectR0='['
    for L in LANG:        
         VectR +="%5.2f, " % result['R'][LANG.index(L)]
         VectR0+="%5.2f, " % result['R0'][LANG.index(L)]
    VectR+="\b\b]";VectR0+="\b\b]"
    
    sortie+="""    - R           : %s \n""" % VectR
    sortie+="""    - R0          : %s \n""" % VectR0
    sortie+="""    - Longueur    : %d \n""" % result['total']
    sortie+="""    - m=min d(X,L): %.3f \n""" % result['m']
    sortie+="""    - C (0<=C<=1) : %.2f (Doit être proche de 1)\n"""\
             % result['C']
    sortie+="""    - D=d(R,R0)   : %.2f (Doit être petit) \n""" \
             %result['D']
    sortie+="""    - M=(1-C)*D*m : %.2f (Doit être petit) \n""" \
             % result['M']
    print sortie
    sys.exit(0)

# Sorties debug
# -------------
# Sortie personnalisée pour étudier les résultats
# Marche nikel avec calc (copier-coller, valeurs séparées par des virgules)
# ou avec gnuplot (valeurs séparées par des espaces), puis dans gnuplot :
#   > plot fichier.txt u a:b  (où a et b sont les colonnes à représenter)
# Rappel :
#   find ./ -name "*.srt" -exec lang -Ad {} \; > fichier.txt
if opts.table or opts.gnuplot:
    indication=recup_indication(nom_fichier)
    if result['langue']==indication:
        bon=1
        OK='BON'
    else:
        bon=0
        OK='PAS_BON'

    sortie=''
        
    if opts.table:
        # Sortie adaptée à Calc
        # ---------------------
        sortie+="%s," % nom_fichier
        sortie+="%s,%s,%d,%s," % (indication,result['langue'],bon,OK)
        for L in LANG:        
             sortie+="%.2f," % R[LANG.index(L)]
        sortie+=",%.3f,%.3f,%.3f,%.3f,%.3f,%d"\
                 % (result['m'],result['C'],1-result['C'],result['D'],
                    result['M'],result['total'])        
        
    elif opts.gnuplot:
        # Sortie adaptée à Gnuplot
        # ------------------------
        sortie+="%s %s %d %s " % (indication,result['langue'],bon,OK)
        for L in LANG:        
             sortie+="%.2f " % R[LANG.index(L)]
        sortie+="%.3f %.3f %.3f %.3f %.3f %d"\
                 % (result['m'],result['C'],1-result['C'],result['D'],
                    result['M'],result['total']) 
    
    print sortie
    sys.exit(0)


# Sortie par défaut (nom)
# -----------------------
if opts.nom:
    print "%s : %s" % (nom_fichier,result['langue'])
    sys.exit(0)
    
sys.exit(0)

Dernière modification par Abu (Le 03/03/2010, à 21:58)

Hors ligne

#2 Le 24/02/2010, à 17:14

magestik

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Si j'ai bien compris c'est basé sur la fréquence de certaines lettres ?
c'est bien vu ^^

Mais y'a un truc "choquant":

remplacement={'à':'a','À':'a','ä':'a','Ä':'a','á':'a',\
              'é':'e','É':'e','è':'e','È':'e','ê':'e','Ê':'e','ë':'e','Ë':'e',\
              'î':'i','Î':'i','ï':'i','Ï':'i','í':'i',\
              'ô':'o','Ô':'o','ö':'o','Ö':'O','ó':'o',\
              'ù':'u','Ù':'u','û':'u','Û':'u','ü':'u','Ü':'u','ú':'u',\
              'ç':'c','Ç':'c','œ':'oe','Œ':'oe','ß':'ss','ñ':'n'}
    for lettre in remplacement:
        texte=texte.replace(lettre,remplacement[lettre])
    return texte

Moi j'aurais fait une analyse de ces caractères spéciaux. Par exemple si on trouve plusieurs "é", "à", "è", "ç" alors c'est français. Pour l'allemand y'aurait ça : "ß". En espagnol il y aurait le point d'interrogation inversé et plusieurs lettre avec un accent comme ça "~" (j'y connais rien à l'espagnol^^)
Au pire tu pourrais d'abord analyser les caractères accentué (si tu testes français tu cherches des caractères français ...). Et si tu cherches la langue te baser sur le nombre de ces caractères. Et si les résultats te plaisent pas tu passe à l'étude par fréquence de lettre.

EDIT: théoriquement, je pensais que l'analyse des caractères spéciaux serait plus rapide. Mais je viens de tester c'est déjà super rapide ^^ Merci, je vais l'utiliser tongue

Voilà wink

Dernière modification par magestik (Le 24/02/2010, à 17:25)

Hors ligne

#3 Le 24/02/2010, à 17:35

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Vi c'est ça j'analyse les fréquences des lettres et je compare avec les fréquences théoriques smile

Pour les caractères spéciaux, bah  j'y ai pensé et j'ai hésité, ça me paraissait plus simple d'avoir que 26 lettres pour ma méthode (analyse des fréquences et calcul d'un indice).
Mais c'est vrai que du coup l'analyse serait plus rapide (et plus sûre)
Il y a des cas (rares) où l'indice est assez élevé (plus de 20), dans ce cas pour être sûr je peux effectivement tester les caractères spéciaux pour confirmer le résultat.
A la base c'était juste pour l'anglais et le français. Les autres langues c'est juste pour le fun d'en rajouter et pouvoir en rajouter d'autres facilement (d'où les 26 lettres)

Hmm en fait ça me donne une idée... je vais coder ça ^^

Merci de ton avis smile

Abu(ntu)

edit : Cool ça me fait plaisir que quelqu'un s'en serve big_smile
edit 2 : Si tu vois un cas où le résultat est faux, tu peux me le dire stp (j'ai déjà pas mal testé mais on sait jamais)

Dernière modification par Abu (Le 24/02/2010, à 17:44)

Hors ligne

#4 Le 24/02/2010, à 17:42

magestik

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Ok si je vois un faux positif (on peut appeller ca comme ca ? tongue ) je te le dirais.
Je pense que je vais l'intégrer à mon lecteur de vidéo. Je sais pas encore comment mais j'ai le temps d'y reflechir.

Hors ligne

#5 Le 24/02/2010, à 18:34

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Permettre l'analyse des caractères spéciaux semble une bonne idée.

Cependant, je préfère ta méthode actuelle.

Personnellement, il m'arrive de placer des mots d'Espagnol dans mes textes (J'ai une amie Péruvienne). Donc: beaucoup de Français et un peu (très peu) d'Espagnol. Mais ça suffit à créer un faux positif si on ne se fie qu'à la présence de caractères spéciaux.

Note personnelle: J'approuve ! C'est bien de voir des gens programmer. Il me semble que cette
activité s'était "engourdie" depuis quelque temps sur ce forum.

Je vais analyser ton code de plus près et posterai mon avis si je prends conscience de qq chose.

Amicalement
-jjc-

Dernière modification par Jean-Julien (Le 24/02/2010, à 18:35)

Hors ligne

#6 Le 24/02/2010, à 18:44

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Sympa ça fait chaud au coeur smile

Effectivement, j'ai pensé à ça : si il y a une citation dans une autre langue, un passage anecdotique (souvent dans les série américaines il y a des passages en espagnol)
Mais ça peut être facilement contourné avec les fréquences d'apparition des caractères spéciaux sur l'ensemble du doc.

Je suis entrain de changer quelques petits trucs :
* Possibilité de renommer le fichier avec la langue (ça ça va être cool smile )
* Et une fonction d'évaluation de la certitude de la réponse (justement c'est là que je vais utiliser les caractères "typiques", pour confirmer mon analyse)

Abu(ntu)

edit : Pour magestik, j'ai essayé de bien prévoir le coup pour pouvoir intégrer ça dans un pipe, ou en faire un module donc ça devrait bien passer pour ton lecteur vidéo
(Perso j'aimerais le rajouter dans nautilus comme plugin, genre une colonne "Langue", ou bien avec le clic droit zou la langue apparait)

Dernière modification par Abu (Le 24/02/2010, à 18:48)

Hors ligne

#7 Le 24/02/2010, à 18:54

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Attention !

La longueur du texte est importante pour la fiabilité.
Ca induit le raisonnement suivant:

- Un long texte donnera des résultats plus fiables. La méthode des 26 lettres est valable.

- Un texte court fournira un résultat beaucoup moins fiable. Dans ce cas, le recours aux caractères spéciaux s'impose. Et dans ce cas, comme le texte est court, la présence de caractères spéciaux prend un poids plus fort dans le repérage. Je pense que localiser un seuil pour définir la taille à partir de laquelle les caractères spéciaux peuvent être considérés est une voie à explorer.

Hors ligne

#8 Le 24/02/2010, à 19:01

magestik

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Je suis d'accord avec toi Jean-Julien. Et avec un pourcentage ?

Hors ligne

#9 Le 24/02/2010, à 19:14

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Oui c'est clair
Quoique un test rapide avec vos deux derniers messages me donne bien la bonne langue (certes les indices sont élevés mais ils sont bons, justement il faut que je mette un indicateur là dessus, genre une sorte de distance entre les différentes langues, et alors analyser les caractères typiques pour confirmer)

Pour le post de Jean-Julien :
    -Indice ENG : 40.158841
    -Indice FR  : 20.714764
    -Indice GER : 42.956824
    -Indice SPA : 32.624764
    -Langue     : FR

Et pour celui de magestik :
    -Indice ENG : 57.187143
    -Indice FR  : 43.220408
    -Indice GER : 56.862449
    -Indice SPA : 48.878980
    -Langue     : FR

Sachant que l'indice pour une langue est calculé par :
Indice=Somme sur chaque lettre (val_abs(fréqu réelle-freq théorique))
(Je me demande si en mettant au carré les termes de la somme ce serait pas plus parlant (genre comme une sorte de variance))

PS : Une prochaine version à venir très bientôt
(ça motive le forum j'ai trouvé plein d'idées grâce à vous smile )

Abu(ntu)

Hors ligne

#10 Le 24/02/2010, à 19:15

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

> magestik

Mon avis: c'est la taille réelle qu'il faut considérer.
Je vais tâcher de faire court.

1) isoler différents textes des différentes longueurs dans les différentes langues.
2) Pour chaque langue et chaque longueur de texte, enregistrer la tableau des fréquences d'apparition des caractères.
3) Comparer ces tableaux des fréquences avec les tableaux de référence du programme actuel.
4) Les différences mesurées vont se réduire avec l'augmentation de la taille des fichiers testés.
5) L'évolution de ces différences en fonction de la taille pourra être représentée par une courbe.
6) Lorsque cette courbe commencera à s'aplatir, on aura localisé la position de la fenêtre de valeurs dans laquelle peut être fixée la valeur du seuil.
7) Il n'est pas exclu que la valeur du seuil puisse varier d'une langue à l'autre.

> Abu

Voilà des idées pour concevoir un programme d'atelier destiné à analyser les fichiers et déterminer les valeurs des seuils. Avec le temps, en pousuivant dans cette voie, tu va affiner l'efficacité de ton script.

Hors ligne

#11 Le 24/02/2010, à 19:25

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Petit mix:

El opinión está muy bueno.
(L'idée est très bonne.)
smile

Hors ligne

#12 Le 24/02/2010, à 19:34

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Second petit mix:

El opinión está muy bueno.
(L'idée est très bonne.)

Ma grand-mère s'appelait Maria Büdeker.

----

Idée: Le repérage de caractères spéciaux appartenant à des langues différentes pourrait gérer le flux d'instructions et fournir une réponse basée sur un algorithme d'analyse d'un fichier mixte.

Il y a de quoi passer son temps !

----

Pour les idées concernant les idéogrammes Chinois, il faut attendre 24 heures...
Bon, je vais préparer le souper.
A+
wink

Hors ligne

#13 Le 24/02/2010, à 19:34

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Version 1.1 en 1er topic
Rajout d'une option pour renommer automatiquement les fichiers
(A tester avant hein...)

PS : C'est cool de voir votre intérêt smile

Abu(ntu)

Hors ligne

#14 Le 24/02/2010, à 19:39

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

El opinión está muy bueno.
(L'idée est très bonne.) :
    -Indice ENG : 61.162973
    -Indice FR  : 51.571351
    -Indice GER : 62.489189
    -Indice SPA : 57.602973
    -Langue     : FR
On est bien entre le français et l'espagnol

Pris séparément :

El opinión está muy bueno :
    -Indice ENG : 81.370000
    -Indice FR  : 71.460000
    -Indice GER : 82.280000
    -Indice SPA : 72.890000
    -Langue     : FR
(pas glop)

L'idée est très bonne. :
    -Indice ENG : 73.935882
    -Indice FR  : 70.390588
    -Indice GER : 70.130588
    -Indice SPA : 75.055882
    -Langue     : GER
(Carrément pas glop du tout)

Hors ligne

#15 Le 24/02/2010, à 19:58

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

PARFAIT !!!
Tu progresses !
Trouver des "pas glop" pour les résoudre, c'est  ce qu'il faut faire.

Hors ligne

#16 Le 24/02/2010, à 20:22

nesthib

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

quelques remarques en vrac :

sur le code des options : plutôt que de faire une option par langue, tu pourrais faire une options avec argument du genre -L FR ou --langue=FR, ainsi ton code sera plus évolutif

pour l'algorithme de détection de langues tu peux également te baser sur les N-grammes, c'est en gros ce que tu fais dans ta première approche mais en utilisant des motifs de plusieurs lettres plutôt que des lettre uniques. (piste pour les comparaisons de séquences : python-ngram (pas testé), difflib (testé mais pas forcément le plus adapté))

Si tu as besoin d'un coup de main je suis partant, le sujet m'intéresse (j'avais pensé proposer ceci en challenge bash, mais le python est définitivement plus adapté ^^)

edit : quelques liens intéressants
- http://www.google.com/uds/samples/language/detect.html
- http://santhoshtr.livejournal.com/13832.html
- http://code.activestate.com/recipes/326576-language-detection-using-character-trigrams/

Dernière modification par nesthib (Le 24/02/2010, à 20:28)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#17 Le 24/02/2010, à 20:29

HP

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

nesthib a écrit :

Si tu as besoin d'un coup de main je suis partant, le sujet m'intéresse (j'avais pensé […] bash, mais le python est définitivement plus adapté ^^)

Python est, de toute façon, généralement plus adapté que Bash ! wink

Dernière modification par nesthib (Le 24/02/2010, à 20:32)


cat /dev/urandom >/dev/null 2>&1 #github

Hors ligne

#18 Le 24/02/2010, à 20:34

nesthib

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

pas pour un challenge bash tongue (mais pour programmer des truc complexe évidemment, c'est pour ça que je ne l'ai pas proposé)

ps. désolé pour l'édit de ton post, j'ai dérapé ^^ /me fatigué


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#19 Le 24/02/2010, à 20:35

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Oui, lorsque les résultats sont flous, il faut concevoir une démarche de lever de doute.
L'analyse de séquences propres à chaque langue est une excelente idée.
Ex: " y " ;  " et " ; " and "; " und " (prendre en compte les espaces). Ce genre de choses...

Hors ligne

#20 Le 24/02/2010, à 20:41

nesthib

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Jean-Julien a écrit :

Oui, lorsque les résultats sont flous, il faut concevoir une démarche de lever de doute.
L'analyse de séquences propres à chaque langue est une excelente idée.
Ex: " y " ;  " et " ; " and "; " und " (prendre en compte les espaces). Ce genre de choses...

la limite de cette idée est qu'il faut une intervention humaine ce qui devient impossible (difficile) pour de nombreux langages. À l'inverse les méthodes statistiques peuvent être réalisées automatiquement sur des corpus propres à chaque langue. C'est AMHA une démarche plus propre.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#21 Le 24/02/2010, à 20:47

Jean-Julien

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Je préconise une intervention humaine pour la définition des séquences.
La recherche des séquences se faisant par le programme.
Je compare cette méthode avec du "pré calculé".

Hors ligne

#22 Le 24/02/2010, à 21:35

magestik

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Je suis en plein film mais j'ai eu une idée !!!

En gros pour chaque langue tu as un truc comme ça :

    repart[LANG.index('ENG')]=\
           [8.08,1.67,3.18,3.99,12.56,2.17,1.80,5.27,7.24,0.14,0.63,4.04,2.60,\
           7.38,7.47,1.91,0.09,6.42,6.59,9.15,2.79,1.00,1.89,0.21,1.65,0.07]

Donc a=8.08, b=1.67 ... Mais pourquoi pas se baser (aussi) sur les caractères spéciaux ?
A la fin tu ajoutes é,è,à,ç,ß,ñ ... Et dans francais tu mettrais 5,4,2,3,0,0. Voilà^^

Qu'est-ce que vous en pensez ?

Hors ligne

#23 Le 24/02/2010, à 21:39

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Oh la vache, je viens de réaliser qu'en fait je suis amené à résoudre un problème de géométrie en dimension 26 , ça sent bon ça !!
Chaque répartition de lettres est un point dans R^26 (enfin plutôt [0,100]^26)
Soit X=[x1,...,x26] le vecteur associé au texte et L1, L2,... les vecteurs associés au différentes langues (fréquences théoriques)
Je calcule la distance entre X et L1,... et je cherche vers quel Li il est le plus proche.
On peut imaginer des zones de certitude et d'incertitude comme des sphères (ou d'autres formes)....
J'y réfléchi...

Sinon en vrac :
- Bien sûr pas d'intervention humaine (en tous cas pas une fois que le programme est fini)
- Le doublon, triplet,etc... j'y ai pensé aussi et c'est carrément efficace, reste à en faire un sélection judicieuse avec des échantillons représentatifs dans chaque langue étudiée
- Idem avec des mots clefs typiques
- Le passage de paramètres : Ben en fait c'est la 1ere fois que je pratique donc c'est vrai que c'est pas tip top cette avalanche d'options. Je vais essayer de faire mieux
- Excellent la petite appli de google
- Je n'ai pas envie de trop alourdir le côté "linguistique" (pour un projet comme ça c'est bête hein...), sinon on pioche 100 mots au hasard et on les cherche dans le dico zou c'est réglé
- A la base le but c'était pour les grands fichiers (sous-titres), pour lesquels ça marche du feu de zeus. Maintenant c'est excellent que ça soulève un intérêt et des challenges (fichiers courts, mixtes, langues asiatiques,...), le projet n'est pas fini smile
- Ce qui m'intéresse c'est surtout le côté maths du truc (et me faire plaisir à coder du Python)

Voilou

A+ pour une nouvelle version

Abu(ntu)

Hors ligne

#24 Le 24/02/2010, à 22:17

nesthib

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Pour résumer j'ai trouvé 4 méthodes principales pour la détection de langages :
- mots spécifiques aux langages (inefficace sur les textes courts, ne fonctionne pas avec les langues dont les mots ne sont pas composés de lettres)
- approches statistiques sur la fréquence des lettres
- approche pas n-grammes (très efficace (>20 car.), ne fonctionne pas avec les langues dont les mots ne sont pas composés de lettres, il existe une astuce pour les langues basées sur les idéogrammes)
- approche par "prédiction par reconnaissance partielle"

sinon autre remarque sur le code, tu aurais tout intérêt à séparer toutes les données concernant tes langues dans des fichiers séparés


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#25 Le 24/02/2010, à 22:18

Abu

Re : [Python] lang : Script pour déterminer la langue d'un fichier texte

Ah oui j'aurais besoin d'aide en expression régulières pour supprimer les codes divers du fichiers (tags pour les sous-titres, balises html,...), bref pour caricaturer tout ce qui se trouve entre <...>

Sinon, si j'ai le temps, je vais tout réécrire c'est devenu trop lourd.

A part ça pour mes distances ça marche bien et je crois avoir une bonne piste.

Voici un nouveau script
Je ne le met pas en 1er post car c'est des changements mineurs mais qui vont aider pour la suite :

- J'ai changé la table de répartition de l'anglais ça me donne de meilleurs résultats
Ligne 239-241 :

    repart[LANG.index('ENG')]=\
            [8.34,1.54,2.73,4.14,12.60,2.03,1.92,6.11,6.71,0.23,0.87,4.24,2.53,\
             6.80,7.70,1.66,0.09,5.68,6.11,9.37,2.85,1.06,2.34,0.20,2.04,0.06]

- Je calcule une distance euclidienne entre le vecteur texte et le vecteur langue :
indice=sqrt(somme(freq_lettre_texte-freq_lettre_théorique)²)

Ligne 265-278 :

import math
def indice(texte):
    ind=[]
    for L in LANG:
        ind.append(0)    
    nb=[]    
    nb=compte(texte)
    for i in range(26):
        for L in LANG:
            ind[LANG.index(L)]+=\
                        pow(float(nb[i])/nb[26]*100-repart[LANG.index(L)][i] ,2)                        
    for L in LANG:
            ind[LANG.index(L)]=math.sqrt(ind[LANG.index(L)])
    return ind

Et j'obtiens ce genre de résultats avec des sous titres (~400) pris au pif dans les 4 langues.
Dans l'ordre : LANG : [indENG, indFR, indGER, indSPA] (Meilleur indice):

Pour les FR :

FR : [9, 3, 9, 7] (3.1)
FR : [9, 2, 9, 7] (2.8)
FR : [9, 2, 9, 7] (2.4)
FR : [9, 3, 8, 6] (3.0)
FR : [9, 2, 9, 7] (2.3)

Pour les ENG :

ENG : [3, 10, 11, 10] (3.1)
ENG : [3, 10, 10, 10] (3.5)
ENG : [3, 10, 10, 10] (3.3)
ENG : [3, 10, 11, 10] (3.6)
ENG : [2, 10, 10, 10] (2.2)

Pour les GER :

GER : [9, 8, 3, 11] (3.9)
GER : [8, 8, 3, 11] (3.1)
GER : [8, 9, 4, 12] (4.5)
GER : [8, 8, 2, 11] (2.5)
GER : [9, 9, 3, 11] (3.9)
GER : [8, 8, 3, 11] (3.7)

Et enfin les SPA :

SPA : [8, 6, 10, 4] (4.1)
SPA : [9, 7, 11, 4] (4.3)
SPA : [9, 7, 11, 4] (4.1)
SPA : [8, 8, 12, 4] (4.2)
SPA : [9, 6, 11, 4] (4.2)
SPA : [8, 7, 11, 3] (3.3)

Ils sont à peu près tous comme ça.
Une seule valeur au-dessus de 5, pour un sous titre espagnol.

On remarque que les "normes" des sous-titres GER et SPA sont un peu plus élevées (3 à 4) que les FR et ENG (2 à 3). A mon avis les tableau de fréquences théoriques sont moins bon. A voir.
Notez les distances avec les autres langues qui sont à peu près constantes.

Ensuite j'ai calculé la distance entre les différente langues :
ENG-FR : 9.4
ENG-GER : 9.4
ENG-SPA : 9.6
FR-GER : 8.5
FR-SPA : 6.8 (voilà pourquoi il est plus difficile de les distinguer)
SPA-GER : 11.3

C'est cohérent et on retrouve à peu près ça dans les résultats.

Abu(ntu)

Hors ligne