在Kmeans中查找推特和群集的Jaccard距离

时间:2016-04-07 18:33:49

标签: json r algorithm twitter k-means

这是我一直在努力解决的问题的后续问题。我有两个问题。一个问题是一个适用于两条推文的算法,我修改后测量了10条推文。我想知道我的修订版正在测量什么。我得到了结果,但是我希望它能够测量几个推文的jaccard距离,而不仅仅是返回一个值。由于它返回了一个值,我认为它只是添加了一切。另一个问题是关于我尝试创建For循环并分配集群。

我正在尝试找到推文数据集之间的Jaccard距离,然后使用Kmeans算法对这些推文进行聚类。

这是我从以下位置检索数据的地方: http://www3.nd.edu/~dwang5/courses/spring15/assignments/A2/Tweets.json

到目前为止我所拥有的是

    install.packages("rjson")
library("rjson")


#download JSON File and put into a dataframe
download.file("http://www3.nd.edu/~dwang5/courses/spring15/assignments/A2/Tweets.json", tf<-tempfile());library(jsonlite);json_alldata <- fromJSON(sprintf("[%s]", paste(readLines(file(tf)),collapse=",")))

# get rid of geo column
tweet.features = json_alldata
tweet.features$geo <- NULL

# *Works.   Compares two tweets and measures Jaccard Distance

tweetText <- list(tweet1 = tweet.features$text[1]:tweet.features$text[2])

jaccard_i <- function(tw1, tw2){
  tw1 <- unlist(strsplit(tw1, " |\\."))
  tw2 <- unlist(strsplit(tw2, " |\\."))
  i <- length(intersect(tw1, tw2))
  u <- length(union(tw1, tw2))

  list(i=i, u=u, j=i/u)
}

jaccard_i(tweetText[[1]], tweetText[[2]])

所有这些都衡量两个指定推文的jaccard距离。哪个好。

但现在我正在尝试修改以比较几条推文之间的距离。这次是我从R。

中的Sample命令检索到的10条随机推文
# Generates two sets of 5 random tweets
tweetText <- list(sample(tweet.features$text, replace = FALSE, size = 5), sample(tweet.features$text, replace = FALSE, size = 5))

jaccard_i <- function(tw1, tw2){
  tw1 <- unlist(strsplit(tw1, " |\\."))
  tw2 <- unlist(strsplit(tw2, " |\\."))
  i <- length(intersect(tw1, tw2))
  u <- length(union(tw1, tw2))

  list(i=i, u=u, j=i/u)
}

jaccard_i(tweetText[[1]], tweetText[[2]])

这给了我结果,但它不正确。

我正在尝试构建一种算法,可以测量所有推文,比较它们的jaccard距离,然后基于Jaccard与Kmeans的距离进行聚类。

所以对于另一次尝试,我想做一个For循环。

我决定使用10条随机推文创建10个集群中心

c <- sample(tweet.features$text, replace = FALSE, size = 10)

现在我做了一个For循环,希望测量我认为我可以分配给数组和集群的推文

#Algorithm attempt
for(i in tweet.features$text){
  for (j in c){
    i <- length(intersect(i, j))
    u <- length(union(i, j))
    j = i/u
  }
  #assign(my.array)
}

我不相信它正在做任何有用的事情,但它试图创建一个测量Jaccard距离的循环。

对不起,这是一个有问题的问题。任何帮助都会受到赞赏,因为我有点失落。

1 个答案:

答案 0 :(得分:2)

在您的第一个功能中,您正在对推文中的单词列表unlist进行操作,因此在tw1tw2中有全局单词列表,您无法使用它们你的推文Jaccard。您可以通过删除unlist来完成此操作,然后tw1tw2是术语列表的列表,您可以使用mapply对它们进行比较。事情如下。

jaccard_i <- function(tw1, tw2){
  tw1 <- strsplit(tw1, " |\\.")
  tw2 <- strsplit(tw2, " |\\.")
  i <- mapply(function(tw1, tw2) {
    length(intersect(tw1, tw2))
  }, tw1=tw1, tw2=tw2)
  u <- mapply(function(tw1, tw2) {
    length(union(tw1, tw2))
  }, tw1=tw1, tw2=tw2)
  list(i=i, u=u, j=i/u)
}

愚蠢的例子:

> tw1 = c("we yes you no", "we are the people")
> tw2= c("we are the people", "we yes you no")
> tweetText = list(tw1, tw2)
> jaccard_i(tweetText[[1]], tweetText[[2]])
$i
[1] 1 1

$u
[1] 7 7

$j
[1] 0.1428571 0.1428571

关于你问题的第二部分,双循环,开始解决它的简单方法就是这样,

tw = c("we yes you no", "we are the people")
lapply(tw, function(tweet1) {
  lapply(tw, function(tweet2) {
    jaccard_i(tweet1, tweet2)
  })
})

结果看起来像这样,

[[1]]
[[1]][[1]]
[[1]][[1]]$i
[1] 4

[[1]][[1]]$u
[1] 4

[[1]][[1]]$j
[1] 1


[[1]][[2]]
[[1]][[2]]$i
[1] 1

[[1]][[2]]$u
[1] 7

[[1]][[2]]$j
[1] 0.1428571



[[2]]
[[2]][[1]]
[[2]][[1]]$i
[1] 1

[[2]][[1]]$u
[1] 7

[[2]][[1]]$j
[1] 0.1428571


[[2]][[2]]
[[2]][[2]]$i
[1] 4

[[2]][[2]]$u
[1] 4

[[2]][[2]]$j
[1] 1

你应该跳过对角线上的值 - 正如我所说的那样,这是一个起点。

希望它有所帮助。