Automaty rządzą naszym życiem. Czy tego chcemy czy nie. Szczególnie w sieciach społecznościowych, nawet podobno wygrały wybory prezydenckie w USA (ciekawe czy w Rosji też). Spróbujmy zatem samodzielnie napisać jakiś automat działający w social mediach. W R, chociaż można w czymkolwiek innym.
Przygotujemy automat (bota), który będzie na Twitterze publikował wybrane przez nas treści. Taki bot już istnieje – to @rstatspl. W tym wpisie znajdziecie informacje jak powstał.
Bot @rstatspl robi trzy rzeczy:
- Repostuje twitty z tagu #rstats – te, które są po polsku oraz te napisane przez konta z ustawionym językiem polskim. To dwie różne sprawy, bo jak się okazało w trakcie prac Twitter sam rozpoznaje (mniej lub bardziej skutecznie) język w jakim napisany jest dany twitt.
- Repostuje posty z fanpage Dane i analizy – ot, taki forward manager :)
- Wita nowych obserwujących i odwdzięcza się; takie “follow za follow”
Aby cokolwiek zrobić automatycznie na Twitterze potrzebujemy aplikacji korzystającej z API. Jak przygotować aplikację? Szczegółowe informacje znajdziecie na stronach Twittera dla developerów. Ja zrobiłem tak:
- utworzyłem nowe konto @rstatspl
- będąc zalogowanym na tym koncie utworzyłem aplikację korzystając z dedykowanej ku temu strony
- po utworzeniu aplikacji potrzebujemy dwóch numerków: Consumer Key (API Key) oraz Consumer Secret (API Secret)
Do języka R mamy oczywiście gotową bibliotekę – rtweet, z której wykorzystamy kilka funkcji:
- do pobierania twittów – search_tweets()
- do wysyłania twittów – post_tweet()
- do pobierania informacji o użytkownikach – lookup_users()
W pierwszej kolejności jednak potrzebujemy tokena, którym nasz skrypt przedstawi się API Twittera. Proces szczegółowo opisany jest na stronie biblioteki, a pokrótce chodzi o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
library(tidyverse) library(rtweet) # dane z kreatora aplikacji appname <- "xxx" # nazwa naszej aplikacji key <- "aaa" # Consumer Key (API Key) secret <- "bbb" # Consumer Secret (API Secret) # tworzymy token w zmiennej "twitter_token" twitter_token <- create_token( app = appname, consumer_key = key, consumer_secret = secret) # zapisujemy token na później, żeby nie tworzyć go za każdym razem save(twitter_token, file = "twitter_token.rdata") |
Powyższy kod wystarczy uruchomić tylko raz, bo później tak przygotowany token wystarczy przypisać do zmiennej środowiskowej, z której korzysta biblioteka:
1 |
Sys.setenv(TWITTER_PAT="/home/lemur/RProjects/rstartpl/twitter_token.rdata") # oczywiście podajemy własną ścieżkę |
Teraz możemy już korzystać z biblioteki i naszej twitterowej aplikacji. Na przykład pobrać 100 najnowszych twittów z tagu #rstats, bez re-twittów:
1 |
rstat_tweets <- search_tweets("#rstats", type = "recent", n = 1000, include_rts = FALSE, retryonratelimit = TRUE) |
Jakie dane otrzymujemy?
1 |
glimpse(rstat_tweets) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
## Observations: 955 ## Variables: 68 ## $ status_id <chr> "976377457052876800", "976375990866739... ## $ created_at <dttm> 2018-03-21 08:38:20, 2018-03-21 08:32... ## $ user_id <chr> "220099608", "25872456", "750892662224... ## $ screen_name <chr> "RMHoge", "drewvid", "oaggimenez", "ma... ## $ text <chr> "Wonders of the #rstats community: I h... ## $ source <chr> "Twitter Lite", "Paper.li", "Twitter W... ## $ display_text_width <dbl> 241, 90, 221, 84, 153, 85, 136, 134, 2... ## $ reply_to_status_id <chr> NA, NA, NA, NA, "976368001468448768", ... ## $ reply_to_user_id <chr> NA, NA, NA, NA, "888164329677365250", ... ## $ reply_to_screen_name <chr> NA, NA, NA, NA, "martinusrihhi", NA, "... ## $ is_quote <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FAL... ## $ is_retweet <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FAL... ## $ favorite_count <int> 0, 0, 0, 1, 1, 0, 1, 0, 1, 3, 0, 1, 1,... ## $ retweet_count <int> 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,... ## $ hashtags <list> ["rstats", <"internationaldayofhappin... ## $ symbols <list> [NA, NA, NA, NA, NA, NA, NA, NA, NA, ... ## $ urls_url <list> ["stackoverflow.com/questions/2351…",... ## $ urls_t.co <list> ["https://t.co/IdrgfZm44j", "https://... ## $ urls_expanded_url <list> ["https://stackoverflow.com/questions... ## $ media_url <list> [NA, NA, "http://pbs.twimg.com/media/... ## $ media_t.co <list> [NA, NA, "https://t.co/7ADdwkyyAu", N... ## $ media_expanded_url <list> [NA, NA, "https://twitter.com/oaggime... ## $ media_type <list> [NA, NA, "photo", NA, NA, NA, NA, NA,... ## $ ext_media_url <list> [NA, NA, "http://pbs.twimg.com/media/... ## $ ext_media_t.co <list> [NA, NA, "https://t.co/7ADdwkyyAu", N... ## $ ext_media_expanded_url <list> [NA, NA, "https://twitter.com/oaggime... ## $ ext_media_type <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ mentions_user_id <list> [NA, NA, "854348082342973440", NA, <"... ## $ mentions_screen_name <list> [NA, NA, "CNRSenLR", NA, <"martinusri... ## $ lang <chr> "en", "en", "en", "en", "en", "en", "e... ## $ quoted_status_id <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_text <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_created_at <dttm> NA, NA, NA, NA, NA, NA, NA, NA, NA, N... ## $ quoted_source <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_favorite_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_retweet_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_user_id <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_screen_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_followers_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_friends_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_statuses_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_location <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_description <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ quoted_verified <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_status_id <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_text <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_created_at <dttm> NA, NA, NA, NA, NA, NA, NA, NA, NA, N... ## $ retweet_source <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_favorite_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_user_id <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_screen_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_followers_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_friends_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_statuses_count <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_location <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_description <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ retweet_verified <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ place_url <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ place_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ place_full_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ place_type <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ country <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ country_code <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA... ## $ geo_coords <list> [<NA, NA>, <NA, NA>, <NA, NA>, <NA, N... ## $ coords_coords <list> [<NA, NA>, <NA, NA>, <NA, NA>, <NA, N... ## $ bbox_coords <list> [<NA, NA, NA, NA, NA, NA, NA, NA>, <N... |
Mamy bardzo dużo ciekawostek, z których coś można wybierać: ID twittu, nazwa i ID użytkownika, który twitt opublikował, czas publikacji, sama treść, wszelakie wymienione linki czy tagi, położenie geograficzne z którego opublikowany został twitt (bardzo rzadko wypełnione, nie nakręcajcie się) i wiele innych.
W przypadku naszego bota interesuje nas język opublikowanego twitta – wybierzmy te, które są po polsku (według Twittera). Do opublikowania retwitta potrzebujemy ID oryginalnego twitta oraz nazwy użytkownika, który twitta opublikował. Zatem:
1 2 3 |
rstat_tweets %>% filter(lang == "pl") %>% select(status_id, screen_name, text) |
status_id | screen_name | text |
---|---|---|
976322838998241281 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/4zstibrNJW |
976232262076334080 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/MRV29j4UcC |
976141643983327233 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/vTWu76Z531 |
976051031078416384 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/fU8ofzWZce |
975960423282376704 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/aib1UhETOW |
975869832280371200 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/MSZRWCxGgS |
975779242993770496 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/CNRKKJ0u54 |
975688644307628032 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/xDd2qvibvx |
975598041670586368 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/jvUokwc3DL |
975507448890101760 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/iTJ93yfH03 |
975416866037534720 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/XLmhPFdjxj |
975326266608975872 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/qoqlnEKLhw |
975235666161340416 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/ogOv94ol6O |
975145081043812352 | dziennikarz | Najbardziej angażujący tweet o #rstats w ciągu ostatnich 6h. https://t.co/GiBxJiZAxA |
Mamy listę, którą możemy przepisać na nasze konto. Bot będzie taką listę pobierał co jakiś czas, więc interesują nas tylko te twitty, których jeszcze nie przesłaliśmy dalej. Musimy sobie więc zapamiętywać co już poszło i tego po prostu nie przekazywać – będziemy to zapamiętywać w pliczku, który sobie teraz wczytamy:
1 2 |
# weź ostatni last_rstats_tweet_id last_rstats_tweet_id <- readRDS("saved_data/last_rstats_tweet_id.RDS") |
Początkowo zmienna last_rstats_tweet_id może być pusta (możemy jej przypisać zero), po pierwszym retwicie się ustawi odpowiednio.
Bot ma przekazywać twitty po polsku oraz od polskich kont. Potrzebujemy więc wybrać polskie konta, które coś opublikowały (z listy pobranych twittów):
1 2 3 4 5 6 7 8 |
# lista unikalnych userów, którzy twitnęli tweet_users <- rstat_tweets %>% distinct(screen_name) %>% pull(screen_name) # pobieramy info o tych userach tweet_users <- lookup_users(tweet_users) # bierzemy tylko polskich tweet_users_pl <- tweet_users %>% filter(account_lang == "pl") %>% pull(screen_name) |
Teraz z puli pobranych twittów wybieramy te, które spełniają nasze ograniczenia:
1 2 3 4 5 6 7 8 9 10 11 |
tweets_to_rt <- rstat_tweets %>% # bez swoich własnych twittów oczywiscie! filter(screen_name != "rstatspl") %>% # te które po polsku lub są od polskich userow filter(lang == "pl" | screen_name %in% tweet_users_pl) %>% select(status_id, screen_name, lang) %>% # wybierz tylko te o ID którego nie było filter(!status_id %in% last_rstats_tweet_id) %>% # zbuduj URLa mutate(url = paste0(glue("https://twitter.com/{screen_name}/status/{status_id}"))) %>% arrange(status_id) |
Dostajemy kilka twittów:
które w pętli możemy opublikować u siebie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# czy jest coś nowego? if(nrow(tweets_to_rt) != 0) { # tweetnij wszystkie po kolei! for(i in 1:nrow(tweets_to_rt)) { # url do twitta twit_url <- as.character(tweets_to_rt[i, "url"]) # zapamiętujemy, że to najnowszy last_rstats_tweet_id <- c(last_rstats_tweet_id, as.character(tweets_to_rt[i, "status_id"])) # "nasz" twitt: post_tweet(status = twit_url) } } # zapisz last_rstats_tweet_id do bazy opublikowanych twittów saveRDS(last_rstats_tweet_id, file = "saved_data/last_rstats_tweet_id.RDS") |
Twitty jakie opublikujemy to kolejno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
## [1] "https://twitter.com/dziennikarz/status/975145081043812352" ## [1] "https://twitter.com/dziennikarz/status/975235666161340416" ## [1] "https://twitter.com/dziennikarz/status/975326266608975872" ## [1] "https://twitter.com/dziennikarz/status/975416866037534720" ## [1] "https://twitter.com/dziennikarz/status/975507448890101760" ## [1] "https://twitter.com/dziennikarz/status/975598041670586368" ## [1] "https://twitter.com/dziennikarz/status/975688644307628032" ## [1] "https://twitter.com/whyRconf/status/975770064430526464" ## [1] "https://twitter.com/dziennikarz/status/975779242993770496" ## [1] "https://twitter.com/olga_mie/status/975842124892721154" ## [1] "https://twitter.com/whyRconf/status/975848771308478465" ## [1] "https://twitter.com/dziennikarz/status/975869832280371200" ## [1] "https://twitter.com/dziennikarz/status/975960423282376704" ## [1] "https://twitter.com/dziennikarz/status/976051031078416384" ## [1] "https://twitter.com/olga_mie/status/976070741115498497" ## [1] "https://twitter.com/dziennikarz/status/976141643983327233" ## [1] "https://twitter.com/kosinski_rblog/status/976213656575922177" ## [1] "https://twitter.com/dziennikarz/status/976232262076334080" ## [1] "https://twitter.com/dziennikarz/status/976322838998241281" |
Pierwsze zadanie wykonane – bot pobiera najnowsze twitty z tagiem #rstats i publikuje linki do tych, które Twitter uznał za napisane po polsku lub pochodzą z kont, które mają ustawiony język polski.
Drugim zadaniem jest przepublikowanie na Twitterze postów z fanpage’a Dane i analizy. Do pobrania postów z fanpage’a wykorzystamy bibliotekę Rfacebook, która pobiera dane przez API Facebooka.
Podobnie jak poprzednio tworzymy aplikację facebookową, a której potrzebujemy klucza (zmienna fb_app_id niżej) oraz sekretnego kodu (zmienna fb_app_secret). Podobnie potrzebujemy utworzyć token, który zapiszemy sobie na później:
1 2 3 4 5 6 7 8 9 10 |
library(Rfacebook) library(lubridate) # numery z aplikacji FB fb_app_id = "xxxx" fb_app_secret = "yyyy" # tworzymy token aplikacji i zapisujemy do lokalnego pliku fb_oauth <- fbOAuth(app_id = fb_app_id, app_secret = fb_app_secret) save(fb_oauth, file="fb_token.RData") |
Powyższy kod wystarczy uruchomić tylko raz.
Na początek przygotujemy funkcję, która pobierze nam najnowsze posty z fanpage’a:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# wczytujemy zapisany token load("/home/lemur/RProjects/rstatpl/fb_oauth.rda") # lista fanpage'y z których pobieramy posty fanpages <- c("DaneAnalizy") # funkcja pobierająca najnowsze posty z fanpage'a getFPPosts <- function(page_name, nposts=50) { fb_page <- getPage(page = page_name, token = fb_oauth, n=nposts) # tylko potrzebne informacje fb_page <- fb_page %>% select(id, created_time, message, likes_count, comments_count) %>% mutate(created_time = ymd_hms(created_time)) return(fb_page) } |
Teraz dla każdego fanpage’a pobierzemy po jednym najnowszym poście, sprawdzamy czy już był opublikowany (po jego ID)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# już przebublikowane posty # na początku może być zero repost_arch <- readRDS("saved_data/fbpost_arch.RDS") for(i in 1:length(fanpages)) { # kolejny fanpage fbpost_pagename <- fanpages[i] # pobieramy najnowszy post fb_posts <- getFPPosts(fbpost_pagename, 1) # ID postu fbpost_id <- as.character(fb_posts[1, "id"]) # czy ten post już był? if(repost_arch %>% filter(post_id == fbpost_id) %>% nrow() == 0) { # zapamiętujemy, ze był repost_arch <- bind_rows(repost_arch, tibble(pagename = fbpost_pagename, post_id = fbpost_id)) # przygotowanie tweeta fbpost_text <- gsub("\n\n", "\n", as.character(fb_posts[1, "message"]), fixed = TRUE) # na Twitter go! :) post_tweet(status = glue("{fbpost_text}\n\nWięcej na FB/{fbpost_pagename}: http://fb.com/{fbpost_id}")) } } |
W efekcie opublikujemy:
1 2 3 |
Zainteresowani? Więcej na FB/DaneAnalizy: http://fb.com/1775448726078953_1872200053070486 |
Na koniec zapisujemy listę opublikowanych postów:
1 2 |
# zapisujemy historie postow, ktore byly saveRDS(repost_arch, "saved_data/fbpost_arch.RDS") |
Ostatnie zadanie to follow za follow i podziękowanie za obserwowanie. Algorytm jest podobny:
- pobieramy listę obserwujących
- porównujemy ją z poprzednim (na przykład sprzed godziny) przebiegiem
- jeśli jest ktoś nowy to zaczynamy go obserwować i jednocześnie piszemy, że miło go widzieć
Gotowy kod (cały skrypt):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
library(tidyverse) library(glue) library(rtweet) # token Sys.setenv(TWITTER_PAT="/home/lemur/RProjects/rstatpl/twitter_token.rdata") # pobierz listę obserwowanych rstatspl_followers <- get_followers("rstatspl", n = 5000) # max 5000, przy bardziej popularnych botach trzeba to zmienić # wczytaj z bazy poprzednia listę rstatspl_followers_old <- readRDS("saved_data/rstatspl_followers_old.RDS") # sprawdź kto jest nowy rstatspl_followers_new <- anti_join(rstatspl_followers, rstatspl_followers_old, by = "user_id") # zacznij ich obserwować if(nrow(rstatspl_followers_new) != 0) { for(i in 1:nrow(rstatspl_followers_new)) { user_id <- as.character(rstatspl_followers_new[i, "user_id"]) user_info <- lookup_users(user_id) user_name <- as.character(user_info$screen_name) # obserwuj konto post_follow(user_id) # twittnij, że super post_tweet(status = glue("@{user_name} witam i życzę miłego dnia! :)")) } } # zapisz listę obserwowanych saveRDS(rstatspl_followers, "saved_data/rstatspl_followers_old.RDS") |
Ostatnia rzecz to uruchomienie bota cyklicznie. Do tego przydaje się środowisko linuxowe i cron. Dodajemy do zadań cyklicznych trzy skrypty, chociaż można je połączyć w jedno. Ja przygotowałem trzy, które uruchamiają się w podobnych cyklach, aby nie zalewać konta w jednym momencie kilkoma twittami na raz. Crontab wygląda tak:
1 2 3 4 5 6 7 8 |
# retweet, co 10 minut */10 * * * * Rscript /home/lemur/RProjects/rstatpl/retweet_rstats.R # re-follow, co 15 minut */15 * * * * Rscript /home/lemur/RProjects/rstatpl/rstatspl_refollow.R # repost z fb - co godzinę, 3 minuty po pełnej godzinie 3 * * * * Rscript /home/lemur/RProjects/rstatpl/retweet_fb.R |
Co można jeszcze zrobić?
Możemy przygotować kilka list obserwowanych użytkowników Twittera i na ich podstawie coś robić. Bardzo fajne boty prowadzi @dziennikarz korzystając na przykład z własnej listy dziennikarzy. Co sześć godzin bot pobiera najnowsze twitty osób należących do listy i re-twittuje tego twita, który miał największe zaangażowanie (liczba like’ów i retwittów). Podobnie działają Najbardziej angażujący twitt o #dataviz #ddj oraz Najbardziej angażujący twitt o #rstats (który był inspiracją do całej tej zabawy).
Analogiczne narzędzia (ale za każdym razem zbierające dane przy uruchomieniu aplikacji) napisałem w Shiny:
- Sentyment w komentarzach pod postami na Facebooku – kod tego narzędzia znajdziecie na moim GitHubie
- Najpopularniejsze twitty i trendy z polskiego Twittera – kod w jakiejś wczesnej wersji również na GitHubie
Pierwsza z dwóch powyższych aplikacji robi prostą analizę tekstu, co może być ciekawym zajęciem dla bota. Wyobrażam sobie pobranie twittów dziennikarzy (korzystając z listy @dziennikarza), przygotowanie listy tematów (na przykład analiza LDA Latent Dirichlet allocation – zobacz mój wpis na ten temat) i napisanie coś na ten temat (@Warzecha dzisiaj pisze o…, @Gzyms@Gmyz o…, a @Lis ciągle o tym samym, czyli o…).
Inny pomysł to odpowiadanie na cudze twitty. Tutaj robi się już trudniej, bo trzeba przeanalizować o czym był twitt. Ewentualnie można to olać i zawsze wkurzać tekstami typu Smoleńsk, kurwa! czy też czymś w tym stylu (na przykład losowo) – to już bardziej dogadywanie… Łatwo w takim przypadku być zbanowanym (albo chociaż wyciszonym).
Tak czy inaczej to w tym wariancie jest największa zabawa i największe pole do popisu. Dlatego też takim powodzeniem cieszy się maszynowe przetwarzanie tekstu w ogłoszeniach rekrutacyjnych dla data scientists – wszyscy chcą pisać boty przyjmujące zamówienia z Facebooka (z Messengera konkretnie).
A teraz popatrzmy na to wszystko nieco inaczej, przy okazji afery z Facebookiem i Cambridge Analytica. Gdyby zamiast jednego bota przygotować ich wiele – kilkadziesiąt, kilkaset? Bot w sumie może być jeden, kont musi być dużo. Farma taka. Gdyby analizować treści pod określonym kontem i na przykład w odpowiedzi na twitty wychwalające rząd (jakikolwiek) wysyłać setki twittów z argumentami przeciw, pokazywaniem jakichś wpadek (vide Komorowski wizytujący Japonię czym grał PiS przed wyborami prezydenckimi), nawołujące do buntu itd itp. Jedna strona mogłaby zalać Twittera swoimi poglądami. Tak się rozprzestrzenia fake news na masową skalę. I teraz od użytkowników zależy w co uwierzą.
Dlatego warto być krytycznym, warto myśleć samodzielnie, oglądać obie strony medalu (czytaj: obie stacje telewizyjne). Dlatego nie warto przyjmować niczego za pewnik – to, że jedni głośno mówią, że rozliczają Żydów, komunistów i złodziejską kastę nie znaczy że jednocześnie nie robią podobnie przyznając sobie nagrody, zmieniając prawo i podporządkowując to czy owo siłom politycznym. Za Kazikiem Staszewskim: Żelazne prawo oligarchii: kto władzę ma najpierw o nią się martwi. Bądźcie czujni!
hejaaa
gratulacje wpisu! jestem początkująca w tej tematyce, a wszystko wydaje się jasne
spróbuję stworzyć swojego bota :-) dzięki!