Skip to content
Snippets Groups Projects
Commit 780ce4a6 authored by Yifan.Tian's avatar Yifan.Tian
Browse files

update readme and code

parent 33d32cbc
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id:f75460b0 tags:
# Connexion à l'Elasticsearch
%% Cell type:code id:478e81f6 tags:
``` python
#Importer elasticsearch, n'oubliez pas de l'installer via pip3 install elasticsearch
import elasticsearch
from elasticsearch import Elasticsearch
print (elasticsearch.VERSION)
```
%% Output
(8, 6, 0)
%% Cell type:code id:d8443460 tags:
``` python
#Connexion avec le server elasticsearch lancé sur Docker, il faut bien fournir le bon password, et le bon path vers http_ca.crt
ELASTIC_PASSWORD = "À REMPLIR"
# Create the client instance
client = Elasticsearch(
"https://localhost:9200",
ca_certs="~/http_ca.crt",
basic_auth=("elastic", ELASTIC_PASSWORD)
)
```
%% Cell type:code id:e28dace4 tags:
``` python
#tester la connexion
client.info()
client.search(index='customer',body={"query": {"match_all": {}}})
```
%% Output
/tmp/ipykernel_453872/3396708810.py:3: DeprecationWarning: The 'body' parameter is deprecated and will be removed in a future version. Instead use individual parameters.
client.search(index='customer',body={"query": {"match_all": {}}})
ObjectApiResponse({'took': 0, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 1, 'relation': 'eq'}, 'max_score': 1.0, 'hits': [{'_index': 'customer', '_id': '1', '_score': 1.0, '_source': {'name': 'Brayan', 'age': 23, 'balance': 10000}}]}})
%% Cell type:markdown id:4ed7e46e tags:
# Traitement de données
%% Cell type:markdown id:3311071e tags:
Idée du traitement :
Nous n'utilisons que les tweets en Français et nous ne voulons pas de doublons.
Il n'y a que les colonnes: id, userId, date, renderedContent, likeCount, coordinates, place, location et followersCount qui nous servirons pour la suite.
Renommer le champ id -> tweetID pour distinguer avec l'id user. La table final appele raw_tweets.
N'hésitez pas à appeler la fonction head() pour voir les résultats de chaque étape
%% Cell type:code id:54d5c1f3 tags:
``` python
import pandas as pd
from pandas import json_normalize
#Get raw_tweets, filter by "fr"
raw_tweets = pd.read_json(r'./greve-tweets20230119.json', lines=True)
raw_tweets = raw_tweets[raw_tweets['lang']=='fr']
```
%% Cell type:markdown id:9fc1e33f tags:
Dans le dataset, le champ "user" est un objet Json, essayons de créér un table à partir de ce champ, et de supprimer des doublons. Nous ne gardons que certaines colonnes utiles.
On a aussi renommé le champ id -> userID pour distinguer l'id de tweet. La table finale appele users
Hint: Utiliser pandas.json_normalize, il faut importer avant d'utiliser
%% Cell type:code id:4ad2a607 tags:
``` python
#Unnest users et drop duplicate
users = json_normalize(raw_tweets['user'])
users = pd.DataFrame(users)
users.rename(columns={'id':'userId'}, inplace=True)
users.drop_duplicates(subset=['userId'], inplace=True)
users.drop('username', inplace=True, axis=1)
users.drop('_type', inplace=True, axis=1)
users.drop('descriptionLinks', inplace=True, axis=1)
users.drop('profileImageUrl', inplace=True, axis=1)
users.drop('profileBannerUrl', inplace=True, axis=1)
users.drop('url', inplace=True, axis=1)
users = pd.DataFrame(users)
users.head(5)
```
%% Output
userId displayname \
0 1829274175 xavier bertrand
1 104034000 Cemil Şanlı
2 1592847078979420160 megascabe
3 1430621814577897476 Matthieu Blanc
4 1242468719198007298 Paglia Orba
rawDescription \
0
1 Journaliste, reporter et vidéaste indé 🇨🇵 • ca...
2 jasper sa mère
3
4
renderedDescription verified \
0 False
1 Journaliste, reporter et vidéaste indé 🇨🇵 • ca... False
2 jasper sa mère False
3 False
4 False
created followersCount friendsCount statusesCount \
0 2013-09-08T13:36:07+00:00 14 41 1634
1 2010-01-12T01:49:43+00:00 20106 460 35063
2 2022-11-16T11:48:41+00:00 162 2669 5693
3 2021-08-25T20:03:29+00:00 89 353 2610
4 2020-03-24T15:10:11+00:00 4 23 1494
favouritesCount ... mediaCount location protected \
0 1087 ... 183 Neuilly-sur-Seine, France False
1 7548 ... 5607 Paris, France False
2 3147 ... 1 Ile-de-France, France False
3 3122 ... 357 France False
4 349 ... 4 France False
link label link._type \
0 NaN None NaN
1 NaN None snscrape.modules.twitter.TextLink
2 NaN None NaN
3 NaN None NaN
4 NaN None NaN
link.text link.url \
0 NaN NaN
1 youtube.com/CemilChosesATe… http://youtube.com/CemilChosesATeDire
2 NaN NaN
3 NaN NaN
4 NaN NaN
link.tcourl link.indices
0 NaN NaN
1 https://t.co/4aAJJEEbYR [0, 23]
2 NaN NaN
3 NaN NaN
4 NaN NaN
[5 rows x 21 columns]
%% Cell type:code id:369baafe tags:
``` python
#Renommer quelques colonnes et drop duplicate
user_id = []
for user in raw_tweets['user']:
uid = user['id']
user_id.append(uid)
raw_tweets['userId'] = user_id
# ne garder que les colonnes utiles
cols = ['id','userId','date', 'renderedContent','likeCount','coordinates','place']
tweets = raw_tweets[cols]
tweets.rename(columns={'id':'tweetId', 'url':'tweetUrl'}, inplace=True)
tweets = pd.DataFrame(tweets)
tweets.drop_duplicates(subset=['tweetId'], inplace=True)
tweets.head(5)
```
%% Output
/tmp/ipykernel_453872/2056371549.py:10: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
tweets.rename(columns={'id':'tweetId', 'url':'tweetUrl'}, inplace=True)
tweetId userId date \
0 1618396540363755520 1829274175 2023-01-25 23:52:58+00:00
2 1618395626852712450 104034000 2023-01-25 23:49:20+00:00
3 1618395386757906436 1592847078979420160 2023-01-25 23:48:23+00:00
4 1618393518418055168 1430621814577897476 2023-01-25 23:40:57+00:00
5 1618392620388192256 1242468719198007298 2023-01-25 23:37:23+00:00
renderedContent likeCount coordinates \
0 @mob_paris_8 Ton cerveau est en grève depuis t... 0 None
2 @BFMParis Force à elles et eux ! Faire grève c... 22 None
3 SNCF : appel de syndicats à une grève reconduc... 0 None
4 @Francois_Ruffin On attend pas la grève du 8 f... 0 None
5 @bernardoGeek @jdicajdisrien Alors à la fois l... 0 None
place
0 None
2 None
3 None
4 None
5 None
%% Cell type:code id:be2ad904 tags:
``` python
users = users[['userId','location','followersCount']]
users
```
%% Output
userId location followersCount
0 1829274175 Neuilly-sur-Seine, France 14
1 104034000 Paris, France 20106
2 1592847078979420160 Ile-de-France, France 162
3 1430621814577897476 France 89
4 1242468719198007298 France 4
... ... ... ...
4871 1277922631434604545 Paris, France 2274
4872 2615616488 Paris, France 181
4873 535327665 paris 10
4874 61656142 Romainville 2342
4875 1151485928332038144 Deauville, France 76
[3149 rows x 3 columns]
%% Cell type:markdown id:6f1e6d98 tags:
La table finale appele "tweets" est créé en mergent les 2 tables précédentes.
%% Cell type:code id:746551d9 tags:
``` python
#Table finale
tweets = pd.merge(tweets,users)
tweets
```
%% Output
tweetId userId date \
0 1618396540363755520 1829274175 2023-01-25 23:52:58+00:00
1 1618395626852712450 104034000 2023-01-25 23:49:20+00:00
2 1616043227596873728 104034000 2023-01-19 12:01:44+00:00
3 1618395386757906436 1592847078979420160 2023-01-25 23:48:23+00:00
4 1616068681380892672 1592847078979420160 2023-01-19 13:42:53+00:00
... ... ... ...
4871 1615987893859717120 1277922631434604545 2023-01-19 08:21:52+00:00
4872 1615987846963400704 2615616488 2023-01-19 08:21:40+00:00
4873 1615987785629941760 535327665 2023-01-19 08:21:26+00:00
4874 1615987763756797953 61656142 2023-01-19 08:21:21+00:00
4875 1615987721830371331 1151485928332038144 2023-01-19 08:21:11+00:00
renderedContent likeCount \
0 @mob_paris_8 Ton cerveau est en grève depuis t... 0
1 @BFMParis Force à elles et eux ! Faire grève c... 22
2 Ces capitalistes sont magiques ! 🤡\n\n"Ok pour... 59
3 SNCF : appel de syndicats à une grève reconduc... 0
4 Grève du 19 janvier : mobilisation monstre à M... 0
... ... ...
4871 On ne parle pas assez du fait que quand il y a... 14
4872 J’ai passé un cap en musculation et je rentre ... 1
4873 @vir__30deretour @CerfiaFR Pas sûr de comprend... 0
4874 Pour celles et ceux qui ne peuvent ou ne font ... 9
4875 j’crois ils veulent pas me faire passer le per... 11
coordinates place location followersCount
0 None None Neuilly-sur-Seine, France 14
1 None None Paris, France 20106
2 None None Paris, France 20106
3 None None Ile-de-France, France 162
4 None None Ile-de-France, France 162
... ... ... ... ...
4871 None None Paris, France 2274
4872 None None Paris, France 181
4873 None None paris 10
4874 None None Romainville 2342
4875 None None Deauville, France 76
[4876 rows x 9 columns]
%% Cell type:code id:0888a459 tags:
``` python
#Create index
client.indices.create(index='tweets')
```
%% Output
ObjectApiResponse({'acknowledged': True, 'shards_acknowledged': True, 'index': 'tweets'})
%% Cell type:code id:db8686c0 tags:
``` python
#Injection des données via bulk
from elasticsearch import helpers
total_number = 4875
c = 0
actions = []
n = 100
while (c < total_number):
actions = []
j = 0
while (j < total_number//n):
action = {
"_index": "tweets",
"_id": tweets['tweetId'].iloc[c],
"userId":tweets['userId'].iloc[c],
"_doc": tweets['renderedContent'].iloc[c],
"date": tweets['date'].iloc[c],
"location": tweets['location'].iloc[c],
"coordinates" : tweets["coordinates"].iloc[c],
"place" : tweets["place"].iloc[c],
"like": tweets["likeCount"].iloc[c],
"followersCount" : tweets["followersCount"].iloc[c]
}
actions.append(action)
j += 1
c += 1
if c == 4875:
break
helpers.bulk(client, actions)
```
%% Cell type:markdown id:9c857c74 tags:
# À vous jouer
%% Cell type:markdown id:a19d51dc tags:
Jusqu'à présent, tous les tweets ont été stockés dans l'index "tweets" d'elasticsearch, cela peut être vérifié via le terminal Kibana ou en executant la ligne suivante :
%% Cell type:code id:bff082f2 tags:
``` python
client.search(index='tweets',body={"query": {"match_all": {}}})
```
%% Cell type:markdown id:8aebccb3 tags:
Comme dans la première partie, nous pouvons répondre aux questions suivantes en interagissant avec elasticsearch, mais cette fois-ci via python !
%% Cell type:markdown id:fa4bf9de tags:
#### Q1 : Trouvez les tweets avec le plus de likes
%% Cell type:code id:35e308b8 tags:
``` python
```
%% Cell type:markdown id:43d2400e tags:
#### Q2 : Trouver l'ID user qui a plus de followers
%% Cell type:code id:14fbed1f tags:
``` python
```
%% Cell type:markdown id:03b1813d tags:
#### Q3 : Trouver les tweets postés par les influenceurs/euses (follower > 10000)
%% Cell type:code id:4ae90861 tags:
``` python
```
This diff is collapsed.
......@@ -263,9 +263,9 @@ Une fois vous avez finit l'importer, vous cliquez sur le boutton **import** en b
## Partie 2 : Elasticsearch Client sur Python
Pour cette partie, on exploitera comment intéragir avec Elasticsearch sur Python. Vous pouvez utiliser IDE comme vous voulez.
**Note** : à part d'Elasticsearch, d'ici, on a également besoin de librairie pandas
#### Q1. Installer Elasticsearch, importer dans Python
Pour cette deuxième partie, on exploitera comment intéragir avec Elasticsearch sur Python. Le code est fourni dans fichier "ConnectorES.ipynb"
**Note** : à part d'Elasticsearch, on a également besoin de librairie pandas
#### Q1. Installer Elasticsearch et l'importer dans Python
>pip3 install elasticsearch
......@@ -278,7 +278,7 @@ from elasticsearch import Elasticsearch
print (elasticsearch.VERSION)
```
D'ici, j'utilise la version 8.6.0
Si vous avez installé l'ES selons les étapes précédemment dans ce TP, la version sera 8.6.0.
#### Q2. Connecter avec le server Elasticsearch
``` bash
ELASTIC_PASSWORD = {Votre password}
......@@ -287,34 +287,26 @@ client = Elasticsearch(
ca_certs="path/vers/http_ca.cert",
basic_auth=("elastic", ELASTIC_PASSWORD))
#Il faut checker si tout va bien en lancant :
#la fonction "info()" nous permet de vérifier si c'est bien connecté avec ES:
client.info()
```
La réponse doit rassemble à cela :
La réponse doit rassembler à cela :
![attendu2](/images/connectapipython.PNG)
Vous pouvez également prendre les données qu'on a créé dans la 1ère partie :
Vous pouvez également récupérer les données qu'on a créé dans la 1ère partie :
``` bash
client.search(index='customer',body={"query": {"match_all": {}}})
```
#### Q3. Traitement les données
Pour la suite de TP, nous vous donnons un dataset qui est les tweets qui ont hashtag #Farmersprotest. Dans cette question, nous avons besoin de nettoyer les données avant injecter dans Elasticsearch
#### 3.1. Lire les données au format JSON
Hint: Utiliser pandas.read_json('/path/vers/des/données',lines=True)
#### 3.2. Filtrer
Nous n'utilisons que les tweets en Anglais et nous ne voulons pas de doublons. En plus, il n'y a que les colonnes : id, date, user, renderedContent qui nous servirons pour la suite. Renommer le champ id -> tweetID pour distinguer. La table résultant appelé raw_tweets
Appeler la fonction head() pour voir les résultats
#### 3.3. Flatten nested champ
Nous voyons que le champ "user" est nested, essayons de créér un table à partir de ce champ. Supprimer de doublons. Nous ne gardons que les colonnes : id, location. Renommer le champ id -> userID pour distinguer. La table résultant appelé users
#### Q3. Traitement les données
Pour la suite de TP, nous vous donnons un dataset rassemble 5 000 tweets contenant "grève" dans un rayon de 800 km autour de Paris, de la pérode 19/01/2023 - 26/01/2023, Dans cette question, nous avons besoin de nettoyer les données avant de les injecter dans Elasticsearch, le code pour la nettoyage est prêt, lancez et observez les données.
Hint: Utiliser pandas.json_normalize, il faut importer avant utiliser
#### 3.4. Créer la table finale
La table finale appelé "tweets" est créé en mergent les 2 tables précédentes.
#### Q3. Trouvez les tweets avec le plus de likes
#### Q4. Trouver l'ID user qui a plus de followers
#### Q5. Trouver les tweets postés par les influenceurs/euses (follower > 10000)
#### Q4. Injection les données dans Elasticsearch
## Partie 3 : Agrégation de données et visualisation dans Kibana
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment