在不使用循环的情况下模糊匹配电影标题并按发行日期提取等效标题
Fuzzy matching movie titles without using a loop and extracting equivalent titles by release date
我正在尝试使用模糊字符串匹配基于包含电影名称的电影标题列合并两个数据集。下面给出了 2 个数据集中的示例。
第一个数据集看起来像
itemid userid rating time title release_date
99995 1677 854 3 1997-12-22 sweet nothing 1995
99996 1678 863 1 1998-03-07 mat' i syn 1997
99997 1679 863 3 1998-03-07 b. monkey 1998
99998 1429 863 2 1998-03-07 sliding doors 1998
99999 1681 896 3 1998-02-11 you so crazy 1994
100000 1682 916 3 1997-11-29 scream of stone (schrei aus stein) 1991
第二个是
itemid userid rating time title release_date
117201 3175936 9140 3 2013-09-22 bei tou zou de na wu nian 2013
117202 3175936 17439 3 2013-09-18 bei tou zou de na wu nian 2013
117203 3181128 3024 5 2013-09-13 mac & jack 2013
117204 3181962 17310 5 2013-09-19 the last shepherd 2013
117205 3188690 13551 5 2013-09-17 the making of a queen 2013
117206 3198468 5338 3 2013-09-22 north 24 kaatham 2013
dput - df1
structure(list(itemid = c(1677L, 1678L, 1679L, 1429L, 1681L,
1682L), userid = c(854L, 863L, 863L, 863L, 896L, 916L), rating = c(3L,
1L, 3L, 2L, 3L, 3L), time = structure(c(10217, 10292, 10292,
10292, 10268, 10194), class = "Date"), title = c("sweet nothing",
"mat' i syn", "b. monkey", "sliding doors", "you so crazy", "scream of stone (schrei aus stein)"
), release_date = c("1995", "1997", "1998", "1998", "1994", "1991"
)), .Names = c("itemid", "userid", "rating", "time", "title",
"release_date"), row.names = 99995:100000, class = "data.frame")
dput - df2
structure(list(itemid = c(3175936L, 3175936L, 3181128L, 3181962L,
3188690L, 3198468L), userid = c(9140L, 17439L, 3024L, 17310L,
13551L, 5338L), rating = c(3, 3, 5, 5, 5, 3), time = structure(c(15970,
15966, 15961, 15967, 15965, 15970), class = "Date"), title = c("bei tou zou de na wu nian",
"bei tou zou de na wu nian", "mac & jack", "the last shepherd",
"the making of a queen", "north 24 kaatham"), release_date = c("2013",
"2013", "2013", "2013", "2013", "2013")), .Names = c("itemid",
"userid", "rating", "time", "title", "release_date"), row.names = 117201:117206, class = "data.frame")
我想使用 levenshteinSim 模糊匹配两个数据集中的标题,例如对于相似度大于 0.85 的标题,从两个数据集中提取该电影的信息到一个新数据集中。同时,我需要检查匹配的标题是否具有相同的发行日期,因为具有完全相同名称的电影可以有多个发行日期。
谁能指导我如何完成这项任务?
到目前为止我已经尝试了以下代码:
df <- sapply(df1$title,lenvenshteinSim,df2$title)
这给出了一个尺寸为 11451 X 1682 的矩阵。其中每一列都是来自第一个数据帧的单个电影标题,行包含相似度值。我可能会在此处放置一个循环,或者可能会查看 melt & dcast 以提取 max(similary) >0.85 的列,但这看起来不是一种有效的方法。另外,我无法匹配此代码中的发布日期。
您可以合并这些数据框
z <- merge(df1,df2,by='release_date',suffixes=c('.df1','.df2'))
这会给你一个笛卡尔积(即 df1
和 df2
之间的所有可能组合对于相同的 release_date
,然后通过以下方式计算 Levenshtein 距离:
z$L.dist <- lenvenshteinSim(z$title.df1,z$title.df2)
有了 z$L.dist
,您可以过滤所需的行:
subset(z,L.dist > 0.85)
更新
这是一个使用 data.table
的类似方法,这可能是一个更快的替代方法:
library(data.table)
d1 <- as.data.table(df1)
d2 <- as.data.table(df2)
setkey(d1,release_date)
setkey(d2,release_date)
z <- d1[d2,allow.cartesian=T,nomatch=F]
#z[,L.dist:=lenvenshteinSim(title,i.title)]
z[,L.dist:=mapply(lenvenshteinSim,title,i.title)]
z[L.dist > 0.8]
我正在尝试使用模糊字符串匹配基于包含电影名称的电影标题列合并两个数据集。下面给出了 2 个数据集中的示例。
第一个数据集看起来像
itemid userid rating time title release_date
99995 1677 854 3 1997-12-22 sweet nothing 1995
99996 1678 863 1 1998-03-07 mat' i syn 1997
99997 1679 863 3 1998-03-07 b. monkey 1998
99998 1429 863 2 1998-03-07 sliding doors 1998
99999 1681 896 3 1998-02-11 you so crazy 1994
100000 1682 916 3 1997-11-29 scream of stone (schrei aus stein) 1991
第二个是
itemid userid rating time title release_date
117201 3175936 9140 3 2013-09-22 bei tou zou de na wu nian 2013
117202 3175936 17439 3 2013-09-18 bei tou zou de na wu nian 2013
117203 3181128 3024 5 2013-09-13 mac & jack 2013
117204 3181962 17310 5 2013-09-19 the last shepherd 2013
117205 3188690 13551 5 2013-09-17 the making of a queen 2013
117206 3198468 5338 3 2013-09-22 north 24 kaatham 2013
dput - df1
structure(list(itemid = c(1677L, 1678L, 1679L, 1429L, 1681L,
1682L), userid = c(854L, 863L, 863L, 863L, 896L, 916L), rating = c(3L,
1L, 3L, 2L, 3L, 3L), time = structure(c(10217, 10292, 10292,
10292, 10268, 10194), class = "Date"), title = c("sweet nothing",
"mat' i syn", "b. monkey", "sliding doors", "you so crazy", "scream of stone (schrei aus stein)"
), release_date = c("1995", "1997", "1998", "1998", "1994", "1991"
)), .Names = c("itemid", "userid", "rating", "time", "title",
"release_date"), row.names = 99995:100000, class = "data.frame")
dput - df2
structure(list(itemid = c(3175936L, 3175936L, 3181128L, 3181962L,
3188690L, 3198468L), userid = c(9140L, 17439L, 3024L, 17310L,
13551L, 5338L), rating = c(3, 3, 5, 5, 5, 3), time = structure(c(15970,
15966, 15961, 15967, 15965, 15970), class = "Date"), title = c("bei tou zou de na wu nian",
"bei tou zou de na wu nian", "mac & jack", "the last shepherd",
"the making of a queen", "north 24 kaatham"), release_date = c("2013",
"2013", "2013", "2013", "2013", "2013")), .Names = c("itemid",
"userid", "rating", "time", "title", "release_date"), row.names = 117201:117206, class = "data.frame")
我想使用 levenshteinSim 模糊匹配两个数据集中的标题,例如对于相似度大于 0.85 的标题,从两个数据集中提取该电影的信息到一个新数据集中。同时,我需要检查匹配的标题是否具有相同的发行日期,因为具有完全相同名称的电影可以有多个发行日期。
谁能指导我如何完成这项任务?
到目前为止我已经尝试了以下代码:
df <- sapply(df1$title,lenvenshteinSim,df2$title)
这给出了一个尺寸为 11451 X 1682 的矩阵。其中每一列都是来自第一个数据帧的单个电影标题,行包含相似度值。我可能会在此处放置一个循环,或者可能会查看 melt & dcast 以提取 max(similary) >0.85 的列,但这看起来不是一种有效的方法。另外,我无法匹配此代码中的发布日期。
您可以合并这些数据框
z <- merge(df1,df2,by='release_date',suffixes=c('.df1','.df2'))
这会给你一个笛卡尔积(即 df1
和 df2
之间的所有可能组合对于相同的 release_date
,然后通过以下方式计算 Levenshtein 距离:
z$L.dist <- lenvenshteinSim(z$title.df1,z$title.df2)
有了 z$L.dist
,您可以过滤所需的行:
subset(z,L.dist > 0.85)
更新
这是一个使用 data.table
的类似方法,这可能是一个更快的替代方法:
library(data.table)
d1 <- as.data.table(df1)
d2 <- as.data.table(df2)
setkey(d1,release_date)
setkey(d2,release_date)
z <- d1[d2,allow.cartesian=T,nomatch=F]
#z[,L.dist:=lenvenshteinSim(title,i.title)]
z[,L.dist:=mapply(lenvenshteinSim,title,i.title)]
z[L.dist > 0.8]