visualiser une évolution de tweets
Attention, ce snack est du fast food tendance junk food.
L’ami Stéphane Wharton voulait un coup d’oeuil sur l’analyse de sentiment qu’il a opéré sur les tweets d’un député d’extrême-droite ayant tenu des propos racistes à l’assemblée. Ne faisant pas une veille sur le sujet, les questions qui semblent pertinente sont :
- quel est la tonalité habituelle des propos du député sur twitter ?
- est-ce que certaines tonalités ont un fonctionnement différent en terme d’audience ?
Comme on peut le voir, la fréquence de tweets et le nombre total de retweets ne suivent pas vraiment la même tendance. la distribution de retweets entre tweets positifs et négatifs n’est pas vraiment la même non plus.
On peut voir que les tweets du personnage sont perçus négativement par le modéle et que cette négativité engendre plus de réactions depuis mi 2021. Ces réactions peuvent être positives comme négatives mais elles génèrent du bruit et amplifie ainsi la portée de son discours.
la tambouille
Le détail des calculs peut être utile pour voir comment réduire les irrégularités cycliques en aggrégeant les tweets à la semaine et en opérant une moyenne glissante.
sentiments_evolution = (
sentiments
.assign(
local_time = lambda df: pd.to_datetime(df.local_time),
date = lambda df: pd.to_datetime(df.local_time).dt.to_period('W')
)
.reset_index()
.groupby(['date', 'sentiment'])
.agg({
'id': 'count',
'retweet_count': ['sum', 'mean'],
'like_count': ['sum', 'mean']
})
.reset_index()
.pivot_table(
index='date',
columns='sentiment',
fill_value=0
)
)
sentiments_evolution
graphique d’évolution des tweets
graphique d’évolution des retweets
tableau de synthèse
sentiments_yearly = (
sentiments
.assign(
local_time = lambda df: pd.to_datetime(df.local_time),
date = lambda df: pd.to_datetime(df.local_time).dt.to_period('Y')
)
.reset_index()
.groupby(['date', 'sentiment'])
.agg({
'like_count': ['mean', 'sum'],
'retweet_count': ['mean', 'sum']
})
.reset_index()
.pivot_table(
index='date',
columns='sentiment'
)
)
sentiments_yearly
/tmp/ipykernel_505791/203913093.py:2: PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.
sentiments
/tmp/ipykernel_505791/203913093.py:2: PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.
sentiments
like_count | retweet_count | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
mean | sum | mean | sum | |||||||||
sentiment | Negative | Neutral | Positive | Negative | Neutral | Positive | Negative | Neutral | Positive | Negative | Neutral | Positive |
date | ||||||||||||
2014 | 0.277966 | 0.440860 | 0.474026 | 82.0 | 41.0 | 73.0 | 0.816949 | 1.172043 | 0.883117 | 241.0 | 109.0 | 136.0 |
2015 | 1.693467 | 1.462185 | 2.043860 | 337.0 | 174.0 | 233.0 | 5.065327 | 3.243697 | 4.745614 | 1008.0 | 386.0 | 541.0 |
2016 | 3.577320 | 3.760563 | 3.930481 | 1388.0 | 534.0 | 735.0 | 5.979381 | 8.056338 | 5.673797 | 2320.0 | 1144.0 | 1061.0 |
2017 | 3.893750 | 5.742574 | 7.697143 | 1246.0 | 1160.0 | 1347.0 | 5.012500 | 6.831683 | 8.622857 | 1604.0 | 1380.0 | 1509.0 |
2018 | 6.803828 | 4.545455 | 6.405405 | 1422.0 | 300.0 | 474.0 | 4.956938 | 2.606061 | 3.297297 | 1036.0 | 172.0 | 244.0 |
2019 | 6.817391 | 5.645570 | 7.728571 | 1568.0 | 446.0 | 541.0 | 5.121739 | 5.949367 | 4.300000 | 1178.0 | 470.0 | 301.0 |
2020 | 9.156627 | 13.728972 | 27.608696 | 2280.0 | 1469.0 | 1905.0 | 5.449799 | 7.158879 | 11.260870 | 1357.0 | 766.0 | 777.0 |
2021 | 38.865052 | 26.384000 | 23.614286 | 11232.0 | 3298.0 | 1653.0 | 17.231834 | 10.648000 | 7.557143 | 4980.0 | 1331.0 | 529.0 |
2022 | 140.068452 | 15.488889 | 70.910569 | 47063.0 | 2091.0 | 8722.0 | 45.199405 | 4.622222 | 18.910569 | 15187.0 | 624.0 | 2326.0 |