jeudi 22 juin 2023

Traitement des données pour l'apprentissage automatique: suite

 Dans un article précédent, j'ai commencé à exposer des techniques pour réduire les données à traiter pour un dispositif d'apprentissage automatique. (voir article).

Continuons notre cheminement : comment éliminer les facteurs moins utiles ou encore comment supprimer des données non conformes (erreur de mesure etc.) 

Analyse des corrélations.

Il est possible d'obtenir la corrélation deux à deux des facteurs avec Pandas avec la méthode corr()


Une valeur proche de zéro est un signe de facteurs indépendants. 


On peut aussi avoir une confirmation visuelle par les lignes suivantes:

corrélation 2 à 2
A noter le ';' en fin d'instruction permettant de cacher les méta-informations de Matplotlib

Garder pour un apprentissage 2 facteurs qui sont fortement corrélés n'apportera pas d'informations nouvelles. Aussi, on peut supprimer un des deux facteurs sans risque d'appauvrir les informations.

Eliminations des valeurs aux extrémités.


Pour cela plusieurs solutions sont proposées

La méthode par l'écart type ou la déviation standard.

On ne conservera que les valeurs comprises dans une fourchette dont les extrémités sont calculées à partir de la moyenne et de l'écart type.  Il est possible de jouer sur l'amplitude de la fourchette.


Ici , on a pris 2 fois l'ecart type de chaque coté pour obtenir l'amplitude de la fourchette.
2 valeurs seulement sont éliminées à droite de la moyenne.

La méthode par la médiane et les quantiles.

La méthode quantile de Pandas permet de séparer les facteurs en jeux de données de même nombre (quantile(0.5)
Il faut donc calculer le quantile pour 0.25 puis 0.75
Exemple:

L'intervalle interquartile sera donné par quantile(0.75) - quantile(0.25)

On pourra déterminer une borne inférieure et supérieure: 
borne int = quant25 - irq * 1,2
et 
borne sup = quant75 + irq * 1.2
(1.2  à 1.5 sont des coefficients généralement utilisés)


Méthode avec LocalOutlierFactor   de sklearn


Utilisation :


Apres filtrage les valeurs retenues sont en rouge: 












vendredi 19 mai 2023

3 précautions à prendre quand on expose un serveur sur Internet

 Dans le cadre des formations Python, nous sommes amenés à faire des démonstrations de web scraping (aspiration de site) avec scrapy.

J'ai déployé une mini application web sur une VM accessible sur Internet.

Le site: http://lemonlabs.fr

Au bout de quelques heures le fichier de journalisation auth.log se rempli toute la journée avec des tentatives d'intrusion SSH souvent avec l'utilisateur root.

Donc trois précautions à prendre rapidement.

1: Fermer tous les ports.

En dehors des ports web et ssh n'ouvrir aucun port: pas de FTP , serveur de base de données

Une base postgresql ouverte sur Internet ne tiendra pas 10 minutes et elle servira de point d'entrée pour exécuter des scripts malveillants.

2: Utiliser un outil de surveillance.

Pour interdire l'acces à une adresse IP, cette adresse doit être ajoutée au fichier /etc/hosts.deny

Pour automatiser cette tache j'utilise denyhosts : c'est un programme python qui scrute les tentatives d'intrusion et qui met à jour le fichier /etc/hosts.deny  (doc en francais ici)


3:Interdire la connexion à l'utilisateur root.

Pour cela créer un utilisateur quelconque qui servira à se connecter en SSH, puis une fois connecté , utiliser la commende su root pour devenir administrateur. En effet l'utilisateur root est un nom d'utilisateur connu de tous alors que votre nom d'utilisateur est inconnu.

Pour interdire la connexion en root, il faut modifier le fichiers de configuration de sshd:   /etc/ssh/sshd_config

(paramètre PermitRootLogin a faire passer à no) 

Attention pensez à maintenir une autre console ouverte  pour intervenir en cas de probleme. 







 


Exo7 python initiation

 On continue sur notre série. Le corrigé de l'exo6 est en fin d'article.


Enoncé de l'exo7 python initiation.: un nombre est il divisible par 3 ?

Réaliser une fonction qui retourne vrai ou faux à la question : un nombre est-il divisible par 3.

Pour répondre à la question et pour rendre l'exercice amusant, il faudra ajouter chaque digit du nombre et vérifier que leur somme est divisible par 3.

Exemple : 121 est-il divisible par 3 ? : 1+2+1 = 4

4 - 3 = 1  => 121 n'est pas divisible par 3.


123 : 1+2+3 = 6 

6 - 3 - 3 = 0  => 123 est divisible par 3


Solution de l'exo6



def somme_impair(n):
    cp = 0
    for  x in range(1,n*2,2):
        cp+= x
    return cp
 
print(somme_impair(2))  
print(somme_impair(4))  
print(somme_impair(10))        
print(somme_impair(15))  
cache = {}
for x in range(1,20):
    cache[x] = somme_impair(x)
print(cache)    
 
def avec_cache(n):
    if n in cache:
        return cache[n]
    else:
        cache[n] = somme_impair(n)
        return cache[n]
print('avant cache')
print(avec_cache(20000))
print('apres cache')
print(avec_cache(20000))
 
 
 

vendredi 12 mai 2023

Exo-6 python initiation

Le corrigé du numéro 5 est à la fin de l'article.


Enoncé exo6.

1) Faire un fonction qui calcule la somme des N premiers nombres impairs.

