我们应该在训练/测试拆分之前还是之后对文本数据进行预处理?

如何解决我们应该在训练/测试拆分之前还是之后对文本数据进行预处理?

我已经阅读了许多有监督的文本分类教程,并且为我的数据实现了tidytext,qunateda,tm,text2vec,RTextTools。 直到现在,我还有一个未解之谜 。对于何时标记文本数据似乎没有达成共识。 火车测试拆分之前还是之后?。在一篇有关堆栈溢出的文章中,有人认为在拆分之前对令牌进行标记甚至是非法的。使用dfm_match函数,quanteda包看起来像是设计为在拆分数据后进行令牌化的。其他人建议在预处理后进行拆分。我看过Julia Silge和Emil Hvitfeldt的精彩教程。
对我来说,如果我在拆分之前进行了预处理步骤,它将为我节省很多代码行。但是,有什么风险?数据泄漏还是什么?有没有证据将两者在分类性能,有效性等方面进行比较?

解决方法

“非法分割”?听起来很有趣(也许很有趣),但我从未听说过。

问题是:在什么情况下会有所作为,以及如何改变?训练测试拆分对文档进行分区。在拆分之前还是之后对令牌进行标记可能无关紧要,因为文档仍将包含相同的令牌。

但是,一旦从这些标记构建矩阵,如果在拆分之后 完成了此操作,则模型矩阵的特征集可能会与测试集中的特征集有所不同。要在测试集上进行预测,测试数据的特征必须与训练矩阵中的特征一致。处理不匹配有几种可能性。

  • 训练集中的功能,但测试集中没有。在 quanteda.textmodels 中,它在predict()中具有一个(方便!)选项,以使预测矩阵自动符合训练矩阵,这意味着测试集将添加此功能。但算作零。 考虑到该功能为训练数据添加了信息,并且可以在测试数据中将其缺少作为信息提供信息,因此证明了这一点的合理性。

  • 功能不在训练集中,但在测试集中。大多数时候,您可能会完全忽略此功能。为什么?由于在训练后的模型中没有关于它的信息,因此它的效果要么不确定,要么完全归因于平滑处理。

回到问题上,它将如何有所作为?我能看到的主要内容是何时形成文档功能矩阵(dfm),然后将其按行拆分,并且训练集中的某些功能完全为零(但在测试集中为零)。如果以包括零频特征的方式进行拆分,则某些受监督的方法会对此进行平滑处理,从而包括其平滑值。

这是 quanteda 中的一个示例,该示例使用了朴素贝叶斯分类器,该分类器默认对所有要素使用+1平滑。

让我们用两个类组成一个简单的dfm。

library("quanteda")
## Package version: 2.1.1

txt <- c(
  d1 = "a a b b d",d2 = "a a a b b",d3 = "a b d d d",d4 = "a a b c d"
)
y <- c("black","black","white",NA)
train <- c(TRUE,TRUE,FALSE)
test <- !train

现在先标记化,然后分割。请注意,对于整个三个训练集文档,功能c为零,但是如果在此组合dfm上进行了索引切片,则该特征将出现在训练集中。

dfmat1 <- tokens(txt) %>%
  dfm()
dfmat1
## Document-feature matrix of: 4 documents,4 features (25.0% sparse).
##     features
## docs a b d c
##   d1 2 2 1 0
##   d2 3 2 0 0
##   d3 1 1 3 0
##   d4 2 1 1 1

在标记和形成dfm之前进行切片时,不包含功能c

dfmat2 <- tokens(txt[train]) %>%
  dfm()
dfmat2
## Document-feature matrix of: 3 documents,3 features (11.1% sparse).
##     features
## docs a b d
##   d1 2 2 1
##   d2 3 2 0
##   d3 1 1 3

测试矩阵如下所示,与“黑色”相关的a相比,与“白色”相关的d的数量更多。

dfmattest <- tokens(txt[test]) %>%
  dfm()
dfmattest
## Document-feature matrix of: 1 document,4 features (0.0% sparse).
##     features
## docs a b c d
##   d4 2 1 1 1

现在,当我们训练模型并进行预测时,当包含c时我们会看到:

library("quanteda.textmodels")

tmod1 <- textmodel_nb(dfmat1,y)
coef(tmod1)
##        black     white
## a 0.42857143 0.2222222
## b 0.35714286 0.2222222
## d 0.14285714 0.4444444
## c 0.07142857 0.1111111
predict(tmod1,newdata = dfmattest,force = TRUE,type = "prob")
##        black     white
## d4 0.5526057 0.4473943

,但不是时,结果略有不同:

tmod2 <- textmodel_nb(dfmat2,y[train])
coef(tmod2)
##       black white
## a 0.4615385  0.25
## b 0.3846154  0.25
## d 0.1538462  0.50
predict(tmod2,type = "prob")
## Warning: 1 feature in newdata not used in prediction.
##        black     white
## d4 0.6173551 0.3826449

警告消息告诉我们,由于训练集中没有使用测试集功能c,因此无法预测结果。

所以要问的问题是,您是否希望将缺少功能视为有益的信息?对于默认的多项式朴素贝叶斯(Naive Bayes),如果您是在根据所有要素形成dfm后进行拆分的,则可以通过平滑来建模缺失,或者如果先拆分并分别创建每个dfm,则可以将其忽略。答案取决于您要如何对待零以及它们在问题中的含义。这也部分取决于您的模型,因为(例如)对于Bernoulli Naive Bayes而言,零被认为是有用的。

,

我创建带有tidymodels的配方并拆分数据集(测试,训练,验证),然后再运行代码。拆分背后的想法是确保您不知道(测试)之后的数据。验证和训练拆分的想法相同,但是,整个数据集的预处理必须相同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?