Fundación Universitaria Konrad Lorenz
Docente: Viviana Márquez vivianam.penama@konradlorenz.edu.co
Clase #12: Mayo 13, 2021
https://www.youtube.com/watch?v=sY9cjVK0mGU&ab_channel=ADSTARS
pip install tweepy
http://docs.tweepy.org/en/latest/
api_key,
api_secret_key,
access_token,
access_token_secret,
bearer_token,
Código en: https://codeshare.io/alXdkD
import pandas as pd
import tweepy
# Leer llaves
keys = pd.read_csv("../archivos/no/keys.csv", header=None)
keys = dict(zip(keys[0],keys[1]))
# Autorizar a través API
auth = tweepy.OAuthHandler(keys['api_key'], keys['api_secret_key'])
auth.set_access_token(keys['access_token'], keys['access_token_secret'])
api = tweepy.API(auth, wait_on_rate_limit=True)
api.update_status('Aún sigo preparando clase...')
Status(_api=<tweepy.api.API object at 0x7f980ce79dd0>, _json={'created_at': 'Wed May 12 14:31:17 +0000 2021', 'id': 1392487549579497477, 'id_str': '1392487549579497477', 'text': 'Aún sigo preparando clase...', 'truncated': False, 'entities': {'hashtags': [], 'symbols': [], 'user_mentions': [], 'urls': []}, 'source': '<a href="https://help.twitter.com/en/using-twitter/how-to-tweet#source-labels" rel="nofollow">NLP_Good_For_Use</a>', 'in_reply_to_status_id': None, 'in_reply_to_status_id_str': None, 'in_reply_to_user_id': None, 'in_reply_to_user_id_str': None, 'in_reply_to_screen_name': None, 'user': {'id': 1295079294239223812, 'id_str': '1295079294239223812', 'name': 'NLP con Vivi', 'screen_name': 'NLPconVivi', 'location': 'Konrad Lorenz', 'description': '“La mejor clase del Universo 7, pero deja muchos talleres” ~ Gokú 2020', 'url': None, 'entities': {'description': {'urls': []}}, 'protected': False, 'followers_count': 15, 'friends_count': 21, 'listed_count': 0, 'created_at': 'Sun Aug 16 19:25:55 +0000 2020', 'favourites_count': 56, 'utc_offset': None, 'time_zone': None, 'geo_enabled': False, 'verified': False, 'statuses_count': 100, 'lang': None, 'contributors_enabled': False, 'is_translator': False, 'is_translation_enabled': False, 'profile_background_color': 'F5F8FA', 'profile_background_image_url': None, 'profile_background_image_url_https': None, 'profile_background_tile': False, 'profile_image_url': 'http://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', 'profile_banner_url': 'https://pbs.twimg.com/profile_banners/1295079294239223812/1607999522', 'profile_link_color': '1DA1F2', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'has_extended_profile': True, 'default_profile': True, 'default_profile_image': False, 'following': False, 'follow_request_sent': False, 'notifications': False, 'translator_type': 'none', 'withheld_in_countries': []}, 'geo': None, 'coordinates': None, 'place': None, 'contributors': None, 'is_quote_status': False, 'retweet_count': 0, 'favorite_count': 0, 'favorited': False, 'retweeted': False, 'lang': 'es'}, created_at=datetime.datetime(2021, 5, 12, 14, 31, 17), id=1392487549579497477, id_str='1392487549579497477', text='Aún sigo preparando clase...', truncated=False, entities={'hashtags': [], 'symbols': [], 'user_mentions': [], 'urls': []}, source='NLP_Good_For_Use', source_url='https://help.twitter.com/en/using-twitter/how-to-tweet#source-labels', in_reply_to_status_id=None, in_reply_to_status_id_str=None, in_reply_to_user_id=None, in_reply_to_user_id_str=None, in_reply_to_screen_name=None, author=User(_api=<tweepy.api.API object at 0x7f980ce79dd0>, _json={'id': 1295079294239223812, 'id_str': '1295079294239223812', 'name': 'NLP con Vivi', 'screen_name': 'NLPconVivi', 'location': 'Konrad Lorenz', 'description': '“La mejor clase del Universo 7, pero deja muchos talleres” ~ Gokú 2020', 'url': None, 'entities': {'description': {'urls': []}}, 'protected': False, 'followers_count': 15, 'friends_count': 21, 'listed_count': 0, 'created_at': 'Sun Aug 16 19:25:55 +0000 2020', 'favourites_count': 56, 'utc_offset': None, 'time_zone': None, 'geo_enabled': False, 'verified': False, 'statuses_count': 100, 'lang': None, 'contributors_enabled': False, 'is_translator': False, 'is_translation_enabled': False, 'profile_background_color': 'F5F8FA', 'profile_background_image_url': None, 'profile_background_image_url_https': None, 'profile_background_tile': False, 'profile_image_url': 'http://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', 'profile_banner_url': 'https://pbs.twimg.com/profile_banners/1295079294239223812/1607999522', 'profile_link_color': '1DA1F2', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'has_extended_profile': True, 'default_profile': True, 'default_profile_image': False, 'following': False, 'follow_request_sent': False, 'notifications': False, 'translator_type': 'none', 'withheld_in_countries': []}, id=1295079294239223812, id_str='1295079294239223812', name='NLP con Vivi', screen_name='NLPconVivi', location='Konrad Lorenz', description='“La mejor clase del Universo 7, pero deja muchos talleres” ~ Gokú 2020', url=None, entities={'description': {'urls': []}}, protected=False, followers_count=15, friends_count=21, listed_count=0, created_at=datetime.datetime(2020, 8, 16, 19, 25, 55), favourites_count=56, utc_offset=None, time_zone=None, geo_enabled=False, verified=False, statuses_count=100, lang=None, contributors_enabled=False, is_translator=False, is_translation_enabled=False, profile_background_color='F5F8FA', profile_background_image_url=None, profile_background_image_url_https=None, profile_background_tile=False, profile_image_url='http://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', profile_image_url_https='https://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', profile_banner_url='https://pbs.twimg.com/profile_banners/1295079294239223812/1607999522', profile_link_color='1DA1F2', profile_sidebar_border_color='C0DEED', profile_sidebar_fill_color='DDEEF6', profile_text_color='333333', profile_use_background_image=True, has_extended_profile=True, default_profile=True, default_profile_image=False, following=False, follow_request_sent=False, notifications=False, translator_type='none', withheld_in_countries=[]), user=User(_api=<tweepy.api.API object at 0x7f980ce79dd0>, _json={'id': 1295079294239223812, 'id_str': '1295079294239223812', 'name': 'NLP con Vivi', 'screen_name': 'NLPconVivi', 'location': 'Konrad Lorenz', 'description': '“La mejor clase del Universo 7, pero deja muchos talleres” ~ Gokú 2020', 'url': None, 'entities': {'description': {'urls': []}}, 'protected': False, 'followers_count': 15, 'friends_count': 21, 'listed_count': 0, 'created_at': 'Sun Aug 16 19:25:55 +0000 2020', 'favourites_count': 56, 'utc_offset': None, 'time_zone': None, 'geo_enabled': False, 'verified': False, 'statuses_count': 100, 'lang': None, 'contributors_enabled': False, 'is_translator': False, 'is_translation_enabled': False, 'profile_background_color': 'F5F8FA', 'profile_background_image_url': None, 'profile_background_image_url_https': None, 'profile_background_tile': False, 'profile_image_url': 'http://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', 'profile_banner_url': 'https://pbs.twimg.com/profile_banners/1295079294239223812/1607999522', 'profile_link_color': '1DA1F2', 'profile_sidebar_border_color': 'C0DEED', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_text_color': '333333', 'profile_use_background_image': True, 'has_extended_profile': True, 'default_profile': True, 'default_profile_image': False, 'following': False, 'follow_request_sent': False, 'notifications': False, 'translator_type': 'none', 'withheld_in_countries': []}, id=1295079294239223812, id_str='1295079294239223812', name='NLP con Vivi', screen_name='NLPconVivi', location='Konrad Lorenz', description='“La mejor clase del Universo 7, pero deja muchos talleres” ~ Gokú 2020', url=None, entities={'description': {'urls': []}}, protected=False, followers_count=15, friends_count=21, listed_count=0, created_at=datetime.datetime(2020, 8, 16, 19, 25, 55), favourites_count=56, utc_offset=None, time_zone=None, geo_enabled=False, verified=False, statuses_count=100, lang=None, contributors_enabled=False, is_translator=False, is_translation_enabled=False, profile_background_color='F5F8FA', profile_background_image_url=None, profile_background_image_url_https=None, profile_background_tile=False, profile_image_url='http://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', profile_image_url_https='https://pbs.twimg.com/profile_images/1338673815547768832/tMJaBsW8_normal.jpg', profile_banner_url='https://pbs.twimg.com/profile_banners/1295079294239223812/1607999522', profile_link_color='1DA1F2', profile_sidebar_border_color='C0DEED', profile_sidebar_fill_color='DDEEF6', profile_text_color='333333', profile_use_background_image=True, has_extended_profile=True, default_profile=True, default_profile_image=False, following=False, follow_request_sent=False, notifications=False, translator_type='none', withheld_in_countries=[]), geo=None, coordinates=None, place=None, contributors=None, is_quote_status=False, retweet_count=0, favorite_count=0, favorited=False, retweeted=False, lang='es')
tweets = tweepy.Cursor(api.search,
q=['giro de italia -RT'],
lang='es',
geocode=f'4.7110,-74.0721,100km',
tweet_mode='extended',
include_rts=False).items(100)
# Objeto generador
t = [tweet for tweet in tweets]
# t[0].
t_processed = []
for tweet in t:
temp = []
temp.append(tweet.full_text)
temp.append(tweet.created_at)
temp.append("Bogotá")
temp.append(tweet.user.location)
temp.append(tweet.id)
temp.append(f"https://twitter.com/i/web/status/{tweet.id}")
t_processed.append(temp)
data = pd.DataFrame(t_processed)
data.columns = ['tweet', 'date', 'city', 'user_location', 'id', 'link']
data.head()
tweet | date | city | user_location | id | link | |
---|---|---|---|---|---|---|
0 | #Giro | -60 Km: Pellaud y Gabburo salieron en ... | 2021-05-12 14:18:20 | Bogotá | Bogotá, D.C., Colombia | 1392484290567548930 | https://twitter.com/i/web/status/1392484290567... |
1 | #Giro | -60 Km: Pellaud y Gabburo salieron en ... | 2021-05-12 14:18:10 | Bogotá | Bogotá - Colombia | 1392484246418231305 | https://twitter.com/i/web/status/1392484246418... |
2 | #Giro | -70 Km: Cuatro equipos se organizan al... | 2021-05-12 14:08:16 | Bogotá | Bogotá, D.C., Colombia | 1392481757790937088 | https://twitter.com/i/web/status/1392481757790... |
3 | #Giro | -70 Km: Cuatro equipos se organizan al... | 2021-05-12 14:08:13 | Bogotá | Bogotá - Colombia | 1392481743039520777 | https://twitter.com/i/web/status/1392481743039... |
4 | #Giro | -80 Km: Todo tranquilo en el pelotón, ... | 2021-05-12 13:52:04 | Bogotá | Bogotá, D.C., Colombia | 1392477679568539650 | https://twitter.com/i/web/status/1392477679568... |
ciudades = pd.read_csv('../archivos/co_small.csv')
ciudades.head()
city | lat | lng | country | iso2 | admin | capital | population | population_proper | |
---|---|---|---|---|---|---|---|---|---|
0 | Bogotá | 4.649178 | -74.062827 | Colombia | CO | Bogotá | primary | 7772000.0 | 6333661.0 |
1 | Medellín | 6.251840 | -75.563591 | Colombia | CO | Antioquia | admin | 3297000.0 | 1999979.0 |
2 | Cali | 3.437222 | -76.522500 | Colombia | CO | Valle del Cauca | admin | 2254000.0 | 2178836.0 |
3 | Barranquilla | 10.963889 | -74.796389 | Colombia | CO | Atlántico | admin | 1798000.0 | 1244491.0 |
4 | Bucaramanga | 7.125393 | -73.119804 | Colombia | CO | Santander | admin | 1009000.0 | 571820.0 |
all_tweets = []
for ciudad in ciudades.iterrows():
c = ciudad[1]
gc = f"{c.lat},{c.lng},70km"
c_name = c.city
tweets = tweepy.Cursor(api.search,
q=['giro de italia -RT'],
lang='es',
geocode=gc,
tweet_mode='extended',
include_rts=False).items(20)
t = []
for tweet in tweets:
temp = []
temp.append(tweet.full_text)
temp.append(tweet.created_at)
temp.append(c_name)
temp.append(tweet.user.location)
temp.append(tweet.id)
temp.append(f"https://twitter.com/i/web/status/{tweet.id}")
t.append(temp)
all_tweets.extend(t)
print(c_name)
Bogotá Medellín Cali Barranquilla Bucaramanga Cartagena Cúcuta Pereira Santa Marta Ibagué Pasto Manizales Villavicencio Neiva Armenia Valledupar Montería Sincelejo Popayán Tunja Ríohacha Florencia Quibdó Arauca Yopal Leticia San Andrés San José del Guaviare Mocoa Puerto Carreño Mitú Inírida
data = pd.DataFrame(all_tweets)
data.columns = ['tweet', 'date', 'city', 'user_location', 'id', 'link']
data.head()
tweet | date | city | user_location | id | link | |
---|---|---|---|---|---|---|
0 | #Giro | -60 Km: Pellaud y Gabburo salieron en ... | 2021-05-12 14:18:10 | Bogotá | Bogotá - Colombia | 1392484246418231305 | https://twitter.com/i/web/status/1392484246418... |
1 | #Giro | -70 Km: Cuatro equipos se organizan al... | 2021-05-12 14:08:13 | Bogotá | Bogotá - Colombia | 1392481743039520777 | https://twitter.com/i/web/status/1392481743039... |
2 | #Giro | -80 Km: Todo tranquilo en el pelotón, ... | 2021-05-12 13:52:02 | Bogotá | Bogotá - Colombia | 1392477672488460291 | https://twitter.com/i/web/status/1392477672488... |
3 | #NuestroCiclismo \n\nLa fuga fue neutralizada ... | 2021-05-12 13:48:39 | Bogotá | Bogotá, Colombia | 1392476819509719042 | https://twitter.com/i/web/status/1392476819509... |
4 | #Giro | -90 Km: El pelotón empezó a acelerar, ... | 2021-05-12 13:42:11 | Bogotá | Bogotá - Colombia | 1392475193034035201 | https://twitter.com/i/web/status/1392475193034... |
data.to_csv("datos20210513.csv", index=False)
pip install snscrape
import snscrape.modules.twitter as sntwitter
maxTweets = 10
for i,tweet in enumerate(sntwitter.TwitterSearchScraper('#eragoldeyepes ' + 'since:2014-07-15 until:2014-08-15').get_items()) :
if i > maxTweets :
break
print(tweet)
print(tweet.date)
print(tweet.content)
print("*"*100)
print()
https://twitter.com/CANmialegria/status/500066563522056192 2014-08-14 23:48:54+00:00 Cambiemos el HT #EraGolDeYepes, por #EraGolDeCopete. ¡Nunca hubo fuera de lugar! ¿#LaCulpaEsDePostobon? @PradoVerde1999 @vamosmiverdecom **************************************************************************************************** https://twitter.com/cami_canoles/status/500064190288384000 2014-08-14 23:39:28+00:00 http://t.co/X3CpWL1Q3x #eragoldeyepes **************************************************************************************************** https://twitter.com/TamayoJr11/status/500062617969643520 2014-08-14 23:33:13+00:00 #EraGolDeYepes http://t.co/K9Am0bxOIh **************************************************************************************************** https://twitter.com/Edw_Chacon/status/500055868361412608 2014-08-14 23:06:24+00:00 JjaJja Todavia Me Acuerdo :') #EraGolDeYepes http://t.co/xFkiku07ae **************************************************************************************************** https://twitter.com/niko14p/status/500043243581882368 2014-08-14 22:16:14+00:00 #EraGolDeYepes **************************************************************************************************** https://twitter.com/SebastianTK1/status/500037065510486017 2014-08-14 21:51:41+00:00 #EraGolDeYepes **************************************************************************************************** https://twitter.com/vanegiraldo196/status/500033127444930560 2014-08-14 21:36:02+00:00 Día 42 #EraGolDeYepes **************************************************************************************************** https://twitter.com/DussanCristhian/status/500023139699802113 2014-08-14 20:56:21+00:00 Ahhhhh #yodespechado disfruto de mis amistades #PásalaJoven es mi#SituacionSentimental .y #EraGolDeYepes **************************************************************************************************** https://twitter.com/SaraBenavides27/status/500021235234136064 2014-08-14 20:48:47+00:00 #EraGolDeYepes . **************************************************************************************************** https://twitter.com/pildoradigital_/status/500011323502370816 2014-08-14 20:09:23+00:00 http://t.co/GGkbwNMx3w #EraGolDeYepes Ingresa y lee lo mejor del fútbol. **************************************************************************************************** https://twitter.com/melanyos_13/status/500007256214478849 2014-08-14 19:53:14+00:00 "@CBorrero01: Uno queriendo superar el #EraGolDeYepes y llega #DiarioDeUnSueño y me hace recaer." ****************************************************************************************************
data = data[['tweet', 'date', 'city']]
data.head()
tweet | date | city | |
---|---|---|---|
0 | #Giro | -60 Km: Pellaud y Gabburo salieron en ... | 2021-05-12 14:18:10 | Bogotá |
1 | #Giro | -70 Km: Cuatro equipos se organizan al... | 2021-05-12 14:08:13 | Bogotá |
2 | #Giro | -80 Km: Todo tranquilo en el pelotón, ... | 2021-05-12 13:52:02 | Bogotá |
3 | #NuestroCiclismo \n\nLa fuga fue neutralizada ... | 2021-05-12 13:48:39 | Bogotá |
4 | #Giro | -90 Km: El pelotón empezó a acelerar, ... | 2021-05-12 13:42:11 | Bogotá |
import re
pattern1 = '?P<pic>pic.twitter.com/[^\s]+'
pattern2 = '?P<url>https?://[^\s]+'
def text_clean(row):
text = row['tweet']
links = [tuple(j for j in i if j)[-1] for i in re.findall(f"({pattern1})|({pattern2})",text)]
for link in links:
text = text.replace(link,"")
hashtags = [interaction for interaction in text.split() if interaction.startswith("#")]
for hashtag in hashtags:
text = text.replace(hashtag,"")
mentions = [interaction for interaction in text.split() if interaction.startswith("@")]
for mention in mentions:
text = text.replace(mention,"")
return text, links, hashtags, mentions
data[['clean', 'links', 'hashtags', 'mentions']] = data.apply(text_clean, axis=1, result_type='expand')
data.head()
tweet | date | city | clean | links | hashtags | mentions | |
---|---|---|---|---|---|---|---|
0 | #Giro | -60 Km: Pellaud y Gabburo salieron en ... | 2021-05-12 14:18:10 | Bogotá | | -60 Km: Pellaud y Gabburo salieron en fuga ... | [https://t.co/87BnZr23FR] | [#Giro, #EnVivo] | [] |
1 | #Giro | -70 Km: Cuatro equipos se organizan al... | 2021-05-12 14:08:13 | Bogotá | | -70 Km: Cuatro equipos se organizan al fren... | [https://t.co/Iy1my4AuPW] | [#Giro, #EnVivo] | [] |
2 | #Giro | -80 Km: Todo tranquilo en el pelotón, ... | 2021-05-12 13:52:02 | Bogotá | | -80 Km: Todo tranquilo en el pelotón, sin i... | [https://t.co/XsrtQlQlko] | [#Giro, #EnVivo] | [] |
3 | #NuestroCiclismo \n\nLa fuga fue neutralizada ... | 2021-05-12 13:48:39 | Bogotá | \n\nLa fuga fue neutralizada y se espera una ... | [https://t.co/CaEIaCFaXL, https://t.co/M0Rilq2... | [#NuestroCiclismo, #DeportesRCN] | [] |
4 | #Giro | -90 Km: El pelotón empezó a acelerar, ... | 2021-05-12 13:42:11 | Bogotá | | -90 Km: El pelotón empezó a acelerar, con e... | [https://t.co/FG9SYFMqmU] | [#Giro, #EnVivo] | [] |
pip install regex
pip install emoji
import regex
import emoji
def get_emojis(text):
emoji_list = []
data = regex.findall(r'\X', text)
for word in data:
if any(char in emoji.UNICODE_EMOJI['en'] for char in word):
emoji_list.append(word)
return emoji_list
data['emojis'] = data['clean'].apply(lambda text: get_emojis(text))
data.head()
tweet | date | city | clean | links | hashtags | mentions | emojis | |
---|---|---|---|---|---|---|---|---|
0 | #Giro | -60 Km: Pellaud y Gabburo salieron en ... | 2021-05-12 14:18:10 | Bogotá | | -60 Km: Pellaud y Gabburo salieron en fuga ... | [https://t.co/87BnZr23FR] | [#Giro, #EnVivo] | [] | [] |
1 | #Giro | -70 Km: Cuatro equipos se organizan al... | 2021-05-12 14:08:13 | Bogotá | | -70 Km: Cuatro equipos se organizan al fren... | [https://t.co/Iy1my4AuPW] | [#Giro, #EnVivo] | [] | [] |
2 | #Giro | -80 Km: Todo tranquilo en el pelotón, ... | 2021-05-12 13:52:02 | Bogotá | | -80 Km: Todo tranquilo en el pelotón, sin i... | [https://t.co/XsrtQlQlko] | [#Giro, #EnVivo] | [] | [] |
3 | #NuestroCiclismo \n\nLa fuga fue neutralizada ... | 2021-05-12 13:48:39 | Bogotá | \n\nLa fuga fue neutralizada y se espera una ... | [https://t.co/CaEIaCFaXL, https://t.co/M0Rilq2... | [#NuestroCiclismo, #DeportesRCN] | [] | [] |
4 | #Giro | -90 Km: El pelotón empezó a acelerar, ... | 2021-05-12 13:42:11 | Bogotá | | -90 Km: El pelotón empezó a acelerar, con e... | [https://t.co/FG9SYFMqmU] | [#Giro, #EnVivo] | [] | [] |
Plotly: Herramienta de visualización interactiva. Funciona con Python, R, Julia, etc. Recurso
Dash: Entorno de trabajo para construir aplicaciones web (usa Flask y Plotly) Rescurso. Ejemplo
Flask: Entorno de trabajo para construir aplicaciones web para Python Recurso
pip install plotly
'''
data['fecha'] = data.date.dt.floor('T').dt.time
temp = pd.DataFrame(data.fecha.value_counts()).reset_index()
temp.columns = ['fecha', 'cnt']
temp = temp.sort_values('fecha')
temp
'''
data['fecha'] = data.date.dt.date
temp = pd.DataFrame(data.fecha.value_counts()).reset_index()
temp.columns = ['fecha', 'cnt']
temp = temp.sort_values('fecha')
temp
fecha | cnt | |
---|---|---|
7 | 2021-05-05 | 3 |
6 | 2021-05-06 | 3 |
5 | 2021-05-07 | 13 |
3 | 2021-05-08 | 31 |
4 | 2021-05-09 | 19 |
2 | 2021-05-10 | 44 |
1 | 2021-05-11 | 111 |
0 | 2021-05-12 | 135 |
import plotly.io as pio
import plotly.express as px
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import matplotlib.pyplot as plt
%matplotlib inline
init_notebook_mode(connected=True)
'''
trace = go.Scatter(x=temp.fecha.values,
y=temp.cnt.values,
text=[f"Fecha: {f}<br>Tuits: {c}" for f,c in zip(temp.fecha.values,temp.cnt.values)],
hoverinfo='text',
mode='lines+markers',
name='Días',
line={'color':'#1DA1F2'})
layout = go.Layout(title='Número de tuits por día')
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
'''
trace = go.Scatter(x=temp.fecha.values,
y=temp.cnt.values,
text=[f"Fecha: {f}<br>Tuits: {c}" for f,c in zip(temp.fecha.values,temp.cnt.values)],
hoverinfo='text',
mode='lines+markers',
name='Días',
line={'color':'#1DA1F2'})
layout = go.Layout(title='Número de tuits por día')
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
from collections import Counter
temp_emojis = pd.DataFrame(list(zip(Counter(sum(data.emojis.values,[])).keys(),Counter(sum(data.emojis.values,[])).values())))
temp_emojis.columns = ['emoji', 'cnt']
temp_emojis.sort_values('cnt', ascending=False, inplace=True)
temp_emojis.head()
emoji | cnt | |
---|---|---|
3 | 🚴♀️ | 16 |
24 | 👉 | 15 |
10 | 👇 | 13 |
13 | 🚴♂️ | 10 |
28 | ❗️️ | 9 |
trace = go.Bar(x=temp_emojis.emoji.values[:15],
y=temp_emojis.cnt.values[:15])
layout = go.Layout(title='Emojis más usados')
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
import datetime
temp_emoji = []
days = [datetime.date(2021, 5, 12),
datetime.date(2021, 5, 11),
datetime.date(2021, 5, 10),
datetime.date(2021, 5, 9),
datetime.date(2021, 5, 8),
datetime.date(2021, 5, 7),
datetime.date(2021, 5, 6),
datetime.date(2021, 5, 5),]
for day in days:
temp = pd.DataFrame(Counter(sum(data[data['fecha']==day]['emojis'].values,[])).most_common(5))
temp['day'] = day
temp_emoji.append(temp)
temp_emoji = pd.concat(temp_emoji)
temp_emoji.columns = ['emojis', 'tweet_count', 'day']
temp_emoji = temp_emoji.pivot(index='emojis', columns='day').reset_index()
temp_emoji.columns = ['emojis'] + list(temp_emoji.columns.get_level_values(1)[1:])
temp_emoji
emojis | 2021-05-05 00:00:00 | 2021-05-06 00:00:00 | 2021-05-07 00:00:00 | 2021-05-08 00:00:00 | 2021-05-09 00:00:00 | 2021-05-10 00:00:00 | 2021-05-11 00:00:00 | 2021-05-12 00:00:00 | |
---|---|---|---|---|---|---|---|---|---|
0 | ❗️ | 1.0 | 2.0 | NaN | 1.0 | NaN | 2.0 | NaN | NaN |
1 | ❗️️ | 1.0 | 2.0 | NaN | 1.0 | NaN | 2.0 | NaN | NaN |
2 | ➡️ | NaN | NaN | NaN | NaN | NaN | NaN | 4.0 | NaN |
3 | ⬇️ | NaN | NaN | NaN | NaN | NaN | 7.0 | NaN | NaN |
4 | 🏆 | NaN | NaN | 2.0 | NaN | NaN | NaN | NaN | 5.0 |
5 | 👇 | NaN | NaN | NaN | NaN | NaN | 5.0 | NaN | 6.0 |
6 | 👉 | 1.0 | 2.0 | NaN | 2.0 | 2.0 | 2.0 | NaN | NaN |
7 | 📝 | NaN | NaN | NaN | NaN | NaN | NaN | 5.0 | NaN |
8 | 📡 | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN |
9 | 🔍 | NaN | NaN | NaN | NaN | NaN | NaN | 3.0 | NaN |
10 | 🔴 | NaN | NaN | NaN | NaN | NaN | NaN | 3.0 | 5.0 |
11 | 🕰️ | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN |
12 | 🗞️ | NaN | NaN | 2.0 | NaN | NaN | NaN | NaN | NaN |
13 | 😓 | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN |
14 | 🚨 | NaN | NaN | 2.0 | NaN | NaN | NaN | NaN | NaN |
15 | 🚴♀️ | NaN | NaN | 2.0 | NaN | NaN | NaN | 4.0 | 9.0 |
16 | 🚴♂️ | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 8.0 |
17 | 🤩 | NaN | NaN | 2.0 | NaN | NaN | NaN | NaN | NaN |
18 | 🥇 | NaN | NaN | NaN | NaN | 1.0 | NaN | NaN | NaN |
beg = temp_emoji.columns[1]
listOfFrames = []
for year in temp_emoji.columns[1:]:
temp = temp_emoji[['emojis', year]]
temp = temp.sort_values(year, ascending=False).dropna()
trace = go.Bar(
x=temp.emojis.values,
y=temp[year].values,
textposition = "outside",
texttemplate = "%{x}<br>%{y}",
textfont = {'size': [14]*10},
hoverinfo='none',
opacity=1,
marker=dict(color="orange"),
cliponaxis = False
)
layout = go.Layout(title=f'Emojis del día {year.date()}',
xaxis = {"range":[-1,10],"autorange": False, "showline":False,"tickangle":-90, "visible":False},
yaxis = {"range":[-1,70],"autorange": False, "showline":False, "visible":False},
plot_bgcolor= '#FFFFFF')
listOfFrames.append(go.Frame(data=[trace], layout=layout))
frames=list(listOfFrames)
year = beg
temp = temp_emoji[['emojis', year]]
temp = temp.sort_values(year, ascending=False).dropna()
# Plot
trace = go.Bar(
x=temp.emojis.values,
y=temp[year].values,
textposition = "outside",
texttemplate = "%{x}<br>%{y}",
textfont = {'size': [14]*10},
hoverinfo='none',
opacity=1,
marker=dict(color="orange"),
cliponaxis = False
)
layout = go.Layout(title=f'Emojis del día {year.date()}',
xaxis = {"range":[-1,10],"autorange": False, "showline":False,"tickangle":-90, "visible":False},
yaxis = {"range":[-1,70],"autorange": False, "showline":False, "visible":False},
plot_bgcolor= '#FFFFFF',
updatemenus=[dict(type="buttons",
buttons=[dict(label="▶️",
method="animate",
args=[None, {"frame": {"duration": 800, "redraw": True},
"fromcurrent": True}]),
{
"args": [[None], {"frame": {"duration": 0, "redraw": True},
"mode": "immediate",
"transition": {"duration": 0}}],
"label": "⏸️",
"method": "animate"
}
]
)
]
)
fig = go.Figure(data=[trace], layout=layout, frames=frames)
fig.show()
import re
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
stopwords_sp = stopwords.words('spanish')
def pre_procesado(texto):
texto = texto.lower()
texto = re.sub(r"[\W\d_]+", " ", texto)
texto = " ".join([palabra for palabra in texto.split() if palabra not in stopwords_sp])
return texto
tfidf_vect = TfidfVectorizer(preprocessor=pre_procesado)
tfidf = tfidf_vect.fit_transform(data.clean.values)
from sklearn.metrics.pairwise import cosine_similarity
voc = [k for k,v in sorted(tfidf_vect.vocabulary_.items(), key=lambda kv: kv[1])]
temp = pd.DataFrame(tfidf.toarray())
temp = cosine_similarity(temp.values)
temp = pd.DataFrame(temp)
# temp.columns = data.tweet
# temp.index = data.tweet
temp
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1.000000 | 0.080158 | 0.166646 | 0.047203 | 0.096889 | 0.258957 | 0.282824 | 0.000000 | 0.142872 | 0.026358 | ... | 0.108336 | 0.035488 | 0.000000 | 0.000000 | 0.000000 | 0.023459 | 0.031704 | 0.062023 | 0.054211 | 0.057792 |
1 | 0.080158 | 1.000000 | 0.163913 | 0.000000 | 0.144729 | 0.044885 | 0.086534 | 0.000000 | 0.047943 | 0.021944 | ... | 0.047956 | 0.029545 | 0.000000 | 0.000000 | 0.000000 | 0.019530 | 0.026395 | 0.051637 | 0.045133 | 0.048114 |
2 | 0.166646 | 0.163913 | 1.000000 | 0.159159 | 0.198125 | 0.115562 | 0.118459 | 0.000000 | 0.065632 | 0.104271 | ... | 0.123469 | 0.040445 | 0.000000 | 0.000000 | 0.000000 | 0.026736 | 0.036133 | 0.070687 | 0.061784 | 0.065865 |
3 | 0.047203 | 0.000000 | 0.159159 | 1.000000 | 0.000000 | 0.044883 | 0.000000 | 0.000000 | 0.000000 | 0.210864 | ... | 0.047954 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
4 | 0.096889 | 0.144729 | 0.198125 | 0.000000 | 1.000000 | 0.054254 | 0.190172 | 0.000000 | 0.057950 | 0.026525 | ... | 0.057966 | 0.035712 | 0.000000 | 0.000000 | 0.000000 | 0.023607 | 0.116554 | 0.062414 | 0.054553 | 0.058156 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
354 | 0.023459 | 0.019530 | 0.026736 | 0.000000 | 0.023607 | 0.022306 | 0.025325 | 0.000000 | 0.023825 | 0.000000 | ... | 0.023832 | 0.035280 | 0.000000 | 0.044771 | 0.000000 | 1.000000 | 0.031518 | 0.025661 | 0.305539 | 0.023910 |
355 | 0.031704 | 0.026395 | 0.036133 | 0.000000 | 0.116554 | 0.030146 | 0.034226 | 0.029979 | 0.032200 | 0.012424 | ... | 0.075052 | 0.111105 | 0.432980 | 0.043283 | 0.432980 | 0.031518 | 1.000000 | 0.143281 | 0.030312 | 0.131364 |
356 | 0.062023 | 0.051637 | 0.070687 | 0.000000 | 0.062414 | 0.058974 | 0.066957 | 0.010797 | 0.062993 | 0.010115 | ... | 0.078441 | 0.061662 | 0.107261 | 0.021349 | 0.107261 | 0.025661 | 0.143281 | 1.000000 | 0.059300 | 0.177331 |
357 | 0.054211 | 0.045133 | 0.061784 | 0.000000 | 0.054553 | 0.051546 | 0.058523 | 0.000000 | 0.055058 | 0.000000 | ... | 0.055073 | 0.033930 | 0.000000 | 0.043057 | 0.000000 | 0.305539 | 0.030312 | 0.059300 | 1.000000 | 0.055254 |
358 | 0.057792 | 0.048114 | 0.065865 | 0.000000 | 0.058156 | 0.054951 | 0.062388 | 0.000000 | 0.058695 | 0.000000 | ... | 0.058711 | 0.036171 | 0.000000 | 0.000000 | 0.000000 | 0.023910 | 0.131364 | 0.177331 | 0.055254 | 1.000000 |
359 rows × 359 columns
trace = go.Heatmap(z=temp.values.tolist(),
x=temp.index.values,
y=temp.columns.values,
colorscale='Oranges')
layout = go.Layout(title='🔥 Mapa de calor entre tweets 🔥',
width=800, height=800)
fig = go.Figure(data=[trace],layout=layout)
iplot(fig)
import scipy.cluster.hierarchy as sch
import numpy as np
pairwise_distances = sch.distance.pdist(temp)
linkage = sch.linkage(pairwise_distances, method='ward')
idx_to_cluster_array = sch.fcluster(linkage, pairwise_distances.max() * 0.5, criterion='distance')
idx = np.argsort(idx_to_cluster_array)
temp = temp.copy()
temp2 = temp.iloc[idx, :].T.iloc[idx, :]
my_idx = idx_to_cluster_array
temp2.index = ['tweet #'+str(i) for i in temp2.columns]
temp2.columns = temp2.index
temp2
tweet #349 | tweet #188 | tweet #328 | tweet #227 | tweet #17 | tweet #186 | tweet #347 | tweet #326 | tweet #222 | tweet #12 | ... | tweet #246 | tweet #57 | tweet #303 | tweet #92 | tweet #62 | tweet #151 | tweet #19 | tweet #229 | tweet #58 | tweet #247 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
tweet #349 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | ... | 0.110505 | 0.110505 | 0.115465 | 0.151334 | 0.151334 | 0.151334 | 0.088032 | 0.088032 | 0.081292 | 0.081292 |
tweet #188 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | ... | 0.110505 | 0.110505 | 0.115465 | 0.151334 | 0.151334 | 0.151334 | 0.088032 | 0.088032 | 0.081292 | 0.081292 |
tweet #328 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | ... | 0.110505 | 0.110505 | 0.115465 | 0.151334 | 0.151334 | 0.151334 | 0.088032 | 0.088032 | 0.081292 | 0.081292 |
tweet #227 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | ... | 0.110505 | 0.110505 | 0.115465 | 0.151334 | 0.151334 | 0.151334 | 0.088032 | 0.088032 | 0.081292 | 0.081292 |
tweet #17 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | 0.280054 | ... | 0.110505 | 0.110505 | 0.115465 | 0.151334 | 0.151334 | 0.151334 | 0.088032 | 0.088032 | 0.081292 | 0.081292 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
tweet #151 | 0.151334 | 0.151334 | 0.151334 | 0.151334 | 0.151334 | 0.068791 | 0.068791 | 0.068791 | 0.068791 | 0.068791 | ... | 0.294685 | 0.294685 | 0.307910 | 1.000000 | 1.000000 | 1.000000 | 0.363106 | 0.363106 | 0.537172 | 0.537172 |
tweet #19 | 0.088032 | 0.088032 | 0.088032 | 0.088032 | 0.088032 | 0.060020 | 0.060020 | 0.060020 | 0.060020 | 0.060020 | ... | 0.107002 | 0.107002 | 0.111804 | 0.363106 | 0.363106 | 0.363106 | 1.000000 | 1.000000 | 0.368008 | 0.368008 |
tweet #229 | 0.088032 | 0.088032 | 0.088032 | 0.088032 | 0.088032 | 0.060020 | 0.060020 | 0.060020 | 0.060020 | 0.060020 | ... | 0.107002 | 0.107002 | 0.111804 | 0.363106 | 0.363106 | 0.363106 | 1.000000 | 1.000000 | 0.368008 | 0.368008 |
tweet #58 | 0.081292 | 0.081292 | 0.081292 | 0.081292 | 0.081292 | 0.036953 | 0.036953 | 0.036953 | 0.036953 | 0.036953 | ... | 0.158296 | 0.158296 | 0.165401 | 0.537172 | 0.537172 | 0.537172 | 0.368008 | 0.368008 | 1.000000 | 1.000000 |
tweet #247 | 0.081292 | 0.081292 | 0.081292 | 0.081292 | 0.081292 | 0.036953 | 0.036953 | 0.036953 | 0.036953 | 0.036953 | ... | 0.158296 | 0.158296 | 0.165401 | 0.537172 | 0.537172 | 0.537172 | 0.368008 | 0.368008 | 1.000000 | 1.000000 |
359 rows × 359 columns
trace = go.Heatmap(z=temp2.values.tolist(),
x=temp2.index.values,
y=temp2.columns.values,
colorscale='Oranges')
layout = go.Layout(title='🔥 Mapa de calor entre tweets (ordenado) 🔥',
width=800, height=800)
fig = go.Figure(data=[trace],layout=layout)
iplot(fig)
imprimir = [37, 106, 36, 104]
for i in imprimir:
print(data.tweet[i])
print()
#Giro104 🇮🇹 Taco Van Der Hoorn ganó la tercera etapa del Giro de Italia. 🇨🇴 7. Fernando Gaviria. 🇨🇴 27. Egan Bernal. #WbeimarLoDice https://t.co/TUxt5K11ri Fernando Gaviria ganó el neerlandés Taco van der Hoorn del Giro de Italia https://t.co/IHlKIlqZp0 #Giro104 🇮🇹 Taco Van Der Hoorn ganó la tercera etapa del Giro de Italia. 🇨🇴 7. Fernando Gaviria. 🇨🇴 27. Egan Bernal. #WbeimarLoDice https://t.co/f8zyMTfTae Taco van se quedó con la etapa cuarta del GIRO de ITALIA. https://t.co/l6UjmGb5m5 Vía @ESPN App https://t.co/tVokyP0s3w
data['cluster'] = my_idx
for c in data.cluster.value_counts().index:
df_temp = data[data.cluster==c]
if df_temp.shape[0]<5:
break
sim = temp2[['tweet #'+str(i) for i in df_temp.index]].mean().mean()
print(f"***** El cluster {c} tiene {df_temp.shape[0]} tweets con una similaridad de {sim:.2%} *****\n")
tweets_ejemplo = df_temp.head().tweet.values
for te in tweets_ejemplo:
print(te)
print()
print()
***** El cluster 43 tiene 17 tweets con una similaridad de 1.84% ***** #pactociudadano Que bien‼️ @Eganbernal🤙🏼🙏🏼buena carrera hoy🤙🏼 Giro de Italia. Bendiciones 🙏🏼🤙🏼siempre adelante! Esas bicicletas CUBE como que siempre me habían parecido bicis chinas de baja calidad (uno las encontraba extrañamente baratas por ahí), pero ahora que las veo en Giro de Italia (son alemanas a la altura de una canyon), se me antojan. Lo que hace la publicidad ome 🥲 @contracomu Ya estoy viendo El Giro de Italia. Jaja. Desde las 5 creo En la etapa cuatro, que termina en Sestela, se empezará a ver quiénes son los más fuertes en el pelotón. Le contamos quiénes son los favoritos 👇 https://t.co/JePJVvwiwy 🏆🚴♂️💖@Elite_cycling¡rinde homenaje a los grandes campeones del Giro de Italia con la icónica botella Fly Giro! ¡The Fly es la botella más ligera del mundo con su peso de 54 g! #Giro| @YajuegoCo| #BandaDeportiva https://t.co/caBaoaKvNP ***** El cluster 11 tiene 10 tweets con una similaridad de 7.63% ***** #Giro | Siga el minuto a minuto de la etapa 5 del Giro de Italia 2021 [EN VIVO] #EnVivo https://t.co/P8b4PJDR93 #ElGiroPorCaracol l Giro de Italia minuto a minuto: siga la actuación de los colombianos en la etapa 5 https://t.co/6Wcqb3Vmfv En vivo - Minuto a minuto 4 etapa del Giro de Italia 2021. #NoticiasBQ 🔴🟡🟢➡️https://t.co/hfvH9IwaM9 https://t.co/qhMltvhGGg En vivo - Minuto a minuto 4 etapa del Giro de Italia 2021. #NoticiasBQ 🔴🟡🟢➡️https://t.co/hfvH9IwaM9 https://t.co/qhMltvhGGg En vivo - Minuto a minuto 4 etapa del Giro de Italia 2021. #NoticiasBQ 🔴🟡🟢➡️https://t.co/hfvH9IwaM9 https://t.co/qhMltvhGGg ***** El cluster 42 tiene 8 tweets con una similaridad de 3.90% ***** Se corrió la primera etapa con montaña en el Giro de Italia. En Hora 13 Noticias tenemos el resumen de la jornada. https://t.co/cBnlmlu23n Lluvia, fuga y batalla con diferencias entre los candidatos al título. Lo que pasó en la etapa 4 del Giro de Italia, a mi estilo, en: https://t.co/GpvgVrGUqD Se corrió la tercera etapa del Giro de Italia y en Hora 13 Noticias tenemos el análisis de lo ocurrido en este importante evento ciclístico. El antioqueño Fernando Gaviria no puedo ganar, fue séptimo en la etapa.https://t.co/6c1PTjOzDu 💗 Giro de Italia 2021 - Etapa 5 ⃣ 📌 Faenza - km 87 🚴♂️ Grupo compacto 🚴♂️ 💻 En vivo:https://t.co/SbPaTVzmfs 🏁 90 kilometros 💰 Apuesta en @YajuegoCo #Giro| #BandaDeportiva https://t.co/MyTLHgtUi1 Giro de Italia 2021: Clasificaciones de la etapa 3 https://t.co/slNjzUkVoR ***** El cluster 58 tiene 7 tweets con una similaridad de 3.78% ***** 🚴♀️¡La fuga se consolidó y pudo llegar a puerto! ¿Cómo se crea una fuga perfecta? En #TeleantioquiaDeportes analizamos la tercera etapa del Giro de Italia 🇮🇹con especial énfasis en este tema, porque Van der Hoorn sí que emocionó. ➡️https://t.co/X97xy1fB41 https://t.co/0dgt1BFDBj Taco Van Der Hoorn se metió en la fuga que era y su historia cambió. Lo que pasó en la etapa 4 del Giro de Italia, a mi estilo, en: https://t.co/2HgGPE0A6z #Giro 🇮🇹 ¡La fuga celebra! Taco van der Hoorm se lleva la etapa 3. El corredor del Intermaché Wanty-Gobert Matériaux cumplió el sueño de la victoria de etapa en su primera participación en una Gran Vuelta. 📸 Giro de Italia Oficial https://t.co/1GZEyV65rg Giro de Italia: Taco van der Hoorn: "No puedo creer que haya ganado" https://t.co/JVZbtmXhH6 #Deportes | De 27 años, Van der Hoorn logró la cuarta victoria de su carrera, aunque de lejos la más importante desde que debutó en profesionales en 2017 https://t.co/TbsLocgDEx ***** El cluster 41 tiene 7 tweets con una similaridad de 3.23% ***** 📝Vuelve el terreno llano al Giro de Italia 2021. Quinta etapa de la 'Corsa Rosa' desde Modena Cattolica con un perfil totalmente ideal para los velocistas, el recorrido tendrá un total de 177 kilómetros. 🧐Me parece que es el momento de Fernando Gaviria. #Giro104 https://t.co/z9eWEpwtSj Primera prueba de fuego 💥 📝Cuarta etapa del Giro de Italia 2021 🇮🇹🚴♂️ que tendrá un recorrido de 187 kilómetros desde Piacenza hasta Sestola con un perfil de mucha exigencia, puertos de montaña que tendrán hasta rampas del 10% de desnivel con rampas estrechas. #Giro104 https://t.co/KHhbps2L4D 📝Tercera etapa del Giro de Italia 2021 🇮🇹🚴🏾♂️ desde Biella hasta Canale con un recorrido de 190 kilómetros. El perfil presenta tres puertos encadenados en el segundo tramo y uno al final no categorizado que puede descolgar a algunos velocistas de cara a la llegada. #Giro104 https://t.co/f0JDguRiNx de 177 Kilómetros, con inicio en Modena y final en Cattolica. Consulta la clasificación del Giro de Italia 2021, en directo Favoritos para hacerse con la victoria en el Giro ASDRUBAL OSORIO PELÁEZ ® #PENSAMIENTOSINFRONTERAS8️⃣AÑOS ™ 5️⃣7️⃣ AÑOS DE HISTORIA https://t.co/oJDZ21vct6 #Colombia🇨🇴 #GIROxESPN #HistoryLA🌎 10 05 2021 Giro de Italia 2021 hoy, etapa 3: perfil y recorrido Peter Sagan considera que el perfil con tres cotas camino de Canale le puede permitir endurecer la carrera y eliminar a los velocistas puros. https://t.co/qkWARymOg2 ***** El cluster 53 tiene 6 tweets con una similaridad de 7.29% ***** #Giro104 🇮🇹 Taco Van Der Hoorn ganó la tercera etapa del Giro de Italia. 🇨🇴 7. Fernando Gaviria. 🇨🇴 27. Egan Bernal. #WbeimarLoDice https://t.co/f8zyMTfTae #Giro104 🇮🇹 Taco Van Der Hoorn ganó la tercera etapa del Giro de Italia. 🇨🇴 7. Fernando Gaviria. 🇨🇴 27. Egan Bernal. #WbeimarLoDice https://t.co/TUxt5K11ri Fernando Gaviria ganó el neerlandés Taco van der Hoorn del Giro de Italia https://t.co/IHlKIlqZp0 Fernando Gaviria ganó el neerlandés Taco van der Hoorn del Giro de Italia https://t.co/IHlKIlqZp0 Fernando Gaviria ganó el neerlandés Taco van der Hoorn del Giro de Italia https://t.co/IHlKIlqZp0 ***** El cluster 80 tiene 6 tweets con una similaridad de 6.00% ***** Hecho en América: Joseph Dombrowski ganó etapa 4 del Giro de Italia [VIDEO] https://t.co/gTlWkuf7mb Hecho en América: Joseph Dombrowski ganó etapa 4 del Giro de Italia [VIDEO] #Giro https://t.co/vpor0B5a4N Hecho en América: Joseph Dombrowski ganó etapa 4 del Giro de Italia [VIDEO] https://t.co/gTlWkuf7mb Hecho en América: Joseph Dombrowski ganó etapa 4 del Giro de Italia [VIDEO] #Giro https://t.co/vpor0B5a4N Hecho en América: Joseph Dombrowski ganó etapa 4 del Giro de Italia [VIDEO] https://t.co/gTlWkuf7mb ***** El cluster 93 tiene 6 tweets con una similaridad de 5.33% ***** Giro de Italia 2021 | Etapa 5: ¿cuáles son los rivales de Fernando Gaviria? #Giro #GiroDitalia2021 #MagliaRosa #GiroDitalia #SemanaEnLaRuta https://t.co/MeumLV13Eb Giro de Italia 2021 | Etapa 5: Fernando Gaviria, convencido de la victoria en Cattolica. #Giro #GiroDitalia2021 #MagliaRosa #GiroDitalia #SemanaEnLaRuta https://t.co/s7NuPdu3eN Giro de Italia 2021: ¿cuáles son los rivales de Fernando Gaviria? #Giro #GiroDitalia2021 #MagliaRosa #GiroDitalia #SemanaEnLaRuta https://t.co/b1pieyMoJy Giro de Italia 2021 | Etapa 5: ¿cuáles son los rivales de Fernando Gaviria? #Giro #GiroDitalia2021 #MagliaRosa #GiroDitalia #SemanaEnLaRuta https://t.co/MeumLV13Eb Giro de Italia 2021 | Etapa 5: Fernando Gaviria, convencido de la victoria en Cattolica. #Giro #GiroDitalia2021 #MagliaRosa #GiroDitalia #SemanaEnLaRuta https://t.co/s7NuPdu3eN ***** El cluster 21 tiene 5 tweets con una similaridad de 3.18% ***** #Deportes | El ciclista belga Tim Merlier (Alpecin-Fenix) se quedó este domingo con la segunda etapa del Giro de Italia, disputada entre Stupinigi y Novara sobre 179 kilómetros https://t.co/HiyDnYRtJm #Deportes | El ciclista belga Tim Merlier (Alpecin-Fenix) se quedó este domingo con la segunda etapa del Giro de Italia, disputada entre Stupinigi y Novara sobre 179 kilómetros https://t.co/Np1wiCuEfv 🥇Por segundo año consecutivo Tim Merlier 🇧🇪 (Alpecin-Fenix) celebra una victoria en territorio italiano. En la temporada anterior se impuso en la sexta etapa de la Tirreno Adriatico y hoy lo hace en la segunda jornada del Giro de Italia. #Giro104 https://t.co/KpVyefDg1M El pedalista belga Tim Merlier, del equipo Alpecin-Fenix, se impuso en el ‘sprint’ final y se quedó con la fracción, que se disputó entre Stupinigi y Novara. ❗️️Noticia completa❗️👉 https://t.co/ymeqY2ITpT https://t.co/l9FUTCU3H4 #Deportes #Ciclismo #Europa #Italia #QuintoPoder • El ciclista belga Tim Merlier (Alpecin) se ha impuesto en la primera llegada masiva del Giro de Italia por delante de Nizzolo (Team Qhubeka), Viviani (Cofidis), Groenewegen (Jumbo Visma) y Peter Sagan (Bora Hansgrohe). https://t.co/JjE9P4hZET ***** El cluster 2 tiene 5 tweets con una similaridad de 4.81% ***** #Giro | -150 Km: Se mantienen Tagliani y Marenga en la fuga del día, mientras el pelotón trata de no alejarse mucho [EN VIVO] #EnVivo https://t.co/RIPyKeaYvv #Giro | -150 Km: Se mantienen Tagliani y Marenga en la fuga del día, mientras el pelotón trata de no alejarse mucho [EN VIVO] #EnVivo https://t.co/Lu5W3pob1F #Giro | -150 Km: Se mantienen Tagliani y Marenga en la fuga del día, mientras el pelotón trata de no alejarse mucho [EN VIVO] #EnVivo https://t.co/RIPyKeaYvv #Giro | -150 Km: Se mantienen Tagliani y Marenga en la fuga del día, mientras el pelotón trata de no alejarse mucho [EN VIVO] #EnVivo https://t.co/Lu5W3pob1F #Giro | -150 Km: Se mantienen Tagliani y Marenga en la fuga del día, mientras el pelotón trata de no alejarse mucho [EN VIVO] #EnVivo https://t.co/Lu5W3pob1F ***** El cluster 45 tiene 5 tweets con una similaridad de 2.31% ***** #GiroDeItalia | El italiano Filippo Ganna se impuso este sábado en el prólogo que marcó el comienzo de la edición número 104 del Giro de Italia y se enfundó la primera maglia rosa. https://t.co/L4AUjzqlw1 El italiano Filippo Ganna, campeón mundial de contrarreloj, confirmó su favoritismo y se convirtió en el primer líder de la 'Corsa Rosa'. ❗️️Noticia completa❗️👉 https://t.co/BOPVXNfD9a https://t.co/PXTlCGpHHC En total, serán 6 los ‘cafeteros’ que tomarán la partida este sábado 8 de mayo en la ‘corsa rosa’, competición de 21 etapas que irá hasta el 30 de mayo. ❗️️Noticia completa❗️👉 https://t.co/CG54ERm9h2 https://t.co/t020EAJJaQ #Colombia🇨🇴 #GiroXCaracol #HistoryLA🌎 #NatGeoEs #MundoDeportivo #Pinterest 08 05 2021 ¡¡Dale a cada día, la posibilidad de de convertirse en el mejor día de tu vida!! Vive desde hoy 8 de mayo y hasta el 30 de mayo el Giro de Italia 2021 104 años. https://t.co/7ug74EgOFh https://t.co/BaRQoYzJZm Los ciclistas boyacenses, Einer Rubio, de #Chíquiza (Movistar Team) y Sebastián Molano de #Paipa, #Boyacá (Team Emiratos UAE) integran la lista de los 6 ciclistas colombianos que desde el sábado 8 de Mayo y hasta el 30 del mismo mes correrán el Giro de Italia. https://t.co/lMJKV041Kq ***** El cluster 71 tiene 5 tweets con una similaridad de 4.48% ***** Muy buena la parte final de la 4 etapa del Giro de Italia 2021 🇮🇹 con Egan Bernal siendo protagonista #ElGiroPorCaracol #GIROxESPN #giroditalia DANIEL MARTÍNEZ quedó a 39 segundos del líder FILIPO GANNA en el Giro de Italia. EGAN Bernal está a 42”, mientras FERNANDO GAVIRIA y HÁROLD TEJADA se distancian 44”. Hoy Egan Bernal demostró, que si su espalda responde, peleará el Giro de Italia. Egan Bernal confesó cuál es su mayor miedo en el Giro de Italia https://t.co/wkOUyh3c5Q Ineos confirma a Egan Bernal para el Giro de Italia https://t.co/YWi3pJ3ukB https://t.co/EFMVGgTjFL ***** El cluster 74 tiene 5 tweets con una similaridad de 9.27% ***** #DEPORTES | Así le fue a Egan Bernal tras la etapa 4 del Giro de Italia 🔍https://t.co/7lxwOv19xa https://t.co/0ymkl3Znzt Así le fue a Egan Bernal tras la etapa 4 del Giro de Italia - https://t.co/qyGGUogxJi https://t.co/hKRPpkUy5y #DEPORTES | Así le fue a Egan Bernal tras la etapa 4 del Giro de Italia 🔍https://t.co/7lxwOv19xa https://t.co/0ymkl3Znzt Así le fue a Egan Bernal tras la etapa 4 del Giro de Italia - https://t.co/qyGGUogxJi https://t.co/hKRPpkUy5y #DEPORTES | Así le fue a Egan Bernal tras la etapa 4 del Giro de Italia 🔍https://t.co/7lxwOv19xa https://t.co/0ymkl3Znzt ***** El cluster 31 tiene 5 tweets con una similaridad de 3.03% ***** Ya estamos EN VIVO por nuestra pantalla principal con la etapa 5 de #ElGiroPorCaracol 🚴♀️ Los velocistas tienen un nuevo round y usted no se lo puede perder. Conéctese a nuestras plataformas >>> https://t.co/bev6hsV4uJ https://t.co/FQCjEZF5b2 #ElGiroPorCaracol Einer Rubio disputa su segundo Giro de Italia. El colombiano es gregario, pero podría luchar por una victoria de etapa. Vea toda la información de la carrera y más perfiles de nuestros ciclistas en >>> https://t.co/Nqam2KUmKf https://t.co/fGxxz7pF4d Ya estamos EN VIVO por nuestra pantalla principal con la etapa 5 de #ElGiroPorCaracol 🚴♀️ Los velocistas tienen un nuevo round y usted no se lo puede perder. Conéctese a nuestras plataformas >>> https://t.co/bev6hsV4uJ https://t.co/FQCjEZF5b2 #ElGiroPorCaracol Einer Rubio disputa su segundo Giro de Italia. El colombiano es gregario, pero podría luchar por una victoria de etapa. Vea toda la información de la carrera y más perfiles de nuestros ciclistas en >>> https://t.co/Nqam2KUmKf https://t.co/fGxxz7pF4d Conéctese ya y vea EN VIVO 🔴 a los colombianos en la etapa 5 de #ElGiroPorCaracol Fernando Gaviria y Juan Sebastián Molano tendrán una nueva oportunidad al esprint >>> https://t.co/bev6htcFTj https://t.co/GRiDIMNuGp ***** El cluster 1 tiene 5 tweets con una similaridad de 6.93% ***** #Giro | -176 Km: Comenzó la quinta etapa del Giro de Italia, con dos ciclistas buscando la primera fuga del día, que son Tagliani y Marengo [EN VIVO] #EnVivo https://t.co/wvWhbV2oEw #Giro | -176 Km: Comenzó la quinta etapa del Giro de Italia, con dos ciclistas buscando la primera fuga del día, que son Tagliani y Marengo [EN VIVO] #EnVivo https://t.co/wzK61kr8FH #Giro | -176 Km: Comenzó la quinta etapa del Giro de Italia, con dos ciclistas buscando la primera fuga del día, que son Tagliani y Marengo [EN VIVO] #EnVivo https://t.co/wvWhbV2oEw #Giro | -176 Km: Comenzó la quinta etapa del Giro de Italia, con dos ciclistas buscando la primera fuga del día, que son Tagliani y Marengo [EN VIVO] #EnVivo https://t.co/wzK61kr8FH #Giro | -176 Km: Comenzó la quinta etapa del Giro de Italia, con dos ciclistas buscando la primera fuga del día, que son Tagliani y Marengo [EN VIVO] #EnVivo https://t.co/wzK61kr8FH ***** El cluster 8 tiene 5 tweets con una similaridad de 4.67% ***** #Giro | -110 Km: Los dos fugados se acercan al primer punto de sprint intermedio y el pelotón persigue a 1:47 [EN VIVO] #EnVivo https://t.co/eVho1MTT0t #Giro | -110 Km: Los dos fugados se acercan al primer punto de sprint intermedio y el pelotón persigue a 1:47 [EN VIVO] #EnVivo https://t.co/GWnxYyFWvv #Giro | -110 Km: Los dos fugados se acercan al primer punto de sprint intermedio y el pelotón persigue a 1:47 [EN VIVO] #EnVivo https://t.co/eVho1MTT0t #Giro | -110 Km: Los dos fugados se acercan al primer punto de sprint intermedio y el pelotón persigue a 1:47 [EN VIVO] #EnVivo https://t.co/GWnxYyFWvv #Giro | -110 Km: Los dos fugados se acercan al primer punto de sprint intermedio y el pelotón persigue a 1:47 [EN VIVO] #EnVivo https://t.co/GWnxYyFWvv ***** El cluster 4 tiene 5 tweets con una similaridad de 4.63% ***** #Giro | -80 Km: Todo tranquilo en el pelotón, sin intentos de fuga y ningún equipo se pone al frente [EN VIVO] #EnVivo https://t.co/XsrtQlQlko #Giro | -80 Km: Todo tranquilo en el pelotón, sin intentos de fuga y ningún equipo se pone al frente [EN VIVO] #EnVivo https://t.co/gS5xo487aS #Giro | -80 Km: Todo tranquilo en el pelotón, sin intentos de fuga y ningún equipo se pone al frente [EN VIVO] #EnVivo https://t.co/XsrtQlQlko #Giro | -80 Km: Todo tranquilo en el pelotón, sin intentos de fuga y ningún equipo se pone al frente [EN VIVO] #EnVivo https://t.co/gS5xo487aS #Giro | -80 Km: Todo tranquilo en el pelotón, sin intentos de fuga y ningún equipo se pone al frente [EN VIVO] #EnVivo https://t.co/gS5xo487aS ***** El cluster 10 tiene 5 tweets con una similaridad de 5.38% ***** #Giro | -160 Km: Los dos fugados le sacan 3:23 minutos al pelotón, donde están los seis colombianos [EN VIVO] #EnVivo https://t.co/g9LpQKMInp #Giro | -160 Km: Los dos fugados le sacan 3:23 minutos al pelotón, donde están los seis colombianos [EN VIVO] #EnVivo https://t.co/Ij3WtIDIzB #Giro | -160 Km: Los dos fugados le sacan 3:23 minutos al pelotón, donde están los seis colombianos [EN VIVO] #EnVivo https://t.co/g9LpQKMInp #Giro | -160 Km: Los dos fugados le sacan 3:23 minutos al pelotón, donde están los seis colombianos [EN VIVO] #EnVivo https://t.co/Ij3WtIDIzB #Giro | -160 Km: Los dos fugados le sacan 3:23 minutos al pelotón, donde están los seis colombianos [EN VIVO] #EnVivo https://t.co/Ij3WtIDIzB ***** El cluster 6 tiene 5 tweets con una similaridad de 4.35% ***** #Giro | -60 Km: Pellaud y Gabburo salieron en fuga del pelotón, sacándoles 1:16 y aceleran para el último punto de sprint [EN VIVO] #EnVivo https://t.co/87BnZr23FR #Giro | -60 Km: Pellaud y Gabburo salieron en fuga del pelotón, sacándoles 1:16 y aceleran para el último punto de sprint [EN VIVO] #EnVivo https://t.co/WO6sJnOayA #Giro | -60 Km: Pellaud y Gabburo salieron en fuga del pelotón, sacándoles 1:16 y aceleran para el último punto de sprint [EN VIVO] #EnVivo https://t.co/87BnZr23FR #Giro | -60 Km: Pellaud y Gabburo salieron en fuga del pelotón, sacándoles 1:16 y aceleran para el último punto de sprint [EN VIVO] #EnVivo https://t.co/WO6sJnOayA #Giro | -60 Km: Pellaud y Gabburo salieron en fuga del pelotón, sacándoles 1:16 y aceleran para el último punto de sprint [EN VIVO] #EnVivo https://t.co/WO6sJnOayA ***** El cluster 15 tiene 5 tweets con una similaridad de 4.20% ***** Estas son las principales etapas del Giro de Italia 2021 https://t.co/HiHeJ2xf7t Todos los datos de las 21 etapas de Giro de Italia 2021 https://t.co/TgxV1Kaonk Todos los datos de las 21 etapas de Giro de Italia 2021 https://t.co/TgxV1Kaonk Todos los datos de las 21 etapas de Giro de Italia 2021 https://t.co/TgxV1Kaonk #DEPORTES | Giro de Italia: 21 etapas a lo largo de 3.840 kilómetros 👉https://t.co/uWq8jyiUA4 https://t.co/ARVIr7KdRU ***** El cluster 5 tiene 5 tweets con una similaridad de 4.66% ***** #Giro | -140 Km: El pelotón le da más ventaja a la fuga y se encuentran con 4:10 [EN VIVO] #EnVivo https://t.co/8fiG2KRd36 #Giro | -140 Km: El pelotón le da más ventaja a la fuga y se encuentran con 4:10 [EN VIVO] #EnVivo https://t.co/wFbEdgif0k #Giro | -140 Km: El pelotón le da más ventaja a la fuga y se encuentran con 4:10 [EN VIVO] #EnVivo https://t.co/8fiG2KRd36 #Giro | -140 Km: El pelotón le da más ventaja a la fuga y se encuentran con 4:10 [EN VIVO] #EnVivo https://t.co/wFbEdgif0k #Giro | -140 Km: El pelotón le da más ventaja a la fuga y se encuentran con 4:10 [EN VIVO] #EnVivo https://t.co/wFbEdgif0k ***** El cluster 12 tiene 5 tweets con una similaridad de 4.35% ***** #Giro | -120 Km: El plan de UAE es lanzar a Fernando Gaviria en los último kilómetros, con la ayuda de Molano y Richeze [EN VIVO] #EnVivo https://t.co/0wuZETgw1Y #Giro | -120 Km: El plan de UAE es lanzar a Fernando Gaviria en los último kilómetros, con la ayuda de Molano y Richeze [EN VIVO] #EnVivo https://t.co/qTTMwlEcB0 #Giro | -120 Km: El plan de UAE es lanzar a Fernando Gaviria en los último kilómetros, con la ayuda de Molano y Richeze [EN VIVO] #EnVivo https://t.co/0wuZETgw1Y #Giro | -120 Km: El plan de UAE es lanzar a Fernando Gaviria en los último kilómetros, con la ayuda de Molano y Richeze [EN VIVO] #EnVivo https://t.co/qTTMwlEcB0 #Giro | -120 Km: El plan de UAE es lanzar a Fernando Gaviria en los último kilómetros, con la ayuda de Molano y Richeze [EN VIVO] #EnVivo https://t.co/qTTMwlEcB0 ***** El cluster 9 tiene 5 tweets con una similaridad de 4.43% ***** #Giro | -90 Km: El pelotón empezó a acelerar, con el INEOS y el Deceuninck al frente para cerrarle espacio a nuevo fugados [EN VIVO] #EnVivo https://t.co/FG9SYFMqmU #Giro | -90 Km: El pelotón empezó a acelerar, con el INEOS y el Deceuninck al frente para cerrarle espacio a nuevo fugados [EN VIVO] #EnVivo https://t.co/VoBMGndcwJ #Giro | -90 Km: El pelotón empezó a acelerar, con el INEOS y el Deceuninck al frente para cerrarle espacio a nuevo fugados [EN VIVO] #EnVivo https://t.co/FG9SYFMqmU #Giro | -90 Km: El pelotón empezó a acelerar, con el INEOS y el Deceuninck al frente para cerrarle espacio a nuevo fugados [EN VIVO] #EnVivo https://t.co/VoBMGndcwJ #Giro | -90 Km: El pelotón empezó a acelerar, con el INEOS y el Deceuninck al frente para cerrarle espacio a nuevo fugados [EN VIVO] #EnVivo https://t.co/VoBMGndcwJ ***** El cluster 3 tiene 5 tweets con una similaridad de 3.47% ***** #Giro | -70 Km: Cuatro equipos se organizan al frente del pelotón, que son el BikeExchange, Israel Start Up Nation, Bahrain Victorious y Bora [EN VIVO] #EnVivo https://t.co/Iy1my4AuPW #Giro | -70 Km: Cuatro equipos se organizan al frente del pelotón, que son el BikeExchange, Israel Start Up Nation, Bahrain Victorious y Bora [EN VIVO] #EnVivo https://t.co/MAkvVZ8QxN #Giro | -70 Km: Cuatro equipos se organizan al frente del pelotón, que son el BikeExchange, Israel Start Up Nation, Bahrain Victorious y Bora [EN VIVO] #EnVivo https://t.co/Iy1my4AuPW #Giro | -70 Km: Cuatro equipos se organizan al frente del pelotón, que son el BikeExchange, Israel Start Up Nation, Bahrain Victorious y Bora [EN VIVO] #EnVivo https://t.co/MAkvVZ8QxN #Giro | -70 Km: Cuatro equipos se organizan al frente del pelotón, que son el BikeExchange, Israel Start Up Nation, Bahrain Victorious y Bora [EN VIVO] #EnVivo https://t.co/MAkvVZ8QxN
🎉 Tarea bonus
Taller #11: Twitter & NLP
Fecha de entrega: Mayo 20, 2021. (Antes del inicio de la próxima clase)