Jupyter, Plotly를 사용한 시각화 프로그램
내용
여기 의 기사에 있는 BuzzFeed에 근무하고 있는 데이터 사이언티스트가 작성한 오픈 소스를 움직여, Jupyter notebook에서 Plotly에 의한 가시화 프로그램을 움직여 봅니다.
환경
Os:macOS Sierra
파이썬 : 파이썬 3.6.1
Jupyter:4.3.0
R:3.4.2
Spark-apache:2.2.0
간단한 프로그램 설명
① Facebook에서 4개의 뉴스 사이트(CNN, NYTimes, BuzzFeed, Upworthy)의 타이틀로부터 Word2Vec 알고리즘을 이용하여 clickbait의 가능성이 있는 뉴스의 타이틀을 분석한다. 분석 결과를 Jupyter에서 Plotly를 사용하여 시각화를 수행한다.
clickbait (클릭 베이트) ··· 일부러 선정적인 표제나 자극적인 썸네일 이미지를 붙여 넷 유저의 클릭을 초대하는 웹 페이지나 링크나 동영상이나 광고등의 일
* 이번에 사용하는 Facebook 뉴스의 타이틀 데이터는 GitHub 에 공개된 데이터를 그대로 사용하고 있습니다.
Word2Vec ... 단어의 의미와 문법을 포착하기 위해 단어를 벡터 표현하고 문장을 분류하는 알고리즘
*자세한 것은 참조원 의 기사를 읽어 부탁드립니다.
실제로 시각화한 결과
녹색으로 표시된 BuzzFeed 뉴스 플롯의 덩어리에 몇 가지 다른 뉴스 사이트의 제목이 혼잡합니다. (예: Which Olympic Sport Should You Play?) 예상대로 should(~해야 한다)라고 말한 단어가 포함된 타이틀은 클릭 베이트의 가능성이 있다고 볼 수 있습니다.
환경 구축
환경 구축에 필요한 것은 다음과 같습니다.
* 그 밖에 별도로 필요한 것이 발생했을 경우는 그 때마다 인스톨을 부탁합니다.
Jupyter notebook
여기 을 참고하여 설치했습니다.
Plotly
Plotly를 설치하고 Jupyter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
R
R을 설치하고 Jupyter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
Spark-apache
Spark-apache를 설치하고 Jupiter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
프로그램 실행
GitHub 더 필요한 파일을 다운로드합니다.
먼저 Jupyter를 시작하고 프로그램 "fb_news_53D_spark.ipynb"를 실행합니다.
fb_news_53D_spark.ipynbspark_path = "/usr/local/Cellar/apache-spark/2.2.0/libexec/"
# Easiest way to get Spark to work with Jupyter: https://github.com/minrk/findspark
#import findspark
#findspark.init(spark_path)
#import pyspark
#from pyspark.sql import SparkSession
#sc = pyspark.SparkContext(appName='fb_headlines')
#spark = SparkSession(sc)
#config = sc._conf.getAll()
#print ('Web URL: ' + filter(lambda x: 'spark.driver.host' in x[0], config)[0][1] + ':4040')
from pyspark.sql.functions import regexp_replace
from pyspark.sql import Column
from pyspark.sql.types import *
def process_df(df):
return (df
.withColumn('text',regexp_replace('link_name', '\'', ''))
.filter("text != ''")
.filter("text != 'Timeline Photos'")
)
def read_tsv(path):
# predefine data frame schema: faster
schema = StructType([
StructField("page_id", StringType(), True),
StructField("status_id", StringType(), True),
StructField("link_name", StringType(), True),
StructField("status_published", TimestampType(), True),
StructField("num_reactions", IntegerType(), True)])
return spark.read.csv(path ,schema = schema, header=True, inferSchema=True, sep="\t")
df_cnn = read_tsv("/fb_headlines/CNN_fb.tsv")
df_nytimes = read_tsv("/fb_headlines/NYTimes_fb.tsv")
df_buzzfeed = read_tsv("/BuzzFeed_fb.tsv")
df_upworthy = read_tsv("/fb_headlines/Upworthy_fb.tsv")
df = df_cnn.union(df_nytimes).union(df_buzzfeed).union(df_upworthy)
df = process_df(df).cache()
df.select('link_name', 'status_published', 'num_reactions').show()
print ( df.count() )
df.printSchema()
from pyspark.ml.feature import Tokenizer, RegexTokenizer
tokenizer = RegexTokenizer(pattern="[^\w]",inputCol="text", outputCol="words")
df = tokenizer.transform(df)
df.select('text','words').show()
from pyspark.ml.feature import Word2Vec
word2Vec = Word2Vec(vectorSize=50, seed=42, inputCol="words", outputCol="vectors")
model = word2Vec.fit(df)
df = model.transform(df)
df.select('words', 'vectors').show()
model.findSynonyms("olympics", 20).show()
model.findSynonyms("election", 20).show()
from pyspark.ml.feature import StringIndexer, OneHotEncoder
stringIndexer = StringIndexer(inputCol="page_id", outputCol="indexed")
model = stringIndexer.fit(df)
df = model.transform(df)
encoder = OneHotEncoder(inputCol="indexed", outputCol="page_ohe")
df = encoder.transform(df)
df.select('page_id', 'page_ohe').show()
from pyspark.ml.feature import VectorAssembler
model = VectorAssembler(inputCols=['page_ohe', 'vectors'], outputCol="merged_vectors")
df = model.transform(df)
df.select('merged_vectors').show()
df2 = df.filter(df.status_published > '2016-06-01 00:00:00').cache()
print ( df2.count() )
df2.printSchema()
import pandas as pd
(df2.select('page_id', 'status_id', 'link_name', 'status_published', 'num_reactions', 'merged_vectors')
.toPandas()
.to_csv('/clickbait-cluster-master/df_transform_53D.csv', index=False, encoding="utf-8")
)
Facebook에서 가져온 뉴스 제목의 데이터는 Github에 게시된 데이터를 그대로 사용합니다.
프로그램 실행 후 결과 CSV 파일이 작성되었다고 생각합니다. 이 데이터는 뉴스 제목에 포함된 각 단어의 단어 벡터를 Word2vec 알고리즘으로 50차원 벡터로 변환한 것입니다.
다음으로 Jupyter에서 프로그램 "fb_news_53D_plotly.ipynb"를 실행합니다.
* 이번에는 9000건의 CSV 데이터가 출력되고 있다고 생각합니다만, 제 실행 환경에서는 CPU의 메모리가 적게 실행할 수 없었기 때문에, 절반의 5000건의 데이터분의 CSV 데이터를 작성해, 실행해 있습니다.
fb_news_53D_plotly.ipynboptions(warn=1)
source("/clickbait-cluster-master/Rstart.R")
library(htmlwidgets)
library(tidyr)
library(tsne)
#library(crosstalk) # Does not work unfortunately
library(plotly)
sessionInfo()
df <- read_csv('/clickbait-cluster-master/df_transform_53D.csv')
df %>% head() %>% print()
vector_names = paste0('w2v_', 1:53)
vector_trim <- function(vector)
substr(vector, 2, nchar(vector)-1)
vector_names %>% head() %>% print()
vector_trim(df$merged_vectors[1])
df$merged_vectors = lapply(df$merged_vectors, vector_trim)
df <- separate(data = df, col = merged_vectors, into = vector_names, convert=T, sep = ",")
df %>% select(w2v_1:w2v_4) %>% head() %>% print()
matrix <- df %>% select(w2v_1:w2v_53) %>% as.matrix()
system.time( cluster_coords <- tsne(matrix, initial_dims=53, perplexity=50, epoch=50) )
cluster_coords %>% head() %>% print()
df_transform = df %>% select(page_id, status_id, link_name, status_published, num_reactions) %>%
mutate(x = cluster_coords[,1], y= cluster_coords[,2])
df_transform %>% select(status_id, x, y) %>% head() %>% print()
write.csv(df_transform, "/clickbait-cluster-master/df_transform_53D.csv", row.names=F)
df_plot <- read_csv("/clickbait-cluster-master/df_transform_53D.csv")
df_plot %>% select(link_name, x, y) %>% mutate(link_name = substr(link_name,1,20)) %>% head() %>% print()
plot <- ggplot(df_plot, aes(x=x, y=y, color=page_id)) +
geom_point(alpha=0.75, stroke=0) +
theme_bw()
ggsave("/clickbait-cluster-master/fb-headlines-cluster-test-53D.png", plot, width=4, height=3, dpi=300)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=3),
text=~link_name)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-test-53D.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
processText <- function(row) {
sprintf("%s<br>%s Reactions<br>%s",
row[3],
format(as.numeric(row[5]), big.mark=","),
format(as.Date(substr(row[4], 1, 10) ), format = "%B %d, %Y" ))
}
apply(df_plot[1,], 1, processText)
df_plot$text = apply(df_plot, 1, processText)
# https://plot.ly/r/axes/
ax <- list(
title = "",
zeroline = FALSE,
showline = FALSE,
showticklabels = FALSE,
showgrid = FALSE
)
m = list(
l = 0,
r = 0,
b = 0,
t = 25,
pad = 0
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax, yaxis = ax, margin=m)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-standalone.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
font <- list(
family='Source Sans Pro, Arial, sans-serif'
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax,
yaxis = ax,
margin=m,
font=font,
plot_bgcolor ='#f7f8fa',
paper_bgcolor='#f7f8fa')
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-web.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
* 참고자료는 plotly의 출력 데이터를 createWidget, saveWidget을 사용하여 html 파일로 출력하고 있습니다. 하고 있습니다.
시각화 데이터를 살펴보기
위에서 출력된 html 파일 "fb-headlines-cluster-test-53D.html"을 열면, plotly에 의한 데이터 시각화가 행해지고 있다고 생각합니다.
Reference
이 문제에 관하여(Jupyter, Plotly를 사용한 시각화 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pentax0317/items/378f1130a606e735fe66
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Os:macOS Sierra
파이썬 : 파이썬 3.6.1
Jupyter:4.3.0
R:3.4.2
Spark-apache:2.2.0
간단한 프로그램 설명
① Facebook에서 4개의 뉴스 사이트(CNN, NYTimes, BuzzFeed, Upworthy)의 타이틀로부터 Word2Vec 알고리즘을 이용하여 clickbait의 가능성이 있는 뉴스의 타이틀을 분석한다. 분석 결과를 Jupyter에서 Plotly를 사용하여 시각화를 수행한다.
clickbait (클릭 베이트) ··· 일부러 선정적인 표제나 자극적인 썸네일 이미지를 붙여 넷 유저의 클릭을 초대하는 웹 페이지나 링크나 동영상이나 광고등의 일
* 이번에 사용하는 Facebook 뉴스의 타이틀 데이터는 GitHub 에 공개된 데이터를 그대로 사용하고 있습니다.
Word2Vec ... 단어의 의미와 문법을 포착하기 위해 단어를 벡터 표현하고 문장을 분류하는 알고리즘
*자세한 것은 참조원 의 기사를 읽어 부탁드립니다.
실제로 시각화한 결과
녹색으로 표시된 BuzzFeed 뉴스 플롯의 덩어리에 몇 가지 다른 뉴스 사이트의 제목이 혼잡합니다. (예: Which Olympic Sport Should You Play?) 예상대로 should(~해야 한다)라고 말한 단어가 포함된 타이틀은 클릭 베이트의 가능성이 있다고 볼 수 있습니다.
환경 구축
환경 구축에 필요한 것은 다음과 같습니다.
* 그 밖에 별도로 필요한 것이 발생했을 경우는 그 때마다 인스톨을 부탁합니다.
Jupyter notebook
여기 을 참고하여 설치했습니다.
Plotly
Plotly를 설치하고 Jupyter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
R
R을 설치하고 Jupyter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
Spark-apache
Spark-apache를 설치하고 Jupiter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
프로그램 실행
GitHub 더 필요한 파일을 다운로드합니다.
먼저 Jupyter를 시작하고 프로그램 "fb_news_53D_spark.ipynb"를 실행합니다.
fb_news_53D_spark.ipynbspark_path = "/usr/local/Cellar/apache-spark/2.2.0/libexec/"
# Easiest way to get Spark to work with Jupyter: https://github.com/minrk/findspark
#import findspark
#findspark.init(spark_path)
#import pyspark
#from pyspark.sql import SparkSession
#sc = pyspark.SparkContext(appName='fb_headlines')
#spark = SparkSession(sc)
#config = sc._conf.getAll()
#print ('Web URL: ' + filter(lambda x: 'spark.driver.host' in x[0], config)[0][1] + ':4040')
from pyspark.sql.functions import regexp_replace
from pyspark.sql import Column
from pyspark.sql.types import *
def process_df(df):
return (df
.withColumn('text',regexp_replace('link_name', '\'', ''))
.filter("text != ''")
.filter("text != 'Timeline Photos'")
)
def read_tsv(path):
# predefine data frame schema: faster
schema = StructType([
StructField("page_id", StringType(), True),
StructField("status_id", StringType(), True),
StructField("link_name", StringType(), True),
StructField("status_published", TimestampType(), True),
StructField("num_reactions", IntegerType(), True)])
return spark.read.csv(path ,schema = schema, header=True, inferSchema=True, sep="\t")
df_cnn = read_tsv("/fb_headlines/CNN_fb.tsv")
df_nytimes = read_tsv("/fb_headlines/NYTimes_fb.tsv")
df_buzzfeed = read_tsv("/BuzzFeed_fb.tsv")
df_upworthy = read_tsv("/fb_headlines/Upworthy_fb.tsv")
df = df_cnn.union(df_nytimes).union(df_buzzfeed).union(df_upworthy)
df = process_df(df).cache()
df.select('link_name', 'status_published', 'num_reactions').show()
print ( df.count() )
df.printSchema()
from pyspark.ml.feature import Tokenizer, RegexTokenizer
tokenizer = RegexTokenizer(pattern="[^\w]",inputCol="text", outputCol="words")
df = tokenizer.transform(df)
df.select('text','words').show()
from pyspark.ml.feature import Word2Vec
word2Vec = Word2Vec(vectorSize=50, seed=42, inputCol="words", outputCol="vectors")
model = word2Vec.fit(df)
df = model.transform(df)
df.select('words', 'vectors').show()
model.findSynonyms("olympics", 20).show()
model.findSynonyms("election", 20).show()
from pyspark.ml.feature import StringIndexer, OneHotEncoder
stringIndexer = StringIndexer(inputCol="page_id", outputCol="indexed")
model = stringIndexer.fit(df)
df = model.transform(df)
encoder = OneHotEncoder(inputCol="indexed", outputCol="page_ohe")
df = encoder.transform(df)
df.select('page_id', 'page_ohe').show()
from pyspark.ml.feature import VectorAssembler
model = VectorAssembler(inputCols=['page_ohe', 'vectors'], outputCol="merged_vectors")
df = model.transform(df)
df.select('merged_vectors').show()
df2 = df.filter(df.status_published > '2016-06-01 00:00:00').cache()
print ( df2.count() )
df2.printSchema()
import pandas as pd
(df2.select('page_id', 'status_id', 'link_name', 'status_published', 'num_reactions', 'merged_vectors')
.toPandas()
.to_csv('/clickbait-cluster-master/df_transform_53D.csv', index=False, encoding="utf-8")
)
Facebook에서 가져온 뉴스 제목의 데이터는 Github에 게시된 데이터를 그대로 사용합니다.
프로그램 실행 후 결과 CSV 파일이 작성되었다고 생각합니다. 이 데이터는 뉴스 제목에 포함된 각 단어의 단어 벡터를 Word2vec 알고리즘으로 50차원 벡터로 변환한 것입니다.
다음으로 Jupyter에서 프로그램 "fb_news_53D_plotly.ipynb"를 실행합니다.
* 이번에는 9000건의 CSV 데이터가 출력되고 있다고 생각합니다만, 제 실행 환경에서는 CPU의 메모리가 적게 실행할 수 없었기 때문에, 절반의 5000건의 데이터분의 CSV 데이터를 작성해, 실행해 있습니다.
fb_news_53D_plotly.ipynboptions(warn=1)
source("/clickbait-cluster-master/Rstart.R")
library(htmlwidgets)
library(tidyr)
library(tsne)
#library(crosstalk) # Does not work unfortunately
library(plotly)
sessionInfo()
df <- read_csv('/clickbait-cluster-master/df_transform_53D.csv')
df %>% head() %>% print()
vector_names = paste0('w2v_', 1:53)
vector_trim <- function(vector)
substr(vector, 2, nchar(vector)-1)
vector_names %>% head() %>% print()
vector_trim(df$merged_vectors[1])
df$merged_vectors = lapply(df$merged_vectors, vector_trim)
df <- separate(data = df, col = merged_vectors, into = vector_names, convert=T, sep = ",")
df %>% select(w2v_1:w2v_4) %>% head() %>% print()
matrix <- df %>% select(w2v_1:w2v_53) %>% as.matrix()
system.time( cluster_coords <- tsne(matrix, initial_dims=53, perplexity=50, epoch=50) )
cluster_coords %>% head() %>% print()
df_transform = df %>% select(page_id, status_id, link_name, status_published, num_reactions) %>%
mutate(x = cluster_coords[,1], y= cluster_coords[,2])
df_transform %>% select(status_id, x, y) %>% head() %>% print()
write.csv(df_transform, "/clickbait-cluster-master/df_transform_53D.csv", row.names=F)
df_plot <- read_csv("/clickbait-cluster-master/df_transform_53D.csv")
df_plot %>% select(link_name, x, y) %>% mutate(link_name = substr(link_name,1,20)) %>% head() %>% print()
plot <- ggplot(df_plot, aes(x=x, y=y, color=page_id)) +
geom_point(alpha=0.75, stroke=0) +
theme_bw()
ggsave("/clickbait-cluster-master/fb-headlines-cluster-test-53D.png", plot, width=4, height=3, dpi=300)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=3),
text=~link_name)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-test-53D.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
processText <- function(row) {
sprintf("%s<br>%s Reactions<br>%s",
row[3],
format(as.numeric(row[5]), big.mark=","),
format(as.Date(substr(row[4], 1, 10) ), format = "%B %d, %Y" ))
}
apply(df_plot[1,], 1, processText)
df_plot$text = apply(df_plot, 1, processText)
# https://plot.ly/r/axes/
ax <- list(
title = "",
zeroline = FALSE,
showline = FALSE,
showticklabels = FALSE,
showgrid = FALSE
)
m = list(
l = 0,
r = 0,
b = 0,
t = 25,
pad = 0
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax, yaxis = ax, margin=m)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-standalone.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
font <- list(
family='Source Sans Pro, Arial, sans-serif'
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax,
yaxis = ax,
margin=m,
font=font,
plot_bgcolor ='#f7f8fa',
paper_bgcolor='#f7f8fa')
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-web.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
* 참고자료는 plotly의 출력 데이터를 createWidget, saveWidget을 사용하여 html 파일로 출력하고 있습니다. 하고 있습니다.
시각화 데이터를 살펴보기
위에서 출력된 html 파일 "fb-headlines-cluster-test-53D.html"을 열면, plotly에 의한 데이터 시각화가 행해지고 있다고 생각합니다.
Reference
이 문제에 관하여(Jupyter, Plotly를 사용한 시각화 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pentax0317/items/378f1130a606e735fe66
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
녹색으로 표시된 BuzzFeed 뉴스 플롯의 덩어리에 몇 가지 다른 뉴스 사이트의 제목이 혼잡합니다. (예: Which Olympic Sport Should You Play?) 예상대로 should(~해야 한다)라고 말한 단어가 포함된 타이틀은 클릭 베이트의 가능성이 있다고 볼 수 있습니다.
환경 구축
환경 구축에 필요한 것은 다음과 같습니다.
* 그 밖에 별도로 필요한 것이 발생했을 경우는 그 때마다 인스톨을 부탁합니다.
Jupyter notebook
여기 을 참고하여 설치했습니다.
Plotly
Plotly를 설치하고 Jupyter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
R
R을 설치하고 Jupyter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
Spark-apache
Spark-apache를 설치하고 Jupiter notebook에서 실행할 수 있습니다.
여기 을 참고하여 설치했습니다.
프로그램 실행
GitHub 더 필요한 파일을 다운로드합니다.
먼저 Jupyter를 시작하고 프로그램 "fb_news_53D_spark.ipynb"를 실행합니다.
fb_news_53D_spark.ipynbspark_path = "/usr/local/Cellar/apache-spark/2.2.0/libexec/"
# Easiest way to get Spark to work with Jupyter: https://github.com/minrk/findspark
#import findspark
#findspark.init(spark_path)
#import pyspark
#from pyspark.sql import SparkSession
#sc = pyspark.SparkContext(appName='fb_headlines')
#spark = SparkSession(sc)
#config = sc._conf.getAll()
#print ('Web URL: ' + filter(lambda x: 'spark.driver.host' in x[0], config)[0][1] + ':4040')
from pyspark.sql.functions import regexp_replace
from pyspark.sql import Column
from pyspark.sql.types import *
def process_df(df):
return (df
.withColumn('text',regexp_replace('link_name', '\'', ''))
.filter("text != ''")
.filter("text != 'Timeline Photos'")
)
def read_tsv(path):
# predefine data frame schema: faster
schema = StructType([
StructField("page_id", StringType(), True),
StructField("status_id", StringType(), True),
StructField("link_name", StringType(), True),
StructField("status_published", TimestampType(), True),
StructField("num_reactions", IntegerType(), True)])
return spark.read.csv(path ,schema = schema, header=True, inferSchema=True, sep="\t")
df_cnn = read_tsv("/fb_headlines/CNN_fb.tsv")
df_nytimes = read_tsv("/fb_headlines/NYTimes_fb.tsv")
df_buzzfeed = read_tsv("/BuzzFeed_fb.tsv")
df_upworthy = read_tsv("/fb_headlines/Upworthy_fb.tsv")
df = df_cnn.union(df_nytimes).union(df_buzzfeed).union(df_upworthy)
df = process_df(df).cache()
df.select('link_name', 'status_published', 'num_reactions').show()
print ( df.count() )
df.printSchema()
from pyspark.ml.feature import Tokenizer, RegexTokenizer
tokenizer = RegexTokenizer(pattern="[^\w]",inputCol="text", outputCol="words")
df = tokenizer.transform(df)
df.select('text','words').show()
from pyspark.ml.feature import Word2Vec
word2Vec = Word2Vec(vectorSize=50, seed=42, inputCol="words", outputCol="vectors")
model = word2Vec.fit(df)
df = model.transform(df)
df.select('words', 'vectors').show()
model.findSynonyms("olympics", 20).show()
model.findSynonyms("election", 20).show()
from pyspark.ml.feature import StringIndexer, OneHotEncoder
stringIndexer = StringIndexer(inputCol="page_id", outputCol="indexed")
model = stringIndexer.fit(df)
df = model.transform(df)
encoder = OneHotEncoder(inputCol="indexed", outputCol="page_ohe")
df = encoder.transform(df)
df.select('page_id', 'page_ohe').show()
from pyspark.ml.feature import VectorAssembler
model = VectorAssembler(inputCols=['page_ohe', 'vectors'], outputCol="merged_vectors")
df = model.transform(df)
df.select('merged_vectors').show()
df2 = df.filter(df.status_published > '2016-06-01 00:00:00').cache()
print ( df2.count() )
df2.printSchema()
import pandas as pd
(df2.select('page_id', 'status_id', 'link_name', 'status_published', 'num_reactions', 'merged_vectors')
.toPandas()
.to_csv('/clickbait-cluster-master/df_transform_53D.csv', index=False, encoding="utf-8")
)
Facebook에서 가져온 뉴스 제목의 데이터는 Github에 게시된 데이터를 그대로 사용합니다.
프로그램 실행 후 결과 CSV 파일이 작성되었다고 생각합니다. 이 데이터는 뉴스 제목에 포함된 각 단어의 단어 벡터를 Word2vec 알고리즘으로 50차원 벡터로 변환한 것입니다.
다음으로 Jupyter에서 프로그램 "fb_news_53D_plotly.ipynb"를 실행합니다.
* 이번에는 9000건의 CSV 데이터가 출력되고 있다고 생각합니다만, 제 실행 환경에서는 CPU의 메모리가 적게 실행할 수 없었기 때문에, 절반의 5000건의 데이터분의 CSV 데이터를 작성해, 실행해 있습니다.
fb_news_53D_plotly.ipynboptions(warn=1)
source("/clickbait-cluster-master/Rstart.R")
library(htmlwidgets)
library(tidyr)
library(tsne)
#library(crosstalk) # Does not work unfortunately
library(plotly)
sessionInfo()
df <- read_csv('/clickbait-cluster-master/df_transform_53D.csv')
df %>% head() %>% print()
vector_names = paste0('w2v_', 1:53)
vector_trim <- function(vector)
substr(vector, 2, nchar(vector)-1)
vector_names %>% head() %>% print()
vector_trim(df$merged_vectors[1])
df$merged_vectors = lapply(df$merged_vectors, vector_trim)
df <- separate(data = df, col = merged_vectors, into = vector_names, convert=T, sep = ",")
df %>% select(w2v_1:w2v_4) %>% head() %>% print()
matrix <- df %>% select(w2v_1:w2v_53) %>% as.matrix()
system.time( cluster_coords <- tsne(matrix, initial_dims=53, perplexity=50, epoch=50) )
cluster_coords %>% head() %>% print()
df_transform = df %>% select(page_id, status_id, link_name, status_published, num_reactions) %>%
mutate(x = cluster_coords[,1], y= cluster_coords[,2])
df_transform %>% select(status_id, x, y) %>% head() %>% print()
write.csv(df_transform, "/clickbait-cluster-master/df_transform_53D.csv", row.names=F)
df_plot <- read_csv("/clickbait-cluster-master/df_transform_53D.csv")
df_plot %>% select(link_name, x, y) %>% mutate(link_name = substr(link_name,1,20)) %>% head() %>% print()
plot <- ggplot(df_plot, aes(x=x, y=y, color=page_id)) +
geom_point(alpha=0.75, stroke=0) +
theme_bw()
ggsave("/clickbait-cluster-master/fb-headlines-cluster-test-53D.png", plot, width=4, height=3, dpi=300)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=3),
text=~link_name)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-test-53D.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
processText <- function(row) {
sprintf("%s<br>%s Reactions<br>%s",
row[3],
format(as.numeric(row[5]), big.mark=","),
format(as.Date(substr(row[4], 1, 10) ), format = "%B %d, %Y" ))
}
apply(df_plot[1,], 1, processText)
df_plot$text = apply(df_plot, 1, processText)
# https://plot.ly/r/axes/
ax <- list(
title = "",
zeroline = FALSE,
showline = FALSE,
showticklabels = FALSE,
showgrid = FALSE
)
m = list(
l = 0,
r = 0,
b = 0,
t = 25,
pad = 0
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax, yaxis = ax, margin=m)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-standalone.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
font <- list(
family='Source Sans Pro, Arial, sans-serif'
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax,
yaxis = ax,
margin=m,
font=font,
plot_bgcolor ='#f7f8fa',
paper_bgcolor='#f7f8fa')
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-web.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
* 참고자료는 plotly의 출력 데이터를 createWidget, saveWidget을 사용하여 html 파일로 출력하고 있습니다. 하고 있습니다.
시각화 데이터를 살펴보기
위에서 출력된 html 파일 "fb-headlines-cluster-test-53D.html"을 열면, plotly에 의한 데이터 시각화가 행해지고 있다고 생각합니다.
Reference
이 문제에 관하여(Jupyter, Plotly를 사용한 시각화 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pentax0317/items/378f1130a606e735fe66
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
GitHub 더 필요한 파일을 다운로드합니다.
먼저 Jupyter를 시작하고 프로그램 "fb_news_53D_spark.ipynb"를 실행합니다.
fb_news_53D_spark.ipynb
spark_path = "/usr/local/Cellar/apache-spark/2.2.0/libexec/"
# Easiest way to get Spark to work with Jupyter: https://github.com/minrk/findspark
#import findspark
#findspark.init(spark_path)
#import pyspark
#from pyspark.sql import SparkSession
#sc = pyspark.SparkContext(appName='fb_headlines')
#spark = SparkSession(sc)
#config = sc._conf.getAll()
#print ('Web URL: ' + filter(lambda x: 'spark.driver.host' in x[0], config)[0][1] + ':4040')
from pyspark.sql.functions import regexp_replace
from pyspark.sql import Column
from pyspark.sql.types import *
def process_df(df):
return (df
.withColumn('text',regexp_replace('link_name', '\'', ''))
.filter("text != ''")
.filter("text != 'Timeline Photos'")
)
def read_tsv(path):
# predefine data frame schema: faster
schema = StructType([
StructField("page_id", StringType(), True),
StructField("status_id", StringType(), True),
StructField("link_name", StringType(), True),
StructField("status_published", TimestampType(), True),
StructField("num_reactions", IntegerType(), True)])
return spark.read.csv(path ,schema = schema, header=True, inferSchema=True, sep="\t")
df_cnn = read_tsv("/fb_headlines/CNN_fb.tsv")
df_nytimes = read_tsv("/fb_headlines/NYTimes_fb.tsv")
df_buzzfeed = read_tsv("/BuzzFeed_fb.tsv")
df_upworthy = read_tsv("/fb_headlines/Upworthy_fb.tsv")
df = df_cnn.union(df_nytimes).union(df_buzzfeed).union(df_upworthy)
df = process_df(df).cache()
df.select('link_name', 'status_published', 'num_reactions').show()
print ( df.count() )
df.printSchema()
from pyspark.ml.feature import Tokenizer, RegexTokenizer
tokenizer = RegexTokenizer(pattern="[^\w]",inputCol="text", outputCol="words")
df = tokenizer.transform(df)
df.select('text','words').show()
from pyspark.ml.feature import Word2Vec
word2Vec = Word2Vec(vectorSize=50, seed=42, inputCol="words", outputCol="vectors")
model = word2Vec.fit(df)
df = model.transform(df)
df.select('words', 'vectors').show()
model.findSynonyms("olympics", 20).show()
model.findSynonyms("election", 20).show()
from pyspark.ml.feature import StringIndexer, OneHotEncoder
stringIndexer = StringIndexer(inputCol="page_id", outputCol="indexed")
model = stringIndexer.fit(df)
df = model.transform(df)
encoder = OneHotEncoder(inputCol="indexed", outputCol="page_ohe")
df = encoder.transform(df)
df.select('page_id', 'page_ohe').show()
from pyspark.ml.feature import VectorAssembler
model = VectorAssembler(inputCols=['page_ohe', 'vectors'], outputCol="merged_vectors")
df = model.transform(df)
df.select('merged_vectors').show()
df2 = df.filter(df.status_published > '2016-06-01 00:00:00').cache()
print ( df2.count() )
df2.printSchema()
import pandas as pd
(df2.select('page_id', 'status_id', 'link_name', 'status_published', 'num_reactions', 'merged_vectors')
.toPandas()
.to_csv('/clickbait-cluster-master/df_transform_53D.csv', index=False, encoding="utf-8")
)
Facebook에서 가져온 뉴스 제목의 데이터는 Github에 게시된 데이터를 그대로 사용합니다.
프로그램 실행 후 결과 CSV 파일이 작성되었다고 생각합니다. 이 데이터는 뉴스 제목에 포함된 각 단어의 단어 벡터를 Word2vec 알고리즘으로 50차원 벡터로 변환한 것입니다.
다음으로 Jupyter에서 프로그램 "fb_news_53D_plotly.ipynb"를 실행합니다.
* 이번에는 9000건의 CSV 데이터가 출력되고 있다고 생각합니다만, 제 실행 환경에서는 CPU의 메모리가 적게 실행할 수 없었기 때문에, 절반의 5000건의 데이터분의 CSV 데이터를 작성해, 실행해 있습니다.
fb_news_53D_plotly.ipynb
options(warn=1)
source("/clickbait-cluster-master/Rstart.R")
library(htmlwidgets)
library(tidyr)
library(tsne)
#library(crosstalk) # Does not work unfortunately
library(plotly)
sessionInfo()
df <- read_csv('/clickbait-cluster-master/df_transform_53D.csv')
df %>% head() %>% print()
vector_names = paste0('w2v_', 1:53)
vector_trim <- function(vector)
substr(vector, 2, nchar(vector)-1)
vector_names %>% head() %>% print()
vector_trim(df$merged_vectors[1])
df$merged_vectors = lapply(df$merged_vectors, vector_trim)
df <- separate(data = df, col = merged_vectors, into = vector_names, convert=T, sep = ",")
df %>% select(w2v_1:w2v_4) %>% head() %>% print()
matrix <- df %>% select(w2v_1:w2v_53) %>% as.matrix()
system.time( cluster_coords <- tsne(matrix, initial_dims=53, perplexity=50, epoch=50) )
cluster_coords %>% head() %>% print()
df_transform = df %>% select(page_id, status_id, link_name, status_published, num_reactions) %>%
mutate(x = cluster_coords[,1], y= cluster_coords[,2])
df_transform %>% select(status_id, x, y) %>% head() %>% print()
write.csv(df_transform, "/clickbait-cluster-master/df_transform_53D.csv", row.names=F)
df_plot <- read_csv("/clickbait-cluster-master/df_transform_53D.csv")
df_plot %>% select(link_name, x, y) %>% mutate(link_name = substr(link_name,1,20)) %>% head() %>% print()
plot <- ggplot(df_plot, aes(x=x, y=y, color=page_id)) +
geom_point(alpha=0.75, stroke=0) +
theme_bw()
ggsave("/clickbait-cluster-master/fb-headlines-cluster-test-53D.png", plot, width=4, height=3, dpi=300)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=3),
text=~link_name)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-test-53D.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
processText <- function(row) {
sprintf("%s<br>%s Reactions<br>%s",
row[3],
format(as.numeric(row[5]), big.mark=","),
format(as.Date(substr(row[4], 1, 10) ), format = "%B %d, %Y" ))
}
apply(df_plot[1,], 1, processText)
df_plot$text = apply(df_plot, 1, processText)
# https://plot.ly/r/axes/
ax <- list(
title = "",
zeroline = FALSE,
showline = FALSE,
showticklabels = FALSE,
showgrid = FALSE
)
m = list(
l = 0,
r = 0,
b = 0,
t = 25,
pad = 0
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax, yaxis = ax, margin=m)
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-standalone.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
font <- list(
family='Source Sans Pro, Arial, sans-serif'
)
p <- plot_ly(df_plot,
x = ~x,
y = ~y,
color=~page_id,
type = "scattergl",
mode = "markers",
marker = list(line = list(width = 0), opacity=0.75, size=6),
text=~link_name,
hoverinfo="text+name") %>% layout(xaxis = ax,
yaxis = ax,
margin=m,
font=font,
plot_bgcolor ='#f7f8fa',
paper_bgcolor='#f7f8fa')
#createWidget(name="plotly",x=plotly_build(p), sizingPolicy=sizingPolicy(browser.padding = 0,
# browser.fill = F, defaultWidth = "100%", defaultHeight = 400)) %>%
#saveWidget("/clickbait-cluster-master/fb-headlines-cluster-web.html", selfcontained=T, libdir="plotly")
htmlwidgets::saveWidget(as_widget(p), "/clickbait-cluster-master/fb-headlines-cluster-test-53D.html")
* 참고자료는 plotly의 출력 데이터를 createWidget, saveWidget을 사용하여 html 파일로 출력하고 있습니다. 하고 있습니다.
시각화 데이터를 살펴보기
위에서 출력된 html 파일 "fb-headlines-cluster-test-53D.html"을 열면, plotly에 의한 데이터 시각화가 행해지고 있다고 생각합니다.
Reference
이 문제에 관하여(Jupyter, Plotly를 사용한 시각화 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/pentax0317/items/378f1130a606e735fe66
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Jupyter, Plotly를 사용한 시각화 프로그램), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/pentax0317/items/378f1130a606e735fe66텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)