Интерактивная визуализация постов с фан-страниц Facebook

Цель

Цель этого короткого сообщения в блоге - продемонстрировать интерактивный инструмент визуализации с результатами обработки естественного языка с помощью алгоритма word2vec на сообщениях FB из аналогичных медиа-каналов.

Результат

Созданный интерактивный инструмент находится здесь.

Из анимированного GIF ниже видно, что сообщения с похожим содержанием ближе друг к другу благодаря алгоритму word2vec! Мы также заметили, что сообщения из National Geographic (точки данных выделены розовым цветом) более сгруппированы в середине, чем сообщения из других каналов, что позволяет предположить, что они либо сосредоточены на более узких темах, либо используют аналогичные формулировки в Facebook.

Подход

Этот пост в блоге вдохновлен постом Макса Вульфа, в котором он использовал Spark и Python для визуализации заголовков кликбейтов из популярных новостных каналов. Мы изменили его подход, так что аналогичная аналогия может быть проделана в R с другими инструментами. Настоятельно рекомендуется просмотреть алгоритм word2vec здесь и сообщение приложения здесь, прежде чем продолжить.

Используемые инструменты: fanpager, R, plotly

  1. Удалите последние сообщения со всех 4 фан-страниц медиа-каналов.
    Нажмите здесь, чтобы просмотреть пошаговое руководство.
  2. Обработка контента с помощью алгоритма НЛП word2vec
    Нажмите здесь, чтобы увидеть введение в алгоритм.
    Нажмите здесь, чтобы просмотреть пошаговое руководство
  3. Визуализируйте результаты с помощью Plotly (см. Полный код R в конце)

Выделять

Изначально мы хотели видеть только векторизованный результат без стоп-слов в сообщениях National Geographic и Discovery Channel.

Мы выполнили t-NSE для преобразования 100-размерных векторов word2vec в 2-мерные для 2D-визуализации на диаграмме рассеяния. Замечено, что если мы удалим стоп-слова, такие как the, a, и that, сообщения National Geographic будут ближе друг к другу, образуя более плотную S-образную форму, а сообщения от Discovery сформировали более широкую S-образную форму с кластером справа, что указывает на большее сходство между этими сообщениями.

В то время как t-SNE имеет тенденцию включать как можно больше информации о многомерных наборах данных, PCA стремится сохранить структуру данных с линейной аппроксимацией.

Сначала мы рассмотрим производительность от PCA. Он показывает, что, используя только 2 главных компонента, мы можем представить более 95% исходных векторов!

Результат PCA со стоп-словами кажется более интересным. Он показал, что сообщения от National Geographic больше ориентированы на левую сторону, в то время как сообщения от Discovery имеют тенденцию смещаться вправо, в сторону от центра.

Кажется, что PCA со стоп-словами может наградить нас более интересными результатами. Давайте продолжим и включим посты из Animal Planet и History Channel.

Хотя производительность PCA упала, мы все еще могли отображать более 90% исходных векторов.

Созданный интерактивный инструмент находится здесь.

Теперь мы можем четко наблюдать следующее:

1… Большинство сообщений National Geographic похожи.
2… Discovery Channel предлагает как узкие, так и более широкие сообщения с меньшим количеством контента
3… Сообщения History Channel более сосредоточены в нижней части
4 … Animal Planet охватывает более широкий круг тем, относительно

Код R

#Data Cleaning
animal <- read.csv("animal.csv",header=FALSE)
animal$V1 <- paste(animal$V1,animal$V2,animal$V3,animal$V4,animal$V5,animal$V6,animal$V7,sep="")
animal$V1 <- sub(".*;","",animal$V1)
animal$V1 <- sub('""""','',animal$V1)
animal$V1 <- sub('"""','',animal$V1)
animal$V1 <- sub('""','',animal$V1)
animal$V1 <- sub('"','',animal$V1)
animal$V1 <- sub('"','',animal$V1)
animal$V1 <- sub('"','',animal$V1)
#Prepare the dataset
train = text$title
train = gsub("[[:punct:]]", "", train)
train <- tolower(train)
stopWords <- stopwords("en")
'%nin%' <- Negate('%in%')
train <- lapply(train, function(x) {
  t <- unlist(strsplit(x, " "))
  t[t %nin% stopWords]
})
train.df = as.data.frame(do.call(rbind, train))
write.table(train.df,"text_data.txt")
write(train,"text_data.txt")
#Input words to model
model=word2vec(train_file = "text_data.txt",output_file = "vec.bin",binary=1)
#Convert binary to text format
bin_to_txt("vec.bin","model1text.txt")
#Convert .txt to .cvs
model1 <- read.table("model1text.txt",fill=TRUE)
write.csv(model1,"model1.csv")
m1 <- read.csv("model1.csv")
#Apply word vectors to posts
s <- strsplit(text$title, split = " ")
new <- data.frame(V1 = rep(text$id, sapply(s, length)), V2 = unlist(s))
colnames(new) <- c("id","word")
colnames(m1)[1] <- "word"
new <- merge(new,m1,by="word")
new2 <- aggregate(V2 ~ id, new, mean)
for (i in 4:102){
  new3 <- aggregate(new[,i] ~ id, new, mean)
  new2 <- merge (new2,new3,by="id")
}
colnames(new2)[1] <- "id"
colnames(new2)[2:101] <- paste("V", 1:100, sep="")
new2$id <- as.factor(new2$id)
#t-SNE on posts
set.seed(1)
tsne <- Rtsne(new2, dims = 2, perplexity=100, verbose=TRUE, max_iter = 500)
t = as.data.frame(tsne$Y)
id <- subset(new2,select="id")
t <- merge(id,t,by=0)
fanpage <- text[,c(1:2)]
final <- merge(fanpage,t,by="id")
plot.t <- ggplot(final,aes(V1, V2, color = final$fanpage))+geom_point(alpha=0.7,size=1)
plot.t
#PCA on posts
pcadata <- new2
pcadata$id <- NULL
pr.out=prcomp(pcadata, scale=TRUE)
pr.out$sdev
pr.var=pr.out$sdev ^2
pve=pr.var/sum(pr.var)
pve
plot(pve, xlab="Principal Component", ylab="Proportion of Variance Explained ", ylim=c(0,1),type="b")
plot(cumsum(pve), xlab="Principal Component ", ylab=" Cumulative Proportion of Variance Explained ", ylim=c(0,1), type="b")
pcadata2 <- scale(pcadata, pr.out$center, pr.out$scale) %*% pr.out$rotation
p1 <- merge(id,pcadata2,by=0)
pfinal <- merge(fanpage,p1,by="id")
pfinal <- merge(pfinal,text,by="id")
#plotly
p <- plot_ly(pfinal, x = ~PC1, y = ~PC2, color = ~fanpage.x, type = 'scatter', mode = 'markers',hoverinfo = 'text',text = ~title)
plotly_POST(p, filename="word2vec")

Это резюмирует сообщение в блоге, надеюсь, оно будет полезным и интересным.

В будущих приложениях мы можем применить алгоритм word2vec к неструктурированным данным, таким как отзывы клиентов, для улучшения прогнозных моделей.

Вопросы, комментарии или проблемы?
[email protected]