为什么某个类特有的特征未被强烈预测为该类?

总结与问题

我正在使用liblinear 2.30 – 我注意到生产环境中存在类似的问题,因此我尝试通过简化的训练来隔离它,包含2个类,每个类一个训练文档,词汇表中5个特征的权重相同,以及一个仅包含一个特征的简单测试文档,该特征仅存在于类2中。

  • a) 特征值用于什么目的?

  • b) 我想了解为什么这个只包含一个特征的测试文档,该特征仅存在于一个类中,却未被强烈预测为该类?

  • c) 我并不期望每个特征有不同的值。将每个特征值从1增加到其他值是否有其他影响?我如何确定这个数字?

  • d) 我的更改是否会对其他更复杂的训练产生不良影响?

我尝试过的方法

下面你会找到与简单训练相关的数据(请关注特征5):

> cat train.txt1 1:1 2:1 3:12 2:1 4:1 5:1> train -s 0 -c 1 -p 0.1 -e 0.01 -B 0 train.txt model.biniter  1 act 3.353e-01 pre 3.333e-01 delta 6.715e-01 f 1.386e+00 |g| 1.000e+00 CG   1iter  2 act 4.825e-05 pre 4.824e-05 delta 6.715e-01 f 1.051e+00 |g| 1.182e-02 CG   1> cat model.binsolver_type L2R_LRnr_class 2label 1 2nr_feature 5bias 0w0.337414143653901600.3374141436539016-0.3374141436539016-0.33741414365390160

这是模型的输出:

solver_type L2R_LRnr_class 2label 1 2nr_feature 5bias 0w0.337414143653901600.3374141436539016-0.3374141436539016-0.337414143653901601 5:10

下面是我的模型预测结果:

> cat test.txt1 5:1> predict -b 1 test.txt model.bin test.outAccuracy = 0% (0/1)> cat test.outlabels 1 22 0.416438 0.583562

这里我有点惊讶,因为预测结果仅为[0.42, 0.58],而特征5仅存在于类2中。为什么呢?因此,我尝试将测试文档的特征值从1增加到10:

> cat newtest.txt1 5:10> predict -b 1 newtest.txt model.bin newtest.outAccuracy = 0% (0/1)> cat newtest.outlabels 1 22 0.0331135 0.966887

现在我得到了更好的预测结果[0.03, 0.97]。因此,我尝试重新编译我的训练数据,将所有特征设置为10:

> cat newtrain.txt1 1:10 2:10 3:102 2:10 4:10 5:10> train -s 0 -c 1 -p 0.1 -e 0.01 -B 0 newtrain.txt newmodel.biniter  1 act 1.104e+00 pre 9.804e-01 delta 2.508e-01 f 1.386e+00 |g| 1.000e+01 CG   1iter  2 act 1.381e-01 pre 1.140e-01 delta 2.508e-01 f 2.826e-01 |g| 2.272e+00 CG   1iter  3 act 2.627e-02 pre 2.269e-02 delta 2.508e-01 f 1.445e-01 |g| 6.847e-01 CG   1iter  4 act 2.121e-03 pre 1.994e-03 delta 2.508e-01 f 1.183e-01 |g| 1.553e-01 CG   1> cat newmodel.binsolver_type L2R_LRnr_class 2label 1 2nr_feature 5bias 0w0.1942051039536484600.19420510395364846-0.19420510395364846-0.194205103953648460> predict -b 1 newtest.txt newmodel.bin newtest.outAccuracy = 0% (0/1)> cat newtest.outlabels 1 22 0.125423 0.874577

再次预测结果对于类2仍然可以接受:0.87


回答:

a) 特征值用于什么目的?

每个n个特征的实例被视为n维空间中的一个点,并附有一个给定的标签,比如+1或-1(在你的例子中是1或2)。线性SVM试图找到最佳超平面,将这些实例分成两个集合,比如SetA和SetB。当SetA包含更多标记为+1的实例,而SetB包含更多标记为-1的实例时,超平面被认为比其他超平面更好,即更准确。最佳超平面被保存为模型。在你的情况下,超平面的公式为:

f(x)=w^T x

其中w是模型,例如在你的第一个案例中是(0.33741,0,0.33741,-0.33741,-0.33741)。

