Pour ce premier objectif, nous apprenons d'abord à récupérer sur internet des données de séries chronologiques et à les mettre sous un bon format. En effet, même si les données temporelles sont partout, les retrouver et les assembler est souvent un parcours de combattant, comme c'est le cas dans la plupart des projets de Data Science dignes du nom !. J'ai donc imaginé un beau scénario pour vous :).
Vous êtes Analyste quantitatif dans une société d'investissement. Votre Manager vous demande de créer une dataframe des prix journaliers de clôture des Actions françaises. Chaque secteur doit être représenté par la plus grande entreprise du CAC 40 (indice boursier représentant le marché financier en France) selon la capitalisation boursière. Vous devez récupérer les données depuis le 1er Janvier 2015 jusqu'à ce jour afin de permettre une actualisation automatique des informations.
Ayant commencé par une recherche internet sur l'indice du CAC 40, vous avez obtenu les informations ci-dessous :
Le CAC (Cotation Assistée en Continu) 40 est le principal indice de la bourse de Paris.
Liste des actions qui composent le CAC 40 : https://en.wikipedia.org/wiki/CAC_40 (Recherche Google).
Vous allez donc utiliser le lien ci-dessus pour scrapper les données à partir de Yahoo Finance. Commençons par importer les librairies nécessaires.
from warnings import filterwarnings
filterwarnings('ignore')
# !pip install xgboost
# Importation des librairies
import pandas as pd
import numpy as np
from pandas_datareader.data import DataReader, get_quote_yahoo
import seaborn as sns
import statsmodels.api as sm
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split, KFold, cross_val_score, GridSearchCV
from sklearn.feature_selection import SelectKBest, chi2, f_regression
from sklearn.linear_model import LinearRegression, Lasso, ElasticNet
from sklearn.tree import DecisionTreeRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, ExtraTreesRegressor, AdaBoostRegressor
from xgboost import XGBRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import mean_squared_error, r2_score
/usr/local/lib/python3.7/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead. import pandas.util.testing as tm
cac40 = pd.read_html('https://en.wikipedia.org/wiki/CAC_40')[3]
cac40
Company | Sector | GICS Sub-Industry | Ticker | |
---|---|---|---|---|
0 | Air Liquide | Basic Materials | Industrial Gases | AI.PA |
1 | Airbus | Industrials | Aerospace & Defense | AIR.PA |
2 | Alstom | Industrials | Rail Transport | ALO.PA |
3 | ArcelorMittal | Basic Materials | Steel | MT.AS |
4 | AXA | Financial Services | Life & Health Insurance | CS.PA |
5 | BNP Paribas | Financial Services | Diversified Banks | BNP.PA |
6 | Bouygues | Industrials | Construction & Engineering | EN.PA |
7 | Capgemini | Technology | IT Consulting & Other Services | CAP.PA |
8 | Carrefour | Consumer Defensive | Hypermarkets & Super Centers | CA.PA |
9 | Crédit Agricole | Financial Services | Regional Banks | ACA.PA |
10 | Danone | Consumer Defensive | Packaged Foods & Meats | BN.PA |
11 | Dassault Systèmes | Technology | Application Software | DSY.PA |
12 | Engie | Utilities | Gas Utilities | ENGI.PA |
13 | EssilorLuxottica | Healthcare | Apparel, Accessories & Luxury Goods | EL.PA |
14 | Eurofins Scientific | Healthcare | Biotechnologies | ERF.PA |
15 | Hermès | Consumer Cyclical | Apparel, Accessories & Luxury Goods | RMS.PA |
16 | Kering | Consumer Cyclical | Apparel, Accessories & Luxury Goods | KER.PA |
17 | L'Oréal | Consumer Defensive | Personal Products | OR.PA |
18 | Legrand | Industrials | Electrical Components & Equipment | LR.PA |
19 | LVMH | Consumer Cyclical | Apparel, Accessories & Luxury Goods | MC.PA |
20 | Michelin | Industrials | Tires & Rubber | ML.PA |
21 | Orange | Communication Services | Integrated Telecommunication Services | ORA.PA |
22 | Pernod Ricard | Consumer Defensive | Distillers & Vintners | RI.PA |
23 | Publicis | Communication Services | Advertising | PUB.PA |
24 | Renault | Consumer Cyclical | Automobile Manufacturers | RNO.PA |
25 | Safran | Industrials | Aerospace & Defense | SAF.PA |
26 | Saint-Gobain | Industrials | Building Products | SGO.PA |
27 | Sanofi | Healthcare | Pharmaceuticals | SAN.PA |
28 | Schneider Electric | Industrials | Electrical Components & Equipment | SU.PA |
29 | Société Générale | Financial Services | Diversified Banks | GLE.PA |
30 | Stellantis | Consumer Cyclical | Automobile Manufacturers | STLA.PA |
31 | STMicroelectronics | Technology | Semiconductors | STM.PA |
32 | Teleperformance | Communication Services | Outsourcing | TEP.PA |
33 | Thales | Industrials | Aerospace & Defense | HO.PA |
34 | TotalEnergies | Energy | Integrated Oil & Gas | TTE.PA |
35 | Unibail-Rodamco-Westfield | Real Estate | Retail REITs | URW.AS |
36 | Veolia | Industrials | Multi-Utilities | VIE.PA |
37 | Vinci | Industrials | Construction & Engineering | DG.PA |
38 | Vivendi | Communication Services | Movies & Entertainment | VIV.PA |
39 | Worldline | Technology | Data Processing & Outsourced Services | WLN.PA |
Etant donné que nous voulons récupérer les prix journaliers de la plus grande entreprise, par secteur, en matière de capitalisation boursière, il faudra avoir la capitalisation boursière de chacune des entreprises de cet indice.
Lorsque vous copiez-collez par exemple le symbole de la société Air Liquide dans la barre de recherche de Yahoo Finance, vous obtenez ce lien : https://fr.finance.yahoo.com/quote/AI.PA?p=AI.PA&.tsrc=fin-srch.
L'idée est donc de récupérer automatiquement la capitalisation boursière de chaque entreprise du CAC40 et d'ajouter ces informations dans une nouvelle colonne de la dataframe précédente. Je vais vous montrer un moyen simple de le faire.
tickers = cac40['Ticker'].to_list()
tickers
['AI.PA', 'AIR.PA', 'ALO.PA', 'MT.AS', 'CS.PA', 'BNP.PA', 'EN.PA', 'CAP.PA', 'CA.PA', 'ACA.PA', 'BN.PA', 'DSY.PA', 'ENGI.PA', 'EL.PA', 'ERF.PA', 'RMS.PA', 'KER.PA', 'OR.PA', 'LR.PA', 'MC.PA', 'ML.PA', 'ORA.PA', 'RI.PA', 'PUB.PA', 'RNO.PA', 'SAF.PA', 'SGO.PA', 'SAN.PA', 'SU.PA', 'GLE.PA', 'STLA.PA', 'STM.PA', 'TEP.PA', 'HO.PA', 'TTE.PA', 'URW.AS', 'VIE.PA', 'DG.PA', 'VIV.PA', 'WLN.PA']
# pip install yfinance
import pandas_datareader.data as web
from pandas_datareader import data
import pandas_datareader as web
import pandas_datareader as pdr
pip install --upgrade pandas-datareader
Requirement already satisfied: pandas-datareader in /usr/local/lib/python3.7/dist-packages (0.10.0) Requirement already satisfied: pandas>=0.23 in /usr/local/lib/python3.7/dist-packages (from pandas-datareader) (1.3.5) Requirement already satisfied: requests>=2.19.0 in /usr/local/lib/python3.7/dist-packages (from pandas-datareader) (2.27.1) Requirement already satisfied: lxml in /usr/local/lib/python3.7/dist-packages (from pandas-datareader) (4.8.0) Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23->pandas-datareader) (2.8.2) Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23->pandas-datareader) (1.21.6) Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23->pandas-datareader) (2022.1) Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas>=0.23->pandas-datareader) (1.15.0) Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader) (2.0.12) Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader) (2021.10.8) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader) (2.10) Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.19.0->pandas-datareader) (1.24.3)
# Récupération des capitalisations boursières
market_cap = data.get_quote_yahoo(tickers)['marketCap']
market_cap
AI.PA 75231248384 AIR.PA 83207675904 ALO.PA 8588016128 MT.AS 23715719168 CS.PA 51983876096 BNP.PA 64638828544 EN.PA 11895973888 CAP.PA 30919235584 CA.PA 15838489600 ACA.PA 31028287488 BN.PA 37935230976 DSY.PA 49713545216 ENGI.PA 28080179200 EL.PA 65432080384 ERF.PA 16197864448 RMS.PA 111337119744 KER.PA 56180330496 OR.PA 175176187904 LR.PA 21285064704 MC.PA 288904577024 ML.PA 21004505088 ORA.PA 31314991104 RI.PA 48065900544 PUB.PA 13710815232 RNO.PA 6811835392 SAF.PA 41269391360 SGO.PA 27825446912 SAN.PA 124753625088 SU.PA 71618461696 GLE.PA 19300556800 STLA.PA 43179159552 STM.PA 34070382592 TEP.PA 18237431808 HO.PA 24879468544 TTE.PA 134118694912 URW.AS 9740951552 VIE.PA 17642549248 DG.PA 51797237760 VIV.PA 11453507584 WLN.PA 10150437888 Name: marketCap, dtype: int64
# Création d'une colonne Market Capitalization
cac40['Market Capitalization'] = market_cap.values
# Changeons l'unité en milliards d'euros
cac40['Market Capitalization'] = cac40['Market Capitalization'] / 1000000000
cac40.head()
Company | Sector | GICS Sub-Industry | Market Capitalization | |
---|---|---|---|---|
Ticker | ||||
AI.PA | Air Liquide | Basic Materials | Industrial Gases | 75.231248 |
AIR.PA | Airbus | Industrials | Aerospace & Defense | 83.207676 |
ALO.PA | Alstom | Industrials | Rail Transport | 8.588016 |
MT.AS | ArcelorMittal | Basic Materials | Steel | 23.715719 |
CS.PA | AXA | Financial Services | Life & Health Insurance | 51.983876 |
Chaque ligne désigne une unique entreprise. Définissons la colonne 'Ticker' comme indices de lignes de la dataframe ci-dessus :
# cac40.set_index('Ticker', inplace = False)
# cac40.head(10)
Nous pouvons maintenant rechercher, pour chaque secteur, la plus grande entreprise en matière de capitalisation boursière.
# Quelle est la plus grande entreprise par secteur ?
composantes = cac40.groupby('Sector')['Market Capitalization'].nlargest(1)
composantes
Sector Ticker Basic Materials AI.PA 75.231248 Communication Services ORA.PA 31.314991 Consumer Cyclical MC.PA 288.904577 Consumer Defensive OR.PA 175.176188 Energy TTE.PA 134.118695 Financial Services BNP.PA 64.638829 Healthcare SAN.PA 124.753625 Industrials AIR.PA 83.207676 Real Estate URW.AS 9.740952 Technology DSY.PA 49.713545 Utilities ENGI.PA 28.080179 Name: Market Capitalization, dtype: float64
# Transformation du résultat en une dataframe
composantes = composantes.reset_index()
composantes
Sector | Ticker | Market Capitalization | |
---|---|---|---|
0 | Basic Materials | AI.PA | 75.231248 |
1 | Communication Services | ORA.PA | 31.314991 |
2 | Consumer Cyclical | MC.PA | 288.904577 |
3 | Consumer Defensive | OR.PA | 175.176188 |
4 | Energy | TTE.PA | 134.118695 |
5 | Financial Services | BNP.PA | 64.638829 |
6 | Healthcare | SAN.PA | 124.753625 |
7 | Industrials | AIR.PA | 83.207676 |
8 | Real Estate | URW.AS | 9.740952 |
9 | Technology | DSY.PA | 49.713545 |
10 | Utilities | ENGI.PA | 28.080179 |
# Classement par ordre décroissant de capitalisation boursière
composantes.sort_values(by = 'Market Capitalization', ascending= False)
Sector | Ticker | Market Capitalization | |
---|---|---|---|
2 | Consumer Cyclical | MC.PA | 288.904577 |
3 | Consumer Defensive | OR.PA | 175.176188 |
4 | Energy | TTE.PA | 134.118695 |
6 | Healthcare | SAN.PA | 124.753625 |
7 | Industrials | AIR.PA | 83.207676 |
0 | Basic Materials | AI.PA | 75.231248 |
5 | Financial Services | BNP.PA | 64.638829 |
9 | Technology | DSY.PA | 49.713545 |
1 | Communication Services | ORA.PA | 31.314991 |
10 | Utilities | ENGI.PA | 28.080179 |
8 | Real Estate | URW.AS | 9.740952 |
Il y a 11 secteurs distincts dans la bourse de Paris et la société LVMH (MC.PA) est la plus grande entreprise en matière de capitalisation boursière.
# Création d'une liste des symboles des plus grandes entreprises
symbols = composantes['Ticker'].to_list
symbols
<bound method IndexOpsMixin.tolist of 0 AI.PA 1 ORA.PA 2 MC.PA 3 OR.PA 4 TTE.PA 5 BNP.PA 6 SAN.PA 7 AIR.PA 8 URW.AS 9 DSY.PA 10 ENGI.PA Name: Ticker, dtype: object>
A présent que nous connaissant les plus grandes entreprises du CAC40 par secteur ainsi que leurs symboles, nous allons importer les prix quotidiens de chaque Action à partir de Yahoo Finance.
import pandas
from pandas_datareader import data as pdr
import yfinance as yfin
yfin.pdr_override()
# Téléchargement des prix journaliers de clôture
df = pdr.get_data_yahoo("AI.PA, ORA.PA, MC.PA, OR.PA, TTE.PA, BNP.PA, SAN.PA, SU.PA, URW.AS, DSY.PA, ENGI.PA", start="2022-01-01", end="2022-04-12").T
print(df.head())
[*********************100%***********************] 11 of 11 completed Date 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 \ Adj Close AI.PA 151.741074 154.667847 157.182144 154.196426 153.646439 BNP.PA 61.200001 63.250000 63.330002 64.190002 64.500000 DSY.PA 50.820000 50.830002 50.529999 48.685001 47.814999 ENGI.PA 11.351163 11.480251 11.428616 11.359769 11.402799 MC.PA 722.687805 735.539978 749.380798 718.832092 707.660645 Date 2022-01-10 2022-01-11 2022-01-12 2022-01-13 2022-01-14 \ Adj Close AI.PA 153.292862 153.941071 155.375000 153.783936 151.976791 BNP.PA 64.000000 64.360001 65.330002 66.959999 66.300003 DSY.PA 46.580002 47.130001 47.064999 46.105000 45.474998 ENGI.PA 11.475087 11.650648 11.838256 11.950132 11.950132 MC.PA 694.709595 701.926575 700.641357 682.153992 667.720032 Date ... 2022-03-29 2022-03-30 2022-03-31 2022-04-01 \ Adj Close AI.PA ... 156.141068 156.553574 156.082138 156.553574 BNP.PA ... 54.340000 53.080002 51.930000 51.689999 DSY.PA ... 46.025002 45.634998 44.715000 44.340000 ENGI.PA ... 10.404515 10.387303 10.270264 10.263379 MC.PA ... 664.160950 652.989441 642.015686 642.213379 Date 2022-04-04 2022-04-05 2022-04-06 2022-04-07 2022-04-08 \ Adj Close AI.PA 158.321426 158.851791 157.300003 157.378586 159.323212 BNP.PA 51.340000 49.000000 47.294998 46.560001 47.845001 DSY.PA 45.580002 45.935001 44.040001 43.564999 41.970001 ENGI.PA 10.327063 10.141176 10.115357 9.934633 9.994876 MC.PA 656.350830 653.384949 628.965759 616.904480 624.516968 Date 2022-04-11 Adj Close AI.PA 161.071426 BNP.PA 48.744999 DSY.PA 40.555000 ENGI.PA 9.913980 MC.PA 612.851135 [5 rows x 71 columns]
print(df.tail())
Date 2022-01-03 2022-01-04 2022-01-05 2022-01-06 2022-01-07 \ Volume ORA.PA 6450743.0 8585931.0 9980707.0 10120682.0 6559974.0 SAN.PA 1271543.0 1995141.0 1795238.0 1866298.0 1897920.0 SU.PA 603855.0 769801.0 752960.0 1009222.0 925347.0 TTE.PA 5436592.0 5584211.0 5641479.0 5444172.0 5732405.0 URW.AS 559578.0 738959.0 944682.0 780178.0 531408.0 Date 2022-01-10 2022-01-11 2022-01-12 2022-01-13 2022-01-14 \ Volume ORA.PA 13833998.0 7827674.0 8407252.0 8804219.0 8621755.0 SAN.PA 1641843.0 2305529.0 1719828.0 1795335.0 1709703.0 SU.PA 1272732.0 1047056.0 1144852.0 705501.0 875974.0 TTE.PA 5681747.0 6505491.0 9331583.0 6197728.0 6533053.0 URW.AS 457845.0 448394.0 669640.0 442238.0 487443.0 Date ... 2022-03-29 2022-03-30 2022-03-31 2022-04-01 \ Volume ORA.PA ... 6473095.0 6893661.0 5864346.0 4840788.0 SAN.PA ... 3353635.0 2270738.0 2337223.0 1983256.0 SU.PA ... 1361098.0 1008655.0 1464407.0 977106.0 TTE.PA ... 9838729.0 6483258.0 6495026.0 6071152.0 URW.AS ... 1113403.0 873811.0 570163.0 572419.0 Date 2022-04-04 2022-04-05 2022-04-06 2022-04-07 2022-04-08 \ Volume ORA.PA 5691603.0 6011307.0 7991039.0 6956138.0 6258061.0 SAN.PA 1733211.0 1944171.0 2522958.0 3491330.0 3858993.0 SU.PA 911519.0 1076424.0 1666931.0 1011775.0 886867.0 TTE.PA 4690279.0 5262056.0 6068545.0 6334970.0 5623325.0 URW.AS 419527.0 508958.0 754345.0 699660.0 426666.0 Date 2022-04-11 Volume ORA.PA 6088876.0 SAN.PA 2845410.0 SU.PA 765350.0 TTE.PA 6022190.0 URW.AS 569676.0 [5 rows x 71 columns]
SUPER TRAVAIL ! Vous venez d'obtenir la dataframe telle que souhaitée par votre Manager qui sera très content. Votre code est aussi réutilisable ce qui permettra d'actualiser les informations au cas où la situation du marché fiancier en France évolue.
Pour l'objectif 2, vous apprendrez à manipuler et visualiser les séries temporelles en utilisant des méthodes et fonctions basiques de Python et Pandas. Tout ceci se fera à travers un exercice dont le but est d'analyser le taux de chômage aux États-Unis de 2000 à 2010. Les données que nous utiliserons ici proviennent de Kaggle, la célèbre palteforma de compétitions en Data Science.
# Importation des données
df_usa = pd.read_csv('/content/drive/MyDrive/chomage aux usa/unemployment_data_us.csv')
df_usa.head()