{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#import des modules nécessaires au fonctionnement du programme \n\n\n# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\n\n\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\n\nfrom os import listdir\nprint(listdir(\"../input\"))\n\nimport warnings\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\nwarnings.filterwarnings(\"ignore\", category=UserWarning)\nwarnings.filterwarnings(\"ignore\", category=FutureWarning)\n# Any results you write to the current directory are saved as output.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","id":"wnOA7fz4eUIa","execution":{"iopub.status.busy":"2022-05-10T22:11:51.896892Z","iopub.execute_input":"2022-05-10T22:11:51.897673Z","iopub.status.idle":"2022-05-10T22:11:52.742676Z","shell.execute_reply.started":"2022-05-10T22:11:51.897635Z","shell.execute_reply":"2022-05-10T22:11:52.741813Z"},"collapsed":true,"jupyter":{"outputs_hidden":true,"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ouverture des données \ntrain = pd.read_csv(\"../input/LANL-Earthquake-Prediction/train.csv\", nrows=20000000,\n                    dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64})#lecture des 20M premiers indices pour les observations afin que ce soit plus facile à ouvrir\ntrain.head(5)\n\ntrain.rename({\"acoustic_data\": \"signal\", \"time_to_failure\": \"quaketime\"}, axis=\"columns\", inplace=True)\ntrain.head(5)\n#Les valeurs sont placées dans un tableau où sont indexés le signal et le quaketime, à savoir le temps avant le prochain tremblement de terre, pour chacun des indices d'acquisition","metadata":{"id":"nP4YWObeeUIh","execution":{"iopub.status.busy":"2022-05-10T22:12:02.586196Z","iopub.execute_input":"2022-05-10T22:12:02.587114Z","iopub.status.idle":"2022-05-10T22:12:07.049274Z","shell.execute_reply.started":"2022-05-10T22:12:02.587067Z","shell.execute_reply":"2022-05-10T22:12:07.048438Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Introduction","metadata":{"id":"4gQHrnS0eUIi"}},{"cell_type":"markdown","source":"L’objectif de ce projet est de prédire le temps restant jusqu’à ce que le prochain séisme ait lieu à un endroit donné en fonction d’un segment d’enregistrement sismique.\n\nPour ce faire, nous disposons d'un signal sismique artificiel enregistrés dans le temps et à une position fixe : ils constituent notre jeu de données, ce signal couvre plusieurs séismes. À noter que les temps d’enregistrement sont des échantillons discrets du temps. Par la suite, les temps d’enregistrement échantillonnés seront désignés comme les indices du signal.\n\n## Visualisation du jeu de données\n\nOn visualise les données à partir desquelles nous allons réaliser l'apprentissage.","metadata":{"id":"CpAGZSd5eUIk"}},{"cell_type":"code","source":"fig, ax = plt.subplots(2,1, figsize=(20,12))\nax[0].plot(train.index.values, train.quaketime.values, c=\"darkred\")\nax[0].set_title(\"Temps avant le prochain séisme sur 20M d'indices\")\nax[0].set_xlabel(\"Indice\")\nax[0].set_ylabel(\"Temps avant le séisme en ms\");\nax[1].plot(train.index.values, train.signal.values, c=\"mediumseagreen\")\nax[1].set_title(\"Signal acoustique sur 20M d'indices\")\nax[1].set_xlabel(\"Indices\")\nax[1].set_ylabel(\"Signal Acoustique\");","metadata":{"id":"L3SfHMAEeUIm","execution":{"iopub.status.busy":"2022-05-10T22:12:07.553366Z","iopub.execute_input":"2022-05-10T22:12:07.553646Z","iopub.status.idle":"2022-05-10T22:12:14.750820Z","shell.execute_reply.started":"2022-05-10T22:12:07.553617Z","shell.execute_reply":"2022-05-10T22:12:14.749794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Une courbe du temps restant avant le prochain séisme est associée au signal accoustique en fonction de l’indice d'enregistrement. On observe qu'il y a un délai entre le signal acoustique et le temps de prévision.\n\n### Visualisation du jeu de données de validation\n\nOn visualise les segments que l'on aura par la suite à associer avec une prédiction de temps jusqu'à un séisme.","metadata":{"id":"AZTUC2PteUIn"}},{"cell_type":"code","source":"test_path = \"../input/LANL-Earthquake-Prediction/test/\"\ntest_files = listdir(\"../input/LANL-Earthquake-Prediction/test\")\nfig, ax = plt.subplots(4,1, figsize=(20,25))\n\nfor n in range(4):\n    seg = pd.read_csv(test_path  + test_files[n])\n    ax[n].plot(seg.acoustic_data.values, c=\"mediumseagreen\")\n    ax[n].set_xlabel(\"Indice\")\n    ax[n].set_ylabel(\"Signal\")\n    ax[n].set_ylim([-300, 300])\n    ax[n].set_title(\"Test {}\".format(test_files[n]));","metadata":{"id":"ELGdBTD1eUIn","execution":{"iopub.status.busy":"2022-05-10T22:12:16.114239Z","iopub.execute_input":"2022-05-10T22:12:16.114485Z","iopub.status.idle":"2022-05-10T22:12:17.455558Z","shell.execute_reply.started":"2022-05-10T22:12:16.114459Z","shell.execute_reply":"2022-05-10T22:12:17.454689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"L’objectif du projet est de retrouver pour chaque signal sismique le temps restant avant le prochain tremblement de terre. Pour résoudre cette problématique, nous allons entraîner notre algorithme sur le jeu de données d’apprentissage, puis nous utiliserons un jeu de validation pour le tester.","metadata":{"id":"UD6c_mIkeUIo"}},{"cell_type":"markdown","source":"# Analyse du jeu de données","metadata":{"id":"rJ0XKEMqeUIp"}},{"cell_type":"markdown","source":"## Analyse de la taille des jeux de données\n\nAfin d'en savoir plus sur les jeux de données que nous allons utiliser, nous nous sommes tout d'abord penchées sur l'étude de leur taille. \n\n### Détermination de la taille du signal d'apprentissage\n\nOn cherche à déterminer la longueur du signal sur lequel nous allons réaliser l'apprentissage.","metadata":{"id":"mVNJrSRaeUIq"}},{"cell_type":"code","source":"train = pd.read_csv(\"../input/LANL-Earthquake-Prediction/train.csv\",\n                    dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64})\nprint(len(train))","metadata":{"execution":{"iopub.status.busy":"2022-04-30T18:38:44.157478Z","iopub.status.idle":"2022-04-30T18:38:44.157837Z","shell.execute_reply.started":"2022-04-30T18:38:44.157632Z","shell.execute_reply":"2022-04-30T18:38:44.157656Z"},"id":"mxfzwgTseUIr","outputId":"d33bf23f-962f-4ea5-bfef-16e24555bd46","jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Ce jeu de données a une longueur de 629 145 480 indices.","metadata":{"id":"KQkd1ezheUIr"}},{"cell_type":"markdown","source":"### Détermination de la taille des segments de test\n\nOn cherche à déterminer la longueur des segments qui nous sont donnnés en tant que test.","metadata":{"id":"QrU5oz0_eUIs"}},{"cell_type":"code","source":"test_path = \"../input/LANL-Earthquake-Prediction/test/\"\n\ntest_files = listdir(\"../input/LANL-Earthquake-Prediction/test\")\n\n\nseg1 = pd.read_csv(test_path  + test_files[1])\nseg2 = pd.read_csv(test_path  + test_files[1])\nseg3 = pd.read_csv(test_path  + test_files[1])\nseg4 = pd.read_csv(test_path  + test_files[1])\n\nprint (\"La durée du premier segment enregistré est de : \",len(seg1),\"indices\",\"\\n\",\"La durée moyenne des 4 premiers segments enregistrés est de : \",(len(seg1)+len(seg2)+len(seg3)+len(seg4))/4, \"indices\")","metadata":{"execution":{"iopub.status.busy":"2022-04-30T18:38:44.159067Z","iopub.status.idle":"2022-04-30T18:38:44.159409Z","shell.execute_reply.started":"2022-04-30T18:38:44.159225Z","shell.execute_reply":"2022-04-30T18:38:44.15925Z"},"id":"eUP939XAeUIs","jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"On constate que la taille des segments à associer est de 150 000 indices pour chaque segment test.","metadata":{"id":"xG5fcwobeUIt"}},{"cell_type":"markdown","source":"### Recherche du temps entre 2 séismes\n\nNous avons cherché à trouver le temps qui séparait deux séismes dans le fichier de données, malheureusement le fichier étant trop lourd, nous n'avons pas réussi à charger des portions assez grandes pour déterminer cette valeur, le programme que nous avions écrit figure cependant dans la case suivante. Nous pouvons tout de même constater que l'écart entre les séismes est significativement supérieur à 40 millions d'indices d'acquisition ce qui est très significativement plus grand que la taille de nos échantillons test.","metadata":{"id":"ruvFYQaBeUIt"}},{"cell_type":"code","source":"%list_i_eq=np.zeros(20) \n%eq=0 \n%for i in range (len(train.index.values)-1):\n%    if train.quaketime.values[i]==0:\n%        list_i_eq[eq]=i\n%        eq+=1\n%print(list_i_eq)","metadata":{"id":"seo8F2UdeUIt","execution":{"iopub.status.busy":"2022-05-04T09:26:25.968799Z","iopub.execute_input":"2022-05-04T09:26:25.970106Z","iopub.status.idle":"2022-05-04T09:27:50.771119Z","shell.execute_reply.started":"2022-05-04T09:26:25.970054Z","shell.execute_reply":"2022-05-04T09:27:50.769576Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualisation des données : zoom sur le signal temporel**","metadata":{"id":"BykU70lneUIu"}},{"cell_type":"code","source":"train = pd.read_csv(\"../input/LANL-Earthquake-Prediction/train.csv\", nrows=20000000,\n                    dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64})#lecture des 20M premiers indices pour les observations afin que ce soit plus facile à ouvrir\ntrain.head(5)\n\ntrain.rename({\"acoustic_data\": \"signal\", \"time_to_failure\": \"quaketime\"}, axis=\"columns\", inplace=True)\ntrain.head(5)\n#Les valeurs sont placées dans un tableau où sont indexés le signal et le quaketime, a savoir le temps avant le prochain tremblement de terre, pour chacun des indices d'acquisition\n\nfig, ax = plt.subplots(3,1,figsize=(20,18))\nax[0].plot(train.index.values[0:50000], train.quaketime.values[0:50000], c=\"Red\")\nax[0].set_xlabel(\"Indice\")\nax[0].set_ylabel(\"Temps jusqu'au prochain tremblement de terre\")\nax[0].set_title(\"A quoi ressemble le signal du temps jusqu'au prochain tremblement de terre à plus petite échelle\")\nax[1].plot(train.index.values[0:49999], np.diff(train.quaketime.values[0:50000]))\nax[1].set_xlabel(\"Indice\")\nax[1].set_ylabel(\"Différence entre deux indices du signal\")\nax[1].set_title(\"Les sauts sont-ils les mêmes?\")\nax[2].plot(train.index.values[0:4000], train.quaketime.values[0:4000])\nax[2].set_xlabel(\"Indices de 0 à 4000\")\nax[2].set_ylabel(\"Temps jusqu'au tremblement de terre\")\nax[2].set_title(\"Comment la prédiction temporelle varie lors de la première marche?\");\n","metadata":{"id":"deqrd461eUIu","execution":{"iopub.status.busy":"2022-05-10T22:12:28.979304Z","iopub.execute_input":"2022-05-10T22:12:28.980034Z","iopub.status.idle":"2022-05-10T22:12:34.530696Z","shell.execute_reply.started":"2022-05-10T22:12:28.979991Z","shell.execute_reply":"2022-05-10T22:12:34.529880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"À l’échelle de temps d’un séisme, c’est-à-dire environ quelques dizaines de millions d'indices, la courbe représentant le temps restant avant le prochain tremblement de terre est en dents de scie, autrement dit elle est constituée de portions de courbes affines.\n\nToutefois, si on passe à une échelle de temps bien inférieure telle qu’une fenêtre de taille 10 000 index, on observe que les pentes décroissantes sont en réalités constituées de sauts discontinus.\n\nEn étudiant le problème, on a pu comprendre que ces sauts étaient dus à la necessité de mettre en mémoire les informations pendant un certain temps ce qui entraine un arrêt périodique de l'acquisition. \n\nEn supposant que le pas des sauts est à peu près constant, nous cherchons l’indice du premier saut après l’apparition du séisme.\n\n### Recherche de la longueur entre 2 sauts dans le signal temporel\n","metadata":{"id":"7yQaaULaeUIu"}},{"cell_type":"code","source":"cran=np.diff(train.quaketime.values[0:10000])\nfor i in range (8000):\n    if cran[i]<-0.0008: \n        a=i\nprint(\"Les sauts sont tous les\",a,\"indices\")\n    ","metadata":{"id":"xZS2wVlLeUIv","execution":{"iopub.status.busy":"2022-05-10T22:12:34.800860Z","iopub.execute_input":"2022-05-10T22:12:34.801150Z","iopub.status.idle":"2022-05-10T22:12:34.811127Z","shell.execute_reply.started":"2022-05-10T22:12:34.801120Z","shell.execute_reply":"2022-05-10T22:12:34.810434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Sur la pente décroissante de la courbe représentant le temps restant avant le prochain tremblement de terre en fonction de l’index, l’occurrence des sauts est de 4 094 indices.","metadata":{"id":"tA7CdlE7eUIv"}},{"cell_type":"markdown","source":"### Bilan de l'analyse du jeu de données\nRappelons que l’objectif du projet est de connaître le temps restant avant le prochain séisme pour chacun des enregistrements sismiques constituant le jeu de données de test. Pour des raisons pratiques, nous ferons par la suite le choix que l’algorithme soit conçu pour apprendre sur des sous jeux de données de même taille que celui de test.\n\nD’après la sous-partie 1), la taille du jeu de test est de 150 000 index. Nous découpons donc le jeu de données (le signal continue) en jeux d'apprentissages (sous-signaux) de taille de 150 000 index.\n\n### Préparation des sous jeux de données\n\nLe jeu d’apprentissage étant constitué de petites parties du signal continu, il est nécessaire de lui associer un temps avant le prochain tremblement de terre. On le choisit de telle sorte qu’il corresponde au temps avant séisme de l’index le plus élevé de notre segment. Ainsi chaque sous jeu de données acoustiques est associé à un temps unique. Ce choix est fait en considérant qu'il existe une différence négligeable entre le temps jusqu'au prochain séisme du début du signal et celui de la fin du signal, le sous-signal étant d'une taille faible. \n\n\nCe vecteur contenant les temps avant le prochain séisme pour chaque segment de signal sismique est utile pour la comparaison avec celle donnée par le modèle. Comme nous le verrons dans la partie suivante, l’algorithme apprend à l’aide du modèle de prévision sur le jeu de données et de la vérification, en minimisant l'écart entre ces deux valeurs.","metadata":{"id":"Znxcjix2eUIv"}},{"cell_type":"markdown","source":"### Découpage des signaux d'apprentissage\n\nOn choisit n signaux pour l'apprentissage de taille 150000.\nOn a n>nrows/150000.\nOn ne coupe alors pas à la suite les signaux mais on prend des morceaux qui se superposent pour pouvoir apprendre de manière plus précise.\nOn traites les n signaux indépendamment en implémentant une matrice de paramètres.\n\nOn décide de ne pas charger toutes les données mais seulement de prendre à chaque fois le découpage du signal qui nous intéresse, dans un soucis d'utilisation de la mémoire allouée et donc de faisabilité.","metadata":{"id":"j75p1Q-teUIw"}},{"cell_type":"markdown","source":"## Comment effectuer le découpage?\n\nOn sélectionne directement à la lecture les indices qui nous intéressent, de cette manière on ne garde jamais en mémoire les sous-signaux précédemment traités.","metadata":{"id":"ZVEtitUgeUIw"}},{"cell_type":"code","source":"#Ouverture d'un sous-signal commençant à l'indice \"ind\" et de longueur \"taille\"\nind=10 #index du début de signal d'intérêt\ntaille=20 #taille du signal\nrownumberList=[i for i in range (ind,ind+taille)]\ntrain = pd.read_csv(\"../input/LANL-Earthquake-Prediction/train.csv\", skiprows=ind, nrows=taille,\n                    dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64})\nprint(train)","metadata":{"id":"o6JS2TLieUIw","execution":{"iopub.status.busy":"2022-05-10T22:12:39.217157Z","iopub.execute_input":"2022-05-10T22:12:39.217578Z","iopub.status.idle":"2022-05-10T22:12:39.232064Z","shell.execute_reply.started":"2022-05-10T22:12:39.217549Z","shell.execute_reply":"2022-05-10T22:12:39.231396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Paramètres choisis pour l'étude du signal\n\nAfin de caractériser une « petite partie » de signal et lancer l'apprentissage, il nous faut choisir des paramètres de caractérisation. \n\nLes paramètres que nous avons choisi sont les suivants: \n\n- min, max, l'écart-type, la moyenne \n\n- max-min \n\n- somme\n\n- quantile (5/95, 25/75)\n\n- TF : même paramètres sur la TF du signal\n\n\n\nPour l’instant, nous mettons tous les paramètres trouvés pertinents quitte à ce que le coefficient de la régression soit faible (proche de 0).\n","metadata":{"id":"Zxw2j08teUIx"}},{"cell_type":"markdown","source":"On crée alors une fonction permettant de stocker tous ces paramètres calculés dans une liste. Il s'agit de la fonction suivante : **signal_parameters**","metadata":{"id":"_D3YS2T_eUIx"}},{"cell_type":"code","source":"def signal_parameters(ind,taille):\n    parameters_matrix=np.zeros(20)\n    signal = pd.read_csv(\"../input/LANL-Earthquake-Prediction/train.csv\", skiprows=ind, nrows=taille,\n                    dtype={'acoustic_data': np.int16, 'time_to_failure': np.float64})\n    signal_fft=np.real(np.fft.fft(signal)[:,0])\n    parameters_matrix[0]=np.min(signal)[0]\n    parameters_matrix[1]=np.max(signal)[0]\n    parameters_matrix[2]=np.mean(signal)[0]\n    parameters_matrix[3]=np.std(signal)[0]\n    parameters_matrix[4]=parameters_matrix[1]- parameters_matrix[0]\n    parameters_matrix[5]=np.sum(signal)[0]\n    parameters_matrix[6]=np.quantile(signal,0.25)\n    parameters_matrix[7]=np.quantile(signal,0.75)\n    parameters_matrix[8]=np.quantile(signal,0.05)\n    parameters_matrix[9]=np.quantile(signal,0.95)\n    parameters_matrix[10]=np.min(signal_fft)\n    parameters_matrix[11]=np.max(signal_fft)\n    parameters_matrix[12]=np.mean(signal_fft)\n    parameters_matrix[13]=np.std(signal_fft)\n    parameters_matrix[14]=parameters_matrix[11]- parameters_matrix[10]\n    parameters_matrix[15]=np.sum(signal_fft)\n    parameters_matrix[16]=np.quantile(signal_fft,0.25)\n    parameters_matrix[17]=np.quantile(signal_fft,0.75)\n    parameters_matrix[18]=np.quantile(signal_fft,0.05)\n    parameters_matrix[19]=np.quantile(signal_fft,0.95)\n    time_to_failure=np.min(signal)[1]\n    \n    return parameters_matrix,time_to_failure","metadata":{"id":"TF6JIBF0eUIy","execution":{"iopub.status.busy":"2022-05-10T22:12:42.906702Z","iopub.execute_input":"2022-05-10T22:12:42.907184Z","iopub.status.idle":"2022-05-10T22:12:42.920443Z","shell.execute_reply.started":"2022-05-10T22:12:42.907125Z","shell.execute_reply":"2022-05-10T22:12:42.919597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Maintenant que nous avons créé une fonction permettant d'obtenir et de stocker tous les paramètres d'un signal, il suffit de l'utiliser pour obtenir les paramètres de tous nos sous-signaux d'apprentissage et les stocker pour ensuite apprendre. ","metadata":{"id":"uPIeYKejeUIy"}},{"cell_type":"code","source":"n=100 #nombre de signaux d'apprentissage, pour 100 signaux, le programme met environ 10 min à tourner\nparameters = []\nsize = 150000\npas=size//2\ntime_to_failure = []\nfor i in range (n):\n    ind=i*pas\n    A,B=signal_parameters(ind,size)\n    parameters.append(A)\n    time_to_failure.append(B)\n","metadata":{"id":"YuwXTwoLeUIz","execution":{"iopub.status.busy":"2022-05-10T22:12:47.195469Z","iopub.execute_input":"2022-05-10T22:12:47.195908Z","iopub.status.idle":"2022-05-10T22:13:41.533601Z","shell.execute_reply.started":"2022-05-10T22:12:47.195854Z","shell.execute_reply":"2022-05-10T22:13:41.532656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**AFFICHAGE DES 5 PREMIERS PARAMETRES** \n\nOn affiche les 5 premiers signaux d'apprentissage c'est à dire le minimum, le maximum, la std, la moyenne et la différence min-max, ainsi que le temps jusqu'au prochain séisme associé.","metadata":{"id":"g5EYE_vueUIz"}},{"cell_type":"code","source":"fig, ax = plt.subplots(3,2,figsize=(20,18))\nplt.subplot(321)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètre\")\nplt.title(\"Minimum\");\nplt.plot([x[0] for x in parameters])\nplt.subplot(322)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètre\")\nplt.title(\"Maximum\");\nplt.plot([x[1] for x in parameters])\nplt.subplot(323)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètre\")\nplt.title(\"Ecart type\");\nplt.plot([x[2] for x in parameters])\nplt.subplot(324)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètre\")\nplt.title(\"Moyenne\");\nplt.plot([x[3] for x in parameters])\nplt.subplot(325)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètre\")\nplt.title(\"Maximum-Minimum\");\nplt.plot([x[4] for x in parameters])\nplt.subplot(326)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètre\")\nplt.title(\"Temps jusqu'au prochain tremblement de terre\");\nplt.plot(time_to_failure)","metadata":{"id":"vjFVaFz5eUIz","execution":{"iopub.status.busy":"2022-05-10T22:14:16.633770Z","iopub.execute_input":"2022-05-10T22:14:16.634229Z","iopub.status.idle":"2022-05-10T22:14:17.673686Z","shell.execute_reply.started":"2022-05-10T22:14:16.634191Z","shell.execute_reply":"2022-05-10T22:14:17.672876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Début de l'apprentissage (régression linéaire)\n## Premier essai","metadata":{"id":"IsDcen4YeUIz"}},{"cell_type":"markdown","source":"Input = Signal accoustique\n\nOutput = Time to failure\n\nOn utilise un modèle de régression linéaire pour réaliser l'apprentissage à l'aide de nos paramètres calculés.","metadata":{"id":"T6BHUWxQeUI0"}},{"cell_type":"code","source":"import torch \nfrom torch.autograd import Variable \n  \nx_data = Variable(torch.Tensor(parameters)) \ny_data = Variable(torch.Tensor(time_to_failure)) \n","metadata":{"id":"YjTPnVgeeUI0","execution":{"iopub.status.busy":"2022-05-10T22:14:23.369186Z","iopub.execute_input":"2022-05-10T22:14:23.369635Z","iopub.status.idle":"2022-05-10T22:14:24.746814Z","shell.execute_reply.started":"2022-05-10T22:14:23.369604Z","shell.execute_reply":"2022-05-10T22:14:24.745902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class LinearRegressionModel(torch.nn.Module): \n  \n    def __init__(self): \n        super(LinearRegressionModel, self).__init__() \n        self.linear = torch.nn.Linear(20, 1)  \n  \n    def forward(self, x): \n        y_pred = self.linear(x) \n        return y_pred \n    \nlr=0.001\nour_model = LinearRegressionModel()   \ncriterion = torch.nn.MSELoss() \noptimizer = torch.optim.SGD(our_model.parameters(), lr) \n  \nfor epoch in range(5000): \n    optimizer.zero_grad() \n    pred_y = our_model(x_data) \n    loss = criterion(pred_y, y_data) \n    loss.backward() \n    optimizer.step() \n    print('epoch {}, loss {}'.format(epoch, loss.item())) \n  \n","metadata":{"id":"6ryhvPY7eUI0","execution":{"iopub.status.busy":"2022-05-10T22:14:27.976852Z","iopub.execute_input":"2022-05-10T22:14:27.977142Z","iopub.status.idle":"2022-05-10T22:14:30.988584Z","shell.execute_reply.started":"2022-05-10T22:14:27.977110Z","shell.execute_reply":"2022-05-10T22:14:30.987786Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**ERREUR**\nCe plan d'apprentissage ne fonctionne pas, on peut observer un problème au niveau des données, la loss donne NaN. Cela est probablement dû a des divisions 0/0 mal gérées, c'est pour cela qu'on observe une divergence avant d'obtenir les NaN. \n\nOn va essayer de transformer les données en les normalisant afin d'éviter ce problème.\n\nPour cela on utilise un module de normalisation déjà codé qui permet de normaliser les caractéristiques en supprimant la moyenne et en mettant à l'echelle la variance unitaire. Les valeurs sont calculées comme z=(x-u)/s avec u la moyenne et s l'écart type des échantillons d'apprentissage.\n\n### Normalisation du signal","metadata":{"id":"5r3h_TadeUI1"}},{"cell_type":"code","source":"#Normalisation du signal\nfrom sklearn.preprocessing import StandardScaler \nsc = StandardScaler()\n\nparameters_fit=sc.fit_transform(parameters)\nx_data_fit=Variable(torch.Tensor(parameters_fit)) ","metadata":{"id":"BBMp7eaPeUI1","execution":{"iopub.status.busy":"2022-05-10T22:14:41.749096Z","iopub.execute_input":"2022-05-10T22:14:41.749839Z","iopub.status.idle":"2022-05-10T22:14:42.614295Z","shell.execute_reply.started":"2022-05-10T22:14:41.749780Z","shell.execute_reply":"2022-05-10T22:14:42.613418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Affichage des paramètres fits  (normalisés)\n\nOn affiche les paramètres une fois normalisés ainsi que les temps jusqu'au prochain séisme associé.","metadata":{"id":"QebivfKCeUI1"}},{"cell_type":"code","source":"fig, ax = plt.subplots(3,2,figsize=(20,18))\nplt.subplot(321)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètres\")\nplt.title(\"Minimum\");\nplt.plot([x[0] for x in parameters_fit])\nplt.subplot(322)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètres\")\nplt.title(\"Maximum normalisé\");\nplt.plot([x[1] for x in parameters_fit])\nplt.subplot(323)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètres\")\nplt.title(\"Ecart type normalisé\");\nplt.plot([x[2] for x in parameters_fit])\nplt.subplot(324)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètres\")\nplt.title(\"Moyenne  normalisée\");\nplt.plot([x[3] for x in parameters_fit])\nplt.subplot(325)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètres\")\nplt.title(\"Maximum-Minimum normalisé\");\nplt.plot([x[4] for x in parameters_fit])\nplt.subplot(326)\nplt.xlabel(\"Signal d'apprentissage\")\nplt.ylabel(\"Paramètres\")\nplt.title(\"Temps jusqu'au prochain tremblement de terre\");\nplt.plot(time_to_failure)","metadata":{"id":"wyTVVv_IeUI1","execution":{"iopub.status.busy":"2022-05-10T22:14:47.104305Z","iopub.execute_input":"2022-05-10T22:14:47.104594Z","iopub.status.idle":"2022-05-10T22:14:48.146626Z","shell.execute_reply.started":"2022-05-10T22:14:47.104562Z","shell.execute_reply":"2022-05-10T22:14:48.145762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Deuxième essai de Regression linéaire","metadata":{"id":"TcSELEWEeUI1"}},{"cell_type":"code","source":"lr=0.01\nour_model = LinearRegressionModel()   \ncriterion = torch.nn.MSELoss() \noptimizer = torch.optim.SGD(our_model.parameters(), lr) \n  \nfor epoch in range(5000): \n    optimizer.zero_grad() \n    pred_y = our_model(x_data_fit) \n    loss = criterion(pred_y, y_data) \n    loss.backward() \n    optimizer.step() \n    print('epoch {}, loss {}'.format(epoch, loss.item())) \n  \n","metadata":{"id":"WejDO8HmeUI2","execution":{"iopub.status.busy":"2022-05-10T22:14:53.889956Z","iopub.execute_input":"2022-05-10T22:14:53.890231Z","iopub.status.idle":"2022-05-10T22:14:57.125972Z","shell.execute_reply.started":"2022-05-10T22:14:53.890204Z","shell.execute_reply":"2022-05-10T22:14:57.125123Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"On observe désormais une loss qui fonctionne, il y a bien apprentissage via le jeu de paramètres.","metadata":{"id":"emgCv0PjeUI2"}},{"cell_type":"markdown","source":"## Test du modèle sur un jeu de validation\n\nOn crée un jeu de données de validation à l'aide du signal d'entrée, pour cela on découpe le signal selon un autre sous jeux de données que celui initialement défini pour l'apprentissage. Puis on test le modèle obtenu sur ce jeu de données.","metadata":{"id":"EaAXs97xeUI2"}},{"cell_type":"code","source":"n_valid=100 #nombre de signaux de validation\nparameters_valid = []\nsize = 150000\npas=size//2\ntime_to_failure_valid = []\npas_initial=1000000 #pour ne pas utiliser le même jeu que l'apprentissage\nfor i in range (n_valid):\n    ind=i*pas+pas_initial\n    A,B=signal_parameters(ind,size)\n    parameters_valid.append(A)\n    time_to_failure_valid.append(B)","metadata":{"id":"YRH91jxeeUI2","execution":{"iopub.status.busy":"2022-05-10T22:14:59.795479Z","iopub.execute_input":"2022-05-10T22:14:59.796329Z","iopub.status.idle":"2022-05-10T22:16:06.554593Z","shell.execute_reply.started":"2022-05-10T22:14:59.796286Z","shell.execute_reply":"2022-05-10T22:16:06.553812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_data_valid_fit = Variable(torch.Tensor(sc.fit_transform(parameters_valid))) \ny_data_valid = Variable(torch.Tensor(time_to_failure_valid)) \npred_y_valid = our_model(x_data_valid_fit) \nloss = criterion(pred_y_valid, y_data_valid) \n\nprint('loss {}'.format(loss.item()))","metadata":{"id":"YkttAa5reUI2","execution":{"iopub.status.busy":"2022-05-10T22:16:22.467870Z","iopub.execute_input":"2022-05-10T22:16:22.468163Z","iopub.status.idle":"2022-05-10T22:16:22.476454Z","shell.execute_reply.started":"2022-05-10T22:16:22.468135Z","shell.execute_reply":"2022-05-10T22:16:22.475865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Pour pouvoir observer l'efficacité de notre modèle, on compare les valeurs obtenues à l'aide de ce dernier et les valeurs données par le jeu de validation, c'est ce que l'on execute dans la cellule suivante. ","metadata":{"id":"z_BhxIoXeUI2"}},{"cell_type":"code","source":"plt.plot(pred_y_valid.detach().numpy(),'+')\nplt.plot(time_to_failure_valid)\nplt.legend([\"données d'apprentissage\", \"données de validation\"], loc =\"upper left\") \nplt.xlabel(\"nombre d'époques\")\nplt.ylabel(\"Temps jusqu'au prochain tremblement de terre\")\nplt.title(\"Visualisation de l'éfficacité du modèle\");","metadata":{"id":"iUiAfwYqeUI3","execution":{"iopub.status.busy":"2022-05-10T22:20:20.349674Z","iopub.execute_input":"2022-05-10T22:20:20.350098Z","iopub.status.idle":"2022-05-10T22:20:20.580432Z","shell.execute_reply.started":"2022-05-10T22:20:20.350047Z","shell.execute_reply":"2022-05-10T22:20:20.579462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nous n’avons réussi à faire tourner le programme qu’avec un nombre de signaux d’apprentissages de 100. Avec 100 signaux, nous n’observons même pas de tremblement de terre et les temps avant tremblement de terre ne sont pas bien balayés, ils sont même assez proches. Cependant, on observe déjà des temps de calcul des paramètres beaucoup trop longs et qui saturent la CPU de kaggle, bloquant l’exécution du programme. Nous n’arrivons donc pas à des résultats aussi satisfaisants que ce que l’on pourrait espérer.\n\n### Pistes d’améliorations\nPour améliorer ce programme, on pourrait faire une sélection plus fine des paramètres à prendre en compte. On pourrait s’intéresser à la corrélation de ces paramètres avec le temps avant le prochain tremblement. Partir d’un modèle prenant en compte le paramètre le plus corrélé, on peut ensuite ajouter des paramètres supplémentaires en effectuant un test de comparaison de modèles gigognes. De cette manière, nous obtiendrons une meilleure sélection des paramètres.\n\nUne autre piste serait aussi de jouer sur le pas d’apprentissage et de le faire varier pour voir son impact sur l’apprentissage.\n\nCes différents points pourraient être intéressants à explorer mais comme nous avons des difficultés pour faire tourner le programme, nous décidons de ne pas aller plus loin. Même si nous ne savons pas si notre modèle (sur un plus grand nombre de signaux d’apprentissage) est efficace, ce projet nous a permis de mieux nous familiariser avec l’environnement collab, le code lié à l’apprentissage profond, mais surtout l’importance du traitement des données. On a notamment pu constater que celui-ci demandait considérablement plus de temps en comparaison à l’écriture du programme d’apprentissage.","metadata":{"id":"dBfsmZFleUI3"}}]}