Exemple : print(somme_impair(2))    => donnera : 4

La fonction doit utiliser une boucle et non pas une formule directe.

2)Utilisation d'un cache.

A l'aide d'un dictionnaire , conservez les résultats des calculs.

Avant de lancer la boucle de calcul, la fonction doit aller voir dans son cache.

Avec un notebook Jupyter placer une instruction %%timeit dans une cellule pour mesurer l'écart  entre un premier calcul et le second.



Corrigé de l'exercice 5



class Comptage():
    def __init__(self, texte):
        self.dico = {}
        tab_texte = texte.split(' ')
        for mot in tab_texte:  
            if mot.find("'") > 0:
                tab= mot.split("'")
                mot= tab[1]
            self.maj_dico(mot)
 
    def maj_dico(self, mot):
        if mot != '' and len(mot) > 1:
             if mot.lower() in self.dico:
                 self.dico[mot.lower()] += 1
             else:
                 self.dico[mot.lower()] = 1
 
    def liste(self):
        liste_ = []
        for cle, valeur in self.dico.items() :
            liste_.append((cle,valeur ))
        return liste_
 

vendredi 5 mai 2023

Collecte sur le web (3eme article)


 

Revoici, après un petit tour de la toile, des liens ou des projets intéressants .

Numero précédent:

 https://germanlinux.blogspot.com/2023/03/collecte-sur-le-web-2eme-article.html





Python.

Datasciences.

Collaboratif.

Exo 5 Python initiation

Voici l'énoncé de l'exercice de la semaine.

Pour rappel la correction de l'exercice 4 est donné en fin d'article;

Exercice 5:

 Construire une classe qui prend comme argument dans son constructeur une chaine de caractères et retourne une liste de tuple avec le mot et son compteur d'apparition dans le texte.

Exemple:  Comptage('Pourquoi , pourquoi , as tu fait ca , tu n'es pas un as de la route . Je voulais voir une fois quel effet ca fait')

Resultat: 

[('pourquoi', 2), ('as', 2), ('tu', 2), ('fait', 2), ('ca', 2), ('es', 1), ('pas', 1), ('un', 1), ('de', 1), ('la', 1), ('route', 1), ('je', 1), ('voulais', 1), ('voir', 1), ('une', 1), ('fois', 1), ('quel', 1), ('effet', 1)]


Règles de gestion: 

  • Ne tenir compte d'un mot d'une lettre
  • Ne pas compter ce qui est avant un apostrophe

On pourra utiliser le caractère <espace> pour repérer la séparation des mots.
Par simplification, les caractères de ponctuation sont entourés d'espace.

Corrigé de l'exercice exo4 python initiation


def transforme(liste):
    sortie = []
    lgl = len(liste)
    lgtuple = len(liste[0])
    for col in range(lgtuple):
        tup_ = ()
        for row in liste:
            tup_ += row[col],
        sortie.append(tup_)
    return sortie
 
a = [(1, 2), (3, 4), (5,6)]
print (transforme(a))

=> [(1, 3, 5), (2, 4, 6)]

vendredi 28 avril 2023

exo4 python initiation

La correction de l'exercice exo3 python initiation est en bas de page.

 EXO4 python initiation.

Soit une liste de tuple :

[(‘a’ ,’b’) , (‘c’, ‘d’) , (‘e’, ‘f’)]


On souhaite obtenir une liste transposée de la forme suivante :

[(‘a’,’c’,’e’), (‘b’,’d’,’f’)]


1) Ecriture de la fonction transpose(liste) → liste

Sachant que , les tuples ont toujours la même taille au sein de la liste.

La fonction doit fonctionner quelque soit la taille de la liste et des tuples.

Elle retournera une liste.


2) Refactoriser cette fonction de manière à la mettre sous forme de classe et méthode

Ajouter une méthode qui retourne le tuple(nb_element_liste, nb_element_tuple)

(pour notre exemple , cette méthode retournera (3,2)


3) Pour la fonction ou la méthode ajouter de la documentation intégrée.



Correction exo3

def palindrome(mot):
    a = mot[::-1]
    if a == mot:
        return True
    else:
        return False
 
print(palindrome('essai'))
print(palindrome('rotor'))