L'émergence récente d'un nouveau coronavirus (2019-nCoV) a gagné une large couverture dans les médias publics et les nouvelles mondiales. C' est une brève introduction sur comment Google Trends nous permet de découvrir les préoccupations et les requêtes les plus populaires sur cette nouvelle épidémie en la France.
Les données collectées auprès de Google Trends présentent les requêtes les plus populaires des utilisateurs.
L'intérêt plus populaire sur la requête de recherche est exprimé par 100, tandis que le manque d'intérêt ou le nombre insuffisant de données est exprimé par 0. Les requêtes sont collectées à partir de cinq moteurs de recherche spécialisés: Web, Image, News, Google Shopping et Recherche YouTube.
Les données sont récupérées depuis la première mention de cette maladie par Google, en novembre 2019. Les données proviennent de Web Search for France.
Les tendances seront comparées au marché boursier français (CAC 40).
Il sera également analysé la tendance de la date de cette étude, afin de connaître les requêtes les plus fréquentes, la situation géographique et la tendance des requêtes les plus fréquentes
Une mise en garde importante concernant les données de Google Trends: elles ne révèlent pas exactement combien de personnes recherchent un terme donné, elles donnent simplement une idée de la hausse ou de la baisse de popularité de ce terme.
# !pip install pytrends
import numpy as np
import matplotlib.pyplot as plt
from datetime import date, datetime, timedelta
from pytrends.request import TrendReq
import time
import pandas as pd
import matplotlib
import gtrend
import seaborn as sns
from pandas.io.json import json_normalize
from pandas.plotting import scatter_matrix
plt.style.use('seaborn-darkgrid')
matplotlib.rcParams['font.family'] = ['DejaVu Sans']
def rmax(maxrow: int=50):
pd.set_option('display.max_rows', maxrow)
def cmax(maxcol: int=50):
pd.set_option('display.max_columns', maxcol)
Configurer les termes et conditions de la requête
pytrend = TrendReq(hl='fr-FR', tz=60)
keyword = 'coronavirus'
start = '2019-10-01'
end = '2020-04-26'
geo='FR'
cat=0
gprop=''
sont consultées les données de tendance Google quotidiennes pendant plus de 5 mois en concaténant plusieurs requêtes et normaliser (scaling) en fonction de la période de chevauchement (overlapping method)
overlapping = gtrend.get_daily_trend(pytrend, keyword, start, end, geo=geo, cat=cat, gprop=gprop, verbose=True, tz=60)
Fetching 'coronavirus' for period:2019-08-01 2020-04-26 Fetching 'coronavirus' for period:2019-02-13 2019-11-09 Normalize by overlapping period:2019-08-01 2019-11-09 Normalize by overlapping period:2020-04-20 2020-04-24
overlapping.plot(figsize=(15,10))
<matplotlib.axes._subplots.AxesSubplot at 0x1a0b6aea978>
Acquérir des données de tendance Google quotidiennes pendant plus de 5 mois en concaténant plusieurs requêtes non chevauchantes de 1 mois et normaliser (scaling) par valeur de tendance hebdomadaire de la même période. (pytrends dailydata.py method)
from pytrends import dailydata
start_d = datetime.strptime(start, '%Y-%m-%d')
end_d = datetime.strptime(end, '%Y-%m-%d')
s_year = start_d.year
s_mon = start_d.month
e_year = end_d.year
e_mon = end_d.month
dailydata = dailydata.get_daily_data(word= keyword,
start_year= s_year,
start_mon= s_mon,
stop_year= e_year,
stop_mon= e_mon,
geo= geo,
verbose= False,
wait_time = 1.0)
print(dailydata.columns)
dailydata[f'{keyword}'].plot(figsize=(15,10))
Index(['coronavirus_unscaled', 'coronavirus_monthly', 'isPartial', 'scale', 'coronavirus'], dtype='object')
<matplotlib.axes._subplots.AxesSubplot at 0x1a0b6aea978>
Les données de tendance hebdomadaire pourraient être une référence pour comparer les méthodes de normalisation ci-dessus. Pour une période de requête comprise 120 jours (~ 4 mois), la tendance google renverra des données weely. Pour avoir une échelle d'axe comparable, les données hebdomadaires sont interpolées pour obtenir des données quotidiennes.
tf = start_d.strftime('%Y-%m-%d')+' '+end_d.strftime('%Y-%m-%d')
pytrend.build_payload(kw_list=[keyword], cat=cat, geo=geo, gprop=gprop, timeframe=tf)
week = pytrend.interest_over_time()
week_interp = week.resample('D').mean()
week_interp[f'{keyword}'] = week_interp[f'{keyword}'].interpolate()
week_interp.drop(columns='isPartial', inplace=True)
week_interp.plot(figsize=(15,10))
<matplotlib.axes._subplots.AxesSubplot at 0x1a0b6b175f8>
Pour une meilleure comparaison visuelle, rassemblons les 3 ensembles de données.
overlapping.loc[:,keyword]
2019-10-01 01:00:00 0.0 2019-10-02 01:00:00 0.0 2019-10-03 01:00:00 0.0 2019-10-04 01:00:00 0.0 2019-10-05 01:00:00 0.0 ... 2020-04-21 01:00:00 20.0 2020-04-22 01:00:00 21.0 2020-04-23 01:00:00 28.0 2020-04-24 01:00:00 20.0 2020-04-25 01:00:00 20.0 Freq: D, Name: coronavirus, Length: 208, dtype: float64
overlapping.columns
Index(['coronavirus', 'overlap'], dtype='object')
combined = pd.concat([overlapping, dailydata.loc[:,keyword], week_interp], axis=1)
combined.tail(20)
coronavirus | overlap | coronavirus | coronavirus | |
---|---|---|---|---|
2020-04-15 01:00:00 | 36.0 | NaN | NaN | NaN |
2020-04-16 00:00:00 | NaN | NaN | 24.85 | 35.0 |
2020-04-16 01:00:00 | 34.0 | NaN | NaN | NaN |
2020-04-17 00:00:00 | NaN | NaN | 23.46 | 34.0 |
2020-04-17 01:00:00 | 33.0 | NaN | NaN | NaN |
2020-04-18 00:00:00 | NaN | NaN | 26.60 | 35.0 |
2020-04-18 01:00:00 | 34.0 | NaN | NaN | NaN |
2020-04-19 00:00:00 | NaN | NaN | 23.43 | 33.0 |
2020-04-19 01:00:00 | 32.0 | NaN | NaN | NaN |
2020-04-20 00:00:00 | NaN | NaN | 11.27 | 23.0 |
2020-04-20 01:00:00 | 22.0 | 1.0 | NaN | NaN |
2020-04-21 00:00:00 | NaN | NaN | 9.45 | 21.0 |
2020-04-21 01:00:00 | 20.0 | 1.0 | NaN | NaN |
2020-04-22 00:00:00 | NaN | NaN | 9.66 | 21.0 |
2020-04-22 01:00:00 | 21.0 | 1.0 | NaN | NaN |
2020-04-23 00:00:00 | NaN | NaN | 16.80 | 28.0 |
2020-04-23 01:00:00 | 28.0 | 1.0 | NaN | NaN |
2020-04-24 00:00:00 | NaN | NaN | 9.45 | 21.0 |
2020-04-24 01:00:00 | 20.0 | 1.0 | NaN | NaN |
2020-04-25 01:00:00 | 20.0 | NaN | NaN | NaN |
combined.columns = ['overlapping method','overlap period', 'dailydata method', 'weekly data']
combined = combined.resample('D').mean()
import matplotlib.dates as mdates
from cycler import cycler
from matplotlib.cm import get_cmap
combined2 = combined.iloc[:, [0,2,3,1]]
combined2.index = [pd.to_datetime(date, format='%Y-%m-%d').date() for date in combined2.index]
# c = ['royalblue', 'darkorange', 'limegreen', 'salmon']
# colors = plt.cm.Paired(np.linspace(0,1,4)) # This returns RGBA; convert:
c = []
for i in range(0,4):
c.append(matplotlib.colors.rgb2hex(plt.cm.tab10(i)))
ax = combined2.plot(figsize=(15,10), color=c)
# set line colors
# c = plt.cm.hot(np.linspace(0,1,4))
# ax.set_prop_cycle(cycler('color', c))
# ax.set_prop_cycle(color=colors)
# ax.set_prop_cycle('color',plt.cm.Spectral(np.linspace(0,1,30)))
# set monthly locator
ax.xaxis.set_major_locator(mdates.YearLocator())
ax.xaxis.set_minor_locator(mdates.MonthLocator(bymonthday=15))
# set formatter
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y'))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%b'))
ax.tick_params(direction='out', pad=20)
# set font and rotation for date tick labels
# plt.gcf().autofmt_xdate()
ax.xaxis.grid(True, which='minor')
plt.ylabel('Relative Search Trends')
plt.xlabel('Date')
plt.title('Daily Google Trends Value pour \'coronavirus\' depuis '+start+' to '+end)
# plt.set_cmap('Pastel2')
plt.show()
La figure montre que l'intérêt pour le coronavirus en France a commencé à partir de janvier 2020. Il est visible dans la ligne de tendance, que l'intérêt croissant s'accélère avec les premiers cas signalés en France et atteint des valeurs maximales en mars, peut-être en raison de la mesures gouvernementales extrêmes pour protéger l'épidémie par les pays des Union Européenne.
ax.get_lines()[0].get_color(), ax.get_lines()[1].get_color(), ax.get_lines()[2].get_color(), ax.get_lines()[3].get_color()
('#1f77b4', '#ff7f0e', '#2ca02c', '#d62728')
combined['overlap period'].fillna(value='0', inplace=True)
combined.tail(20)
overlapping method | overlap period | dailydata method | weekly data | |
---|---|---|---|---|
2020-04-06 | 41.0 | 0 | 36.49 | 41.0 |
2020-04-07 | 40.0 | 0 | 35.67 | 41.0 |
2020-04-08 | 40.0 | 0 | 34.40 | 40.0 |
2020-04-09 | 37.0 | 0 | 30.78 | 38.0 |
2020-04-10 | 37.0 | 0 | 28.86 | 37.0 |
2020-04-11 | 31.0 | 0 | 20.77 | 31.0 |
2020-04-12 | 29.0 | 0 | 17.98 | 29.0 |
2020-04-13 | 39.0 | 0 | 31.98 | 39.0 |
2020-04-14 | 35.0 | 0 | 26.60 | 35.0 |
2020-04-15 | 36.0 | 0 | 28.86 | 37.0 |
2020-04-16 | 34.0 | 0 | 24.85 | 35.0 |
2020-04-17 | 33.0 | 0 | 23.46 | 34.0 |
2020-04-18 | 34.0 | 0 | 26.60 | 35.0 |
2020-04-19 | 32.0 | 0 | 23.43 | 33.0 |
2020-04-20 | 22.0 | 1 | 11.27 | 23.0 |
2020-04-21 | 20.0 | 1 | 9.45 | 21.0 |
2020-04-22 | 21.0 | 1 | 9.66 | 21.0 |
2020-04-23 | 28.0 | 1 | 16.80 | 28.0 |
2020-04-24 | 20.0 | 1 | 9.45 | 21.0 |
2020-04-25 | 20.0 | 0 | NaN | NaN |
Concentrons-nous sur une période plus courte, comme 2020 janvier à 2020 avril où les données de tendance varient beaucoup et 3 méthodes ont donné des valeurs assez différentes. Dans ce cas, nous pouvons même récupérer les «vraies» données quotidiennes directement à partir de la tendance google (période inférieure à 5 mois) sans faire de mise à l'échelle / traitement pour comparaison.
p_start = '2020-01-20'
p_end = '2020-04-26'
# p_start_d = datetime.strptime(p_start, '%Y-%m-%d')
# p_end_d = datetime.strptime(p_end, '%Y-%m-%d')
tf = p_start+' '+p_end
geo='FR'
pytrend.build_payload(kw_list=[keyword], cat=cat, geo=geo, gprop=gprop, timeframe=tf)
daily_real = pytrend.interest_over_time()
combined_period = combined.loc[p_start:p_end]
combined_period = pd.concat([combined_period,daily_real], axis=1)
combined_period.drop(columns=['isPartial','overlap period'], inplace=True)
combined_period.columns = ['overlapping method', 'dailydata method', 'weekly data', 'original data']
c = []
for i in range(0,7):
c.append(matplotlib.colors.rgb2hex(plt.cm.tab10(i)))
c
['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2']
#combined_period.plot(figsize=(15,10))
from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU
combined2 = combined_period.copy()
combined2.index = [pd.to_datetime(date, format='%Y-%m-%d').date() for date in combined2.index]
c = ['#1f77b4', '#ff7f0e', '#2ca02c', '#e377c2']
ax = combined2.plot(figsize=(15,10), color=c)
# set weekday locator
ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=TU))
# set formatter
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d'))
# set font and rotation for date tick labels
plt.gcf().autofmt_xdate()
plt.ylabel('Relative Search Trends')
plt.xlabel(None)
plt.title('Daily Google Trends Value pour \'coronavirus\' depuis '+p_start+' to '+p_end)
plt.show()
Les données quotidiennes ont évidemment une différence plus grande que les valeurs réelles et hebdomadaires, mais cette valeur ajustée suit la même tendance que les autres.
Les recherches de "coronavirus" ont été multipliées par sept environ depuis le 25 février, coïncidant avec le premier décès dû à cette maladie https://www.lefigaro.fr/sciences/coronavirus-avec-6-nouveaux-cas-et-1-mort-en-moins-de-48-heures-la-surveillance-se-complique-en-france-20200226
Examinons maintenant le comportement de la Bourse française avec l'indice des prix du CAC 40 et les tendances de recherche de Google dans le coronavirus identifiées ci-dessus.
import yfinance as yf
ticker = yf.Ticker("^FCHI")
print(ticker)
ticker.info
frstock = ticker.history(start=start, end=end)
yfinance.Ticker object <^FCHI>
combined_stock = pd.concat([combined, frstock.Close], axis=1)
combined_stock.drop(columns=['dailydata method', 'overlap period'], inplace=True)
combined_stock.columns = ['daily trends', 'weekly trends', 'CAC40 stock price']
combined_stock.head()
daily trends | weekly trends | CAC40 stock price | |
---|---|---|---|
2019-10-01 | 0.0 | 0.0 | 5597.63 |
2019-10-02 | 0.0 | 0.0 | 5422.77 |
2019-10-03 | 0.0 | 0.0 | 5438.77 |
2019-10-04 | 0.0 | 0.0 | 5488.32 |
2019-10-05 | 0.0 | 0.0 | NaN |
cor_fr = pd.merge(combined2, combined_stock,left_index=True, right_index=True)
fig = plt.figure()
ax = combined2.plot(figsize=(20,10), color=c)
ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=TU))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d'))
ax2 = ax.twinx()
ax2.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=TU))
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%b %d'))
CAC40 = ax2.plot(cor_fr['CAC40 stock price'], color='black')
ax2.legend(['CAC40 stock price'])
l = ax.get_ylim()
l2 = ax2.get_ylim()
f = lambda x : l2[0]+(x-l[0])/(l[1]-l[0])*(l2[1]-l2[0])
ticks = f(ax.get_yticks())
ax2.yaxis.set_major_locator(matplotlib.ticker.FixedLocator(ticks))
plt.gcf().autofmt_xdate()
ax.set_ylabel('Tendances relatives de la recherche Google %')
ax2.set_ylabel('CAC40 stock price € ')
plt.title('Daily Google Trends Value pour \'coronavirus\' depuis '+p_start+' to '+p_end)
plt.show()
<Figure size 432x288 with 0 Axes>
Ce graphique montre comment le scepticisme des investisseurs sur les mesures de soutien économique, la guerre des prix sur le marché du pétrole et le reclassement de l'épidémie de Covid-19 en "pandémie" n'a pas favorisé la Bourse de Paris.
pytrend.build_payload(kw_list=['coronavirus'], geo = 'FR', timeframe = 'now 1-d')
interest_over_time_df = pytrend.interest_over_time()
print(interest_over_time_df.tail())
coronavirus isPartial date 2020-04-26 16:56:00 66 False 2020-04-26 17:04:00 72 False 2020-04-26 17:12:00 73 False 2020-04-26 17:20:00 75 False 2020-04-26 17:28:00 70 True
interest_by_region_df = pytrend.interest_by_region()
interest_by_region_df.sort_values(by = 'coronavirus', ascending = True).plot.barh()
plt.title('Daily Google Trends Value par Coronavirus par Région Française')
Text(0.5, 1.0, 'Daily Google Trends Value par Coronavirus par Région Française')
Il s'agit d'une répartition de la popularité par zone géographique des recherches google associées au coronavirus en la France
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes= False)
dx = interest_over_time_df.plot.line(figsize = (12,9),title = "Tendance horaire relatives de la recherche Google en France")
dx.set_xlabel('GMT +1 Time', fontsize = 15)
dx.set_ylabel('search',fontsize = 15)
dx.tick_params(axis='both', which='major', labelsize=13)
Nous voyons en détail les consultations d'aujourd'hui 11 mars et comment la fréquence se concentre sur les heures du matin, du midi et de la nuit en dehors des heures de travail
kw_list= ['coronavirus']
pytrend.build_payload(kw_list=kw_list, geo = 'FR', timeframe = '2019-10-01 2020-04-26')
related_queries= pytrend.related_queries()
print(related_queries)
{'coronavirus': {'top': query value 0 france coronavirus 100 1 le coronavirus 58 2 cas coronavirus 21 3 merci à tous ceux qui aident à combattre le co... 20 4 italie 19 5 coronavirus italie 19 6 coronavirus en france 17 7 coronavirus conseils 14 8 coronavirus carte 12 9 coronavirus mort 11 10 coronavirus symptome 11 11 coronavirus attestation 10 12 coronavirus chine 10 13 chine coronavirus 10 14 coronavirus monde 10 15 coronavirus france cas 9 16 confinement coronavirus 8 17 corona 8 18 coronavirus bilan 8 19 coronavirus nombre de cas 7 20 direct coronavirus 6 21 coronavirus paris 6 22 info coronavirus 6 23 morts coronavirus 6 24 deces coronavirus 5, 'rising': query value 0 france coronavirus 1828600 1 le coronavirus 1066800 2 cas coronavirus 380600 3 merci à tous ceux qui aident à combattre le co... 370250 4 italie 352500 5 coronavirus italie 342200 6 coronavirus en france 303900 7 coronavirus conseils 260100 8 coronavirus carte 216550 9 coronavirus mort 204250 10 coronavirus symptome 200500 11 coronavirus attestation 184850 12 coronavirus chine 183850 13 chine coronavirus 183000 14 coronavirus monde 174000 15 coronavirus france cas 160300 16 confinement coronavirus 153800 17 corona 147450 18 coronavirus bilan 140200 19 coronavirus nombre de cas 118900 20 direct coronavirus 117450 21 coronavirus paris 113600 22 info coronavirus 102100 23 morts coronavirus 101150 24 deces coronavirus 92800}}
type(related_queries)
dict
related = related_queries['coronavirus']['top']
related
query | value | |
---|---|---|
0 | france coronavirus | 100 |
1 | le coronavirus | 58 |
2 | cas coronavirus | 21 |
3 | merci à tous ceux qui aident à combattre le co... | 20 |
4 | italie | 19 |
5 | coronavirus italie | 19 |
6 | coronavirus en france | 17 |
7 | coronavirus conseils | 14 |
8 | coronavirus carte | 12 |
9 | coronavirus mort | 11 |
10 | coronavirus symptome | 11 |
11 | coronavirus attestation | 10 |
12 | coronavirus chine | 10 |
13 | chine coronavirus | 10 |
14 | coronavirus monde | 10 |
15 | coronavirus france cas | 9 |
16 | confinement coronavirus | 8 |
17 | corona | 8 |
18 | coronavirus bilan | 8 |
19 | coronavirus nombre de cas | 7 |
20 | direct coronavirus | 6 |
21 | coronavirus paris | 6 |
22 | info coronavirus | 6 |
23 | morts coronavirus | 6 |
24 | deces coronavirus | 5 |
grows = related_queries['coronavirus']['rising']
grows
query | value | |
---|---|---|
0 | france coronavirus | 1828600 |
1 | le coronavirus | 1066800 |
2 | cas coronavirus | 380600 |
3 | merci à tous ceux qui aident à combattre le co... | 370250 |
4 | italie | 352500 |
5 | coronavirus italie | 342200 |
6 | coronavirus en france | 303900 |
7 | coronavirus conseils | 260100 |
8 | coronavirus carte | 216550 |
9 | coronavirus mort | 204250 |
10 | coronavirus symptome | 200500 |
11 | coronavirus attestation | 184850 |
12 | coronavirus chine | 183850 |
13 | chine coronavirus | 183000 |
14 | coronavirus monde | 174000 |
15 | coronavirus france cas | 160300 |
16 | confinement coronavirus | 153800 |
17 | corona | 147450 |
18 | coronavirus bilan | 140200 |
19 | coronavirus nombre de cas | 118900 |
20 | direct coronavirus | 117450 |
21 | coronavirus paris | 113600 |
22 | info coronavirus | 102100 |
23 | morts coronavirus | 101150 |
24 | deces coronavirus | 92800 |
pytrend = TrendReq()
pytrend.build_payload(kw_list=['cas coronavirus', 'coronavirus en france', 'chine coronavirus', 'italie','coronavirus symptome'], geo = 'FR', timeframe = 'today 3-m')
interest_over_time_df = pytrend.interest_over_time()
plt.show()
sns.set(color_codes= False)
dx2 = interest_over_time_df.plot.line(figsize = (15,9),title = "Principales tendances relatives de la recherche Google en France")
dx2.set_xlabel('Time GMT +1', fontsize = 12)
dx2.set_ylabel('Relative Google Search Trends',fontsize = 12)
dx2.tick_params(axis='both', which='major', labelsize=12)
plt.show()
À l'ère des BigData, l'analyse des requêtes Google est devenue un outil précieux pour les chercheurs pour explorer et prédire le comportement humain, car il a été suggéré que les données en ligne sont corrélées avec les données réelles sur la santé.
Il est important d'utiliser les données de Google Trends dans l'évaluation des coronavirus pour aider les chercheurs, les responsables de la santé et les organisations.
Mais l'analyse des données de Google Trends présente plusieurs limites, l'examen des données Web peut porter invalider l'analyse. Une analyse minutieuse doit être effectuée pour s'assurer que les reportages et les événements soudains ne compromettent pas la validité des résultats. De plus, comme l'échantillon est inconnu, plusieurs autres facteurs démographiques tels que l'âge et le sexe ne peuvent pas être inclus dans l'analyse.
Les consultations faites par les internautes en France nous permettent réponse à des questions telles que les jours avec la fréquence la plus élevée de consultations, le calendrier des interactions, les régions avec le plus de consultations et la tendance de la popularité des informations sur le coronavirus pour examiner les comportements de la communication collective sur Internet.
Il a également été possible de comparer la variable de marché financier CAC 40 et la sensibilité de cet indice boursier aux inquiétudes sur le futur proche de la progression de la maladie, ainsi qu'aux actions de l'État pour la prévention de cette pandémie.
La signification des résultats ci-dessus est que l'infodémiologie avec l'analyse des tendances de Google fournit une caractéristique référence à recadrer les discussions sur l’effet COVID-19, ainsi que des schémas substantiels de la prochaine pandémie.