from numpy import *from matplotlib.pyplot import *## Paramètres choisisTf=1.2      # durée totale en secondesN=1000      # nombre de valeurs## Q1 - Avec arangedt=Tf/(N-1)             # Incrément de temps en secondestemps=arange(0,Tf+dt/2,dt) # liste des instants en secondes## Q2 - Avec une fonction intermédiairedef chirp(temps,f0,Deltafe,T,E0):    def fe(t):        return(f0+t*Deltafe/T)    e=zeros(len(temps)) # e : vecteur nul de même dimension que le vecteur temps    for i in range(len(temps)):        if temps[i]<=T:            e[i]=E0*sin(2*pi*fe(temps[i])*temps[i])    return(e)## APPLICATION - Utilisation de la fonction précédente pour obtenir un tracé identique au sujetf0=1        # Fréquence porteuse en HzT=1         # durée de modulation en secondesDeltafe=30  # Bande de fréquence de modulation en HzE0=1        # Amplitude du signalsignal=chirp(temps,f0,Deltafe,T,E0)plot(temps,signal)title("Signal modulé e(t) avec f0="+str(f0)+"Hz et Deltafe="+str(Deltafe)+"Hz")xlabel("Temps en s")ylabel("Amplitude du signal modulé")xticks(np.arange(0, Tf+0.1, step=0.1))grid()show()## APPLICATION - Importation d'un exemple sous format wav, tracé du signalfrom scipy.io import wavfilefrom scipy.signal import stftimport osos.chdir("D:\Documents(D)\Bellevue\Informatique\eleves\S3\DS\DS 2020\DS4 - Mines - Covid ou CCINP PSI\CCINP")fe, s = wavfile.read("uboot_echolot.wav")Te=1/feN=len(s)temps=arange(0,len(s)*Te,Te)plot(temps,s)title("Exemple de signal reçu par un sonar - "+str(nom_fichier))xlabel("Temps en s")ylabel("Amplitude du son")grid()show()## Q3 - Utilisation de la fonction stftn=256 # Pour l'exemplef,t,S=stft(s,fs=fe,window="hamming",nperseg=n,noverlap=n//2)# Nombre de fft réalisées = len(t) = N//(n//2)  avec N le nombre de frames du signal initial et n le nombre de frames de chaque segment analysé avec recouvrement de n//2# Nombre de fréquences de la FFT : len(f) = n//2+1# Nombre d'amplitudes pour chaque fréquence de la FFT : len(S) = n//2+1# le sujet impose des réponses différentes avec len(f) = len(S) = N//(n//2)pcolormesh(t, f, abs(S),shading='gouraud')ylim(100,2000)show()## Q4 : intérêt du spectrogramme## Q5 : fonction w(t,f,eta)# DT,T et Df sont supposées connuesdef w(t,f,eta):      t_eta=DT/2+eta*T      f_eta=Df/2+eta*Df      if abs(t-t_eta)<DT/2 and abs(f-f_eta)<Df/2:            return(1)      else:            return(0)## Q6 : fonction enveloppe(eta,S,p,dt,df)def enveloppe(eta,S,p,dt,df):      P_eta=0      for i in range(S.shape[0]):       # ou range(len(t))            for j in range(S.shape[1]): # ou range(len(f))                  P_eta=p[i,j]*S[i,j]*w(t[i],f[j],eta)*dt*df## Q7 : fonction normalisation(P)def normalisation(P):      return( (P-min(P)) / (max(P)-min(P)) )## APPLICATION : test de la fonction précédentea=array([0,1,5,8,-3,0.2])print("\n Q7:")print("vecteur a =",a)print("vecteur a normalisé = ",normalisation(a))## Q8 :Arbre de la figure 5a## Q9 : Groupe pour A à partir de l'arbre 5a## Q10 : fonction indices_aleatoires(m,p_var)from random import randrangedef indices_aleatoires(m,p_var):      liste_indices_aleatoires=[] # Initialisation de la liste (vide pour l'utilisation de append)      for i in range(p_var):            indice=randrange(m)            while indice in liste_indices_aleatoires: # On boucle tant que l'indice est déjà dans la liste                  indice=randrange(m)            liste_indices_aleatoires.append(indice)   # Une fois le nouvel indice différent trouvé, on le rajoute à la liste      return liste_indices_aleatoiresprint("Liste de 4 indices aléatoires différents entre 0 et 4 (inclus) :",indices_aleatoires(5,4))## Q11 : fonction [gauche,droite]=test_separation(ind, val, donnees)def test_separation(ind, val, donnees):      gauche, droite = [],[]      for i in range(donnees.shape[0]):            if donnees[i,ind]<val:                  gauche.append(donnees[i,:])            else:                  droite.append(donnees[i,:])      return [gauche,droite]## Application avec l'exemple du sujet sur les 4 premières lignesdonnees = array([ [0.96,0.95,0.06,0.08,0.84,0.74,0.67,0.31,0.61,0.61,1],                  [0.16,0.43,0.39,0.72,0.99,0.95,0.54,0.44,0.27,0.04,0],                  [0.46,0.32,0.38,0.89,0.53,0.56,0.24,0.02,0.33,0.14,1],                  [1.00,0.67,0.18,0.89,0.80,0.73,0.91,0.76,0.79,0.35,1],                  [0.96,0.16,0.75,0.72,0.46,0.53,0.49,0.92,0.50,0.83,0],                  [0.88,0.90,0.46,0.57,0.92,0.72,0.49,0.22,0.32,0.70,0],                  [0.91,0.27,0.91,0.31,0.96,0.71,0.50,0.52,0.65,0.59,0],                  [0.21,0.51,0.93,0.62,0.08,0.82,0.73,0.91,0.19,0.74,0],                  [0.65,0.27,0.23,0.88,0.11,0.52,0.85,0.24,0.21,0.88,1],                  [0.72,0.03,0.36,0.17,0.67,0.08,0.95,0.03,0.73,0.02,1]                  ])[gauche, droite]= test_separation(1, 0.5, donnees)print("Données avant séparation:")print(donnees)print("séparation par la colonne 1 avec 0.5 comme valeur de comparaison:")print("Partie gauche:")print(gauche)print("Partie droite:")print(droite)## Q12 : 5 instructions à compléter dans la fonction Gini_groupesdef Gini_groupes ( groupes ) :      #nombre de données total      n_donnees = len(groupes[0])+len(groupes[1])# instruction 1      gini = 0.0 #somme pondérée des indices Gini de chaque groupe      for donnees in groupes :            taille = len(donnees) # taille d’un groupe            if taille != 0 :                  gini_gr = 0.0                  for val in [ 0 , 1 ] :                        p=0                        for ligne in donnees :                              if ligne[-1] == val :                                    p=p+1  # instruction 2                        p=p/taille      # instruction 3                        gini_gr += 1-p**2  # instruction 4                  # ajout de gini_gr avec le poids relatif                  gini += gini_gr * taille / n_donnees # instruction 5      return giniprint('gini=',Gini_groupes([gauche, droite]))## Q13 : fonction feuille(data)def feuille(data):      nb0,nb1=0,0      for i in range(len(data)):            if data[i][-1]==0:                  nb0+=1            else:                  nb1+=1      if nb0>nb1:            return 0      else:            return 1print("feuille(donnees)=",feuille(donnees))## Q14 : Condition de la fonction récursive "construit"def construit ( arbre , sep_max , taille_min , p_var , ind_rec ) :      gauche , droite = arbre[2] , arbre[3]      if gauche==[] or droite==[] : # condition 1            valeur = feuille( gauche + droite )            arbre[2] = valeur            arbre[3] = valeur            return # On ne retourne aucune valeur car arbre est modifié directement dans la fonction      if ind_rec==sep_max : # condition 2            arbre[2] , arbre[3] = feuille( gauche ) , feuille( droite )            return      if len(gauche)< taille_min: # condition 3            arbre[2] = feuille( gauche )      else :            arbre[2] = separe( gauche , p_var )            construit( arbre[2] , sep_max , taille_min , p_var , ind_rec +1)      if len(droite)< taille_min: # condition 4            arbre[3] = feuille ( droite )      else :            arbre[3] = separe( droite , p_var )            construit( arbre[3] , sep_max , taille_min , p_var , ind_rec +1)def separe ( donnees , p_var ) :      # Initialisation des paramètres      b_ind , b_val , b_gini = inf , inf , inf      b_g , b_d = [ ] , [ ]      m = len ( donnees [0] ) - 1      # extraction d'indices aléatoires      ind_var = indices_aleatoires (m, p_var )      for ind in ind_var :            for ligne in donnees :                  # séparation des données en deux groupes                  [ gauche , droite ]= test_separation ( ind , ligne [ ind ] , donnees )                  gini = Gini_groupes ( [ gauche , droite ] )                  if gini < b_gini :                        b_ind , b_val , b_gini = ind , ligne [ ind ] , gini                        b_g , b_d = gauche , droite      return [ b_ind , b_val , b_g , b_d ]def construire_arbre(data_train,sep_max,taille_min,p_var):      arbre=separe(data_train,p_var)      construit(arbre,sep_max,taille_min,p_var,1)      return arbreprint(construire_arbre(donnees,100,0,4))## Q16 : 4 instructions de prediction(arbre,donnee)def prediction(arbre,donnee):      [ind,val,gauche,droite]=arbre      if donnee[ind]<val:            if isinstance(gauche,list):                  return prediction(gauche,donnee) #instruction1:            else:                  return gauche      else:            if isinstance(droite,list):                  return prediction(droite,donnee) #instruction1:#instruction3            else:                  return droite##Q17: fonction random_forest(data_train,data_test,sep_max,taille_min,n_arbres,p_var)def random_forest(data_train,data_test,sep_max,taille_min,n_arbres,p_var)      foret=construire_foret(data_train, sep_max, taille_min, p_var, ind_rec, n_arbres)      classes=[]      for donnee in data_test:          n = 0          for arbre in foret:              n = n + prediction(arbre,donnees)          if n <= (n_arbres//2) :              classes.append(0)          else:              classes.append(1)      return classes