在 Kmeans 中查找推文和聚类的 Jaccard 距离

Find Jaccard distance of tweets and cluster in Kmeans

这是我已经研究了一段时间的问题的后续问题。我有两个问题。一种算法适用于两条推文,我对其进行了修改以测量 10 条推文。我想知道我的修订衡量的是什么。我得到了结果,但我希望它测量多个推文的 jaccard 距离,而不仅仅是 return 一个值。由于它是 returning 一个值,我认为它只是将所有内容相加。另一个问题是关于我尝试创建一个 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 距离。

很抱歉,这是一个加载的问题。任何帮助将不胜感激,因为我有点迷茫。

在你的第一个函数中,你正在对推文中的单词列表进行 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

当然,您应该跳过对角线中的值 - 正如我所说,这只是一个起点。

希望对您有所帮助。