“트윗(tweet)”이란 말은 작은 새가 지저귀는 소리를 나타내는 영어 낱말로, 트위터(영어: Twitter)는 소셜 네트워크 서비스(SNS)이자 마이크로블로그 서비스로 볼 수 있다.
단문 메시지 서비스(SMS), 인스턴트 메신저, 전자 우편(e-mail) 등을 통해 “트윗(tweet)”를 전송할 수 있고, 글 한 편에 해당하는 단위는 트윗으로 140자가 한도가 된다. 한글이든 영문이든, 공백과 기호를 포함해 한 번에 140 까지 글자를 올릴 수 있다. 최근 Donald J. Trump 대통령이 트워터를 적극적으로 정치에 활용하면서 다시 관심을 받고 있는 서비스이기도 하다.
텍스트 문자 데이터를 R로 받아오기 위해서는 먼저 트위터 계정을 생성하고 핸드폰 번호를 등록하고 인증과정을 거쳐야 된다.
Settings
→ Mobile
로 들어가서 핸드폰 번호 인증을 받는다.
인증된 핸드폰 번호가 있어야 트위터 개발자 페이지에서 앱개발에 대한 키값을 받을 수 있다.
https://apps.twitter.com/ 웹페이지에 트위터 앱을 등록하면 트위터 API를 통해 다양한 데이터를 받을 수 있다.
트위터 계정을 생성하고, 핸드폰 인증을 마친 뒤에 트위터 개발자 페이지에서 TOOLS 메뉴를 찾아 Manage Your Apps로 들어간다. 이유는 트위터 데이터를 통해 부가적인 가치를 창출하는 응용프로그램을 개발해야 되기 때문이다.
Name
, Description
, Website
는 필수 값으로 기재를 하고, Website
는 정확한 주소 정보가 아니더라도 상관없다.응용프로그램이 생성되었으면 다음으로 남은 단계는 고객 키(Consumer Key) 와 비밀번호(Consumer Secret) 와 더불어 접속 토큰(Access Token) 과 접속 토큰 비밀번호(Access Secret) 를 확인한다. 만약 의심스러운 경우 지체없이 Regenerate
버튼을 눌러 재생성한다.
twitteR
, rtweet
팩키지twitteR
오랜기간동안 트위터가 서비스 되었고, R을 활용한 데이터 분석이 인기를 끌어 쉽게 텍스트 문자정보를 긁어와서 분석을 수월하게 진행할 수 있다. twitteR
과 ROAuth
팩키지를 설치하고 트위터 개발자 페이지, 앱 개발 페이지에서 수집한 고객키값과 접속토큰값을 twitterOAuth.R
파일에 저장한다.
그리고, source
명령어로 파일을 불러와서 메모리에 올리고 setup_twitter_oauth
명령어를 통해 트위터 인증을 한다.
searchTwitter
명령어로 검색어를 넣고 @HQ_sohn 넣고, 한글로 언어를 설정하고, lang='ko'
, 긁어올 트윗 갯수를 n=100
으로 지정한다. 긁어온 데이터는 리스트 정보라 이를 twListToDF
명령어를 통해 데이터프레임으로 변환한다.
head(hq_tweets_df$text)
명령어를 통해 트위터를 잘 긁어왔는지 확인한다.
library(twitteR)
library(ROAuth)
source("twitterOAuth.R")
# twitterOAuth.R 파일에 담겨있는 정보
#
# consumer_key <- "..............."
# consumer_secret <- "..............."
# access_token <- "..............."
# access_secret <- "..............."
setup_twitter_oauth(consumer_key, consumer_secret, access_token, access_secret)
hq_tweets <- searchTwitter("@HQ_sohn", lang='ko', n=100)
hq_tweets_df <- twListToDF(hq_tweets)
head(hq_tweets_df$text)
rtweet
팩키지rtweet
팩키지를 설치하고 나서, 토큰을 설정하여 트위터 API를 사용하는데 인증을 받아야 한다. 이를 위해서 Obtaining and using access tokens, rtweet: Collecting Twitter Data을 참조하여 설정한다.
create_token()
함수의 app
, consumer_key
, consumer_secret
인자를 설정한다. 그리고 토큰을 로컬 파일로 저장하여 다음번에 노출없이 사용한다.
# 0. 환경설정 -----
library(botrnot) # devtools::install_github("mkearney/botrnot")
library(rtweet) # devtools::install_github("mkearney/rtweet")
library(tidyverse)
library(extrafont)
loadfonts()
library(rtweet)
library(lubridate)
# 0.1. 토큰 설정 -----
appname <- "the_xwMOOC"
consumer_key <- "fEExxxxxxxxxxxxxxxxxx"
consumer_secret <- "7iBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
twitter_token <- create_token(
app = appname,
consumer_key = consumer_key,
consumer_secret = consumer_secret)
# 0.2. 토큰 저장 -----
file_name <- file.path('C:/seoul', "twitter_token.rds")
twitter_token %>% saveRDS(file = file_name)
트위터가 페이스북에 밀려 최근에는 대중적이지 않지만, 그래도 트럼프의 힘으로 뉴스에 노출빈도가 높아지고 있으며 꾸준히 SNS의 주된 용도로 사용하는 정치인도 많다. 현재까지 서울시장 경선에 선언을 했거나 출마가 예정된 정치인에 대한 트위터 분석을 수행해보자.
트위터에서 중요하게 생각하는 지표는 다음과 같다. 트위터 상단에 Tweets, Following, Followers, Likes… 순으로 배치되어 있다.
# 1. 데이터 가져오기 -----
candid_name_df <- tribble(
~이름, ~screen_name,
"안철수", "cheolsoo0919",
"박원순", "wonsoonpark",
"우상호", "woosangho2",
"박영선", "Park_Youngsun",
"김문수", "kimmoonsoo1"
)
candid_v <- c("wonsoonpark", "cheolsoo0919", "woosangho2", "Park_Youngsun", "kimmoonsoo1")
candid_tl_df <- get_timelines(candid_v, n = 100)
# 2. 탐색적 데이터 분석 -----
## 2.1. 서울시장 후보자 현황 -----
candid_user_df <- lookup_users(candid_v)
candid_info_df <- candid_user_df %>%
select(name, followers_count, friends_count, statuses_count, favourites_count, screen_name) %>%
gather(type, value, -name, -screen_name)
### 시각화
ggplot(data = candid_info_df,
aes(x = reorder(name, value), y = value,fill = type, colour = type)) +
geom_col() +
facet_wrap(~type, scales = "free") +
theme_minimal(base_family = "NanumGothic") +
theme(
legend.position = "none",
strip.background = element_blank(),
strip.text = element_text(size = 15, face="bold", colour = "black"),
title = element_blank(),
axis.text.x = element_blank()
) +
coord_flip() +
geom_text(aes(y = value, label = scales::comma(value)), colour = "black", hjust = "inward")
트윗을 보내는 방법을 분석하면 각 후보마다 트위터를 활용하는 방법/기계에 대한 내용도 파악이 가능하다.
candid_dev_df <- get_timelines(candid_v, n = 1000)
candid_dev_df <- left_join(candid_dev_df, candid_name_df)
candid_dev_df %>%
count(이름, source) %>%
ggplot(aes(x = reorder(source, n), y = n)) +
geom_col(fill = "#00B6B4") +
theme_minimal() +
theme(
plot.title = element_text(size=20, face="bold"),
strip.background = element_blank(),
strip.text = element_text(size = 15, face="bold", colour = "black"),
axis.text.x = element_blank()
) +
labs(
x = NULL,
y = NULL,
title = "트윗을 날리는 방법/장치"
) +
coord_flip() +
geom_text(aes(y = n, label = n), hjust = "inward") +
facet_wrap(~이름)
트위터의 인기도를 측정하는 방법중의 하나가 리트윗횟수(retweet)와 좋아요(favourite) 갯수로 추정하는 것이다.
candid_like_df <- left_join(candid_dev_df, candid_name_df)
candid_like_df %>%
group_by(이름) %>%
summarise(리트윗_합계 = sum(retweet_count), 좋아요_합계 = sum(favorite_count),
리트윗_평균 = mean(retweet_count), 좋아요_평균 = mean(favorite_count)) %>%
gather(type, value, -이름) %>%
ggplot(aes(x = reorder(이름, value), y = value, fill = type)) +
geom_col() +
labs(
x = NULL,
y = NULL,
title= "리트윗/좋아요 합계와 평균",
subtitle="리트윗(Retweet), 좋아요(Favourite)"
) +
coord_flip() +
facet_wrap(~type, scales = "free") +
theme_minimal() +
theme(
legend.position = "none",
plot.title = element_text(size=20, face="bold"),
strip.background = element_blank(),
strip.text = element_text(size = 15, face="bold", colour = "black")
) +
scale_y_continuous(labels = scales::comma)
주요 서울시장 후보 트윗 좋아요 추세를 보면, 박원순 서울시장 “2017-12-13” 방탄소년단 트윗에 대한 효과가 눈에 띄네요.
방탄소년단이 부른 서울 홍보송은 역시 대단했습니다. 그 유명한 빌보드에도 소개됐다고 하네요. 그래서 오늘은 여러분들께 뮤직비디오를 최초 공개합니다.
— 박원순 (@wonsoonpark) December 13, 2017
영상이 궁금하신 분들은 서울시 관광청 유튜브 계정(https://t.co/QQaMqNrDHG)에서 보실 수 있답니다. #BTS #방탄소년단 #WithSeoul pic.twitter.com/Imt75h5L4a
candid_trend_df <- candid_dev_df %>%
mutate(year_month = rollback(created_at, roll_to_first = TRUE, preserve_hms = FALSE)) %>%
group_by(name, year_month) %>%
summarise(fav_mean = mean(favorite_count), rt_mean = mean(retweet_count))
candid_trend_df %>%
select(name, year_month, fav_mean, rt_mean) %>%
gather(type, value, -name, -year_month) %>%
ggplot(aes(x = year_month, y = value, colour = name)) +
geom_line() +
facet_wrap(~type, scales = "free", nrow = 2) +
labs(
x = NULL,
y = NULL,
title = "주요 서울시장 후보 트윗 좋아요 추세"
) +
theme_minimal() +
facet_wrap(~name, scales="free") +
theme(
legend.position = "none",
plot.title = element_text(size=20, face="bold"),
strip.background = element_blank(),
strip.text = element_text(size = 15, face="bold", colour = "black")
) +
scale_x_datetime(date_labels = "%y-%m") +
scale_y_continuous(labels = scales::comma)