概率(对于LR)的公式为:

prob(x)=1/(1+exp(-y*f(x))

其中y=+1或-1。参见LIBLINEAR论文的附录L。

b) 我想了解为什么这个只包含一个特征的测试文档,该特征仅存在于一个类中,却未被强烈预测为该类?

不仅1 5:1给出了如[0.42,0.58]的弱概率,如果你预测2 2:1 4:1 5:1,你会得到[0.337417,0.662583],这似乎表明求解器对结果也不是很自信,即使输入与训练数据集完全相同。

根本原因在于f(x)的值,或者可以简单地看作x与超平面之间的距离。只有当距离无限大时(见prob(x)),才能100%确信x属于某个类别。

c) 我并不期望每个特征有不同的值。将每个特征值从1增加到其他值是否有其他影响?我如何确定这个数字?

TL;DR

放大训练集和测试集就像拥有更大的惩罚参数C(-c选项)。因为更大的C意味着对错误有更严格的惩罚,直观上说,求解器对预测更有信心。


放大训练集的每个特征就像拥有更小的C。具体来说,逻辑回归解决以下关于w的方程。

min 0.5 w^T w + C ∑i log(1+exp(−yi w^T xi)) 

LIBLINEAR论文的eq(3))

对于大多数实例,yi w^T xi是正的,且更大的xi意味着更小的∑i log(1+exp(−yi w^T xi))。因此效果有些类似于拥有更小的C,而更小的C意味着更小的|w|。

另一方面,放大测试集相当于拥有更大的|w|。因此,放大训练集和测试集的基本效果是

(1). 训练时拥有更小的|w|(2). 然后,测试时拥有更大的|w|

因为(2)的效果比(1)更显著,总体来说,放大训练集和测试集就像拥有更大的|w|,或者说拥有更大的C。

我们可以在数据集上运行,并将每个特征乘以10^12。在C=1的情况下,我们有模型和概率

> cat model.bin.m1e12.c1solver_type L2R_LRnr_class 2label 1 2nr_feature 5bias 0w3.0998430106024949e-12 0 3.0998430106024949e-12 -3.0998430106024949e-12 -3.0998430106024949e-12 0 > cat test.out.m1e12.c1labels 1 22 0.0431137 0.956886

接下来我们在原始数据集上运行。在C=10^12的情况下,我们有概率

> cat model.bin.m1.c1e12solver_type L2R_LRnr_class 2label 1 2nr_feature 5bias 0w3.0998430101989314 0 3.0998430101989314 -3.0998430101989314 -3.0998430101989314 0 > cat test.out.m1.c1e12labels 1 22 0.0431137 0.956886

因此,因为更大的C意味着对错误有更严格的惩罚,所以直观上求解器对预测更有信心。

d) 我的更改是否会对其他更复杂的训练产生不良影响?

从(c)我们知道你的更改就像拥有更大的C,这将导致更好的训练准确性。但几乎可以肯定,当C变得太大时,模型会过拟合训练集。结果,模型无法承受训练集中的噪声,测试准确性会表现得很差。

至于找到一个好的C,一个流行方法是通过交叉验证(-v选项)。


最后,

这可能有点跑题,但你可能想看看如何预处理文本数据。通常(例如,liblinear的作者在这里建议),对数据进行实例级归一化是很常见的做法。

对于文档分类,我们的经验表明,如果你将每个文档归一化为单位长度,那么不仅训练时间更短,而且性能也更好。

Related Posts

多维度Top-k评分

例如,在机器学习中的自然语言处理中,通常使用波束搜索来…

R – Caret train() “错误:停止” 与 “在newdata中未找到对象中使用的所有变量名”

我正在尝试为蘑菇数据构建一个简单的朴素贝叶斯分类器。我…

创建训练和测试数据集分割,数据嵌套在多个文件夹中

我正在准备数据以训练一个图像识别模型。目前我有一个文件…

我的神经网络预测出现错误:IndexError: list index out of range

我正在进行一个简单的垃圾邮件/非垃圾邮件文本分类。我的…

python 给出数组是一维的,但索引了两个维度错误

我已经为 miniBatchGradientDesce…

TensorFlow自定义训练步骤使用不同的损失函数

背景 根据TensorFlow文档,可以使用以下方式执…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注