【问题标题】:R - Document Term Matrix with comma separated text column entriesR - 带有逗号分隔的文本列条目的文档术语矩阵
【发布时间】:2019-04-18 21:02:52
【问题描述】:

我有一个数据框,其中有一列由字符串 (project_skills) 组成,表示某个工作 (job_id) 提供的技能。我想为每个工作拆分这个字符串以获得一个工作提供的技能向量,然后创建一个文档术语矩阵来表示某个工作提供哪些技能(在所有可能的技能中)。

我有以下数据框:

job_id           project_skills
107182           CSS,HTML,Joomla,PHP
108169           XTCommerce,Magento,Prestashop,VirtueMart,osCommerce
112969           Google Search Console,Google Analytics,Google Webmaster Central,C++,Java,C#
114660           Marketing,Email Marketing
118686           PHP

结果应该看起来像这样(基本上是一个带有逗号分隔短语的文档术语矩阵:

        project_skills
job_id  CSS   HTML   PHP   Google Search Console   Google Analytics   Java ...
107182  1     0       0 ...         
108169  0     0       0     0                       0         
112969  0     0       0     1                       1 ...         
114660  0     0       0 ...            
118686  0     0       1 ...

我尝试了以下方法:

df <- data.frame(job_id = c(107182, 108169, 112969, 114660, 118686), project_skills = c("CSS,HTML,Joomla,PHP", "XTCommerce,Magento,Prestashop,VirtueMart,osCommerce", "Google Search Console,Google Analytics,Google Webmaster Central,C++,Java,C#", "Marketing,Email Marketing", "PHP"))

corpus <- Corpus(VectorSource(df$project_skills))
corpus <- tm_map(corpus, function(x) {
PlainTextDocument(
    strsplit(x,"\\,")[[1]], 
    id=ID(x)
)
})
inspect(corpus)
dtm <- DocumentTermMatrix(corpus)
as.matrix(dtm)

但不幸的是,这会拆分所有单词而不是逗号(例如,Google Search Console 应被视为 DTM 中的一个术语)。

【问题讨论】:

    标签: r string dataframe tm strsplit


    【解决方案1】:

    tm(或其他一些文本挖掘包)在单词(空格)上拆分,如果你不检查,往往会删除像 + 和 # 这样的标点符号。最简单的选择就是使用strsplit。我在下面使用 tidyr 和 dplyr 显示了一个选项。第一个按job_id分组,然后拆分列。这将创建一个嵌套,当未嵌套时会创建一个长 data.frame。在这里,我为每个条目添加值 1,这就像文档术语矩阵中的 1 一样。然后传播成宽格式以获得您预期的输出。如果您查看生成的结构,列名就是您所期望的,而不是显示波浪号 (~)。

    library(tidyr)
    library(dplyr)
    
    outcome <- df1 %>%
      group_by(job_id) %>% 
      mutate(project_skills = strsplit(project_skills, ",")) %>% 
      unnest() %>% 
      mutate(value = 1) %>% # add 1 for every value
      spread(key = project_skills, value = value) # use fill = 0 if you don't want NA's
    
    head(outcome)
    # A tibble: 5 x 18
    # Groups:   job_id [5]
      job_id  `C#` `C++`   CSS `Email Marketin~ `Google Analyti~ `Google Search ~ `Google Webmast~  HTML  Java Joomla Magento Marketing
       <int> <dbl> <dbl> <dbl>            <dbl>            <dbl>            <dbl>            <dbl> <dbl> <dbl>  <dbl>   <dbl>     <dbl>
    1 107182    NA    NA     1               NA               NA               NA               NA     1    NA      1      NA        NA
    2 108169    NA    NA    NA               NA               NA               NA               NA    NA    NA     NA       1        NA
    3 112969     1     1    NA               NA                1                1                1    NA     1     NA      NA        NA
    4 114660    NA    NA    NA                1               NA               NA               NA    NA    NA     NA      NA         1
    5 118686    NA    NA    NA               NA               NA               NA               NA    NA    NA     NA      NA        NA
    # ... with 5 more variables: osCommerce <dbl>, PHP <dbl>, Prestashop <dbl>, VirtueMart <dbl>, XTCommerce <dbl>
    

    【讨论】:

    • 非常感谢,这解决了我的问题,这是一个非常灵活和好的解决方案。 ?
    【解决方案2】:

    有很多解决方案,但 strsplit 是你的朋友。这正是以下代码中所做的:

    library(udpipe)
    df <- data.frame(job_id = c(107182, 108169, 112969, 114660, 118686), project_skills = c("CSS,HTML,Joomla,PHP", "XTCommerce,Magento,Prestashop,VirtueMart,osCommerce", "Google Search Console,Google Analytics,Google Webmaster Central,C++,Java,C#", "Marketing,Email Marketing", "PHP"), 
                     stringsAsFactors = FALSE)
    dtm <- document_term_frequencies(x = df$project_skills, document = df$job_id, split = ",")
    dtm <- document_term_matrix(dtm)
    colnames(dtm)
     [1] "C#"                       "C++"                      "CSS"                      "Email Marketing"         
     [5] "Google Analytics"         "Google Search Console"    "Google Webmaster Central" "HTML"                    
     [9] "Java"                     "Joomla"                   "Magento"                  "Marketing"               
    [13] "osCommerce"               "PHP"                      "Prestashop"               "VirtueMart"              
    [17] "XTCommerce"              
    rownames(dtm)
    [1] "107182" "108169" "112969" "114660" "118686"
    dim(dtm)
    [1]  5 17
    

    【讨论】:

    • 感谢这个解决方案也有效,而且更简单、更紧凑?
    猜你喜欢
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    相关资源
    最近更新 更多