是否有原因为啥仅存在于给定类中的特征没有被强烈预测到该类中?

Posted

技术标签:

【中文标题】是否有原因为啥仅存在于给定类中的特征没有被强烈预测到该类中?【英文标题】:Is there a reason why a feature only present in a given class is not being predicted strongly into that class?是否有原因为什么仅存在于给定类中的特征没有被强烈预测到该类中? 【发布时间】:2020-05-17 22:26:32 【问题描述】:

总结和问题

我正在使用 liblinear 2.30 - 我注意到 prod 中存在类似问题,因此我尝试通过简单的减少训练来隔离它,其中包含 2 个类、每类 1 个训练文档、5 个在我的词汇表中具有相同权重的特征和 1 个简单的测试文档仅包含仅存在于第 2 类中的一项功能。

a) 特征值的用途是什么?

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

c) 我不希望每个功能有不同的值。将每个特征值从 1 增加到其他值是否还有其他含义?我如何确定这个数字?

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

我尝试了什么

您将在下面找到与简单训练相关的数据(请关注功能 5):

> cat train.txt
1 1:1 2:1 3:1
2 2:1 4:1 5:1
> train -s 0 -c 1 -p 0.1 -e 0.01 -B 0 train.txt model.bin
iter  1 act 3.353e-01 pre 3.333e-01 delta 6.715e-01 f 1.386e+00 |g| 1.000e+00 CG   1
iter  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.bin
solver_type L2R_LR
nr_class 2
label 1 2
nr_feature 5
bias 0
w
0.3374141436539016
0
0.3374141436539016
-0.3374141436539016
-0.3374141436539016
0

这是模型的输出:

solver_type L2R_LR
nr_class 2
label 1 2
nr_feature 5
bias 0
w
0.3374141436539016
0
0.3374141436539016
-0.3374141436539016
-0.3374141436539016
0
1 5:10

您将在下面找到我的模型的预测:

> cat test.txt
1 5:1
> predict -b 1 test.txt model.bin test.out
Accuracy = 0% (0/1)
> cat test.out
labels 1 2
2 0.416438 0.583562

这里是我有点惊讶的地方,因为预测只是[0.42, 0.58],因为特征 5 只存在于类 2 中。为什么? 所以我只是尝试将测试文档的特征值从 1 增加到 10:

> cat newtest.txt
1 5:10
> predict -b 1 newtest.txt model.bin newtest.out
Accuracy = 0% (0/1)
> cat newtest.out
labels 1 2
2 0.0331135 0.966887

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

> cat newtrain.txt
1 1:10 2:10 3:10
2 2:10 4:10 5:10
> train -s 0 -c 1 -p 0.1 -e 0.01 -B 0 newtrain.txt newmodel.bin
iter  1 act 1.104e+00 pre 9.804e-01 delta 2.508e-01 f 1.386e+00 |g| 1.000e+01 CG   1
iter  2 act 1.381e-01 pre 1.140e-01 delta 2.508e-01 f 2.826e-01 |g| 2.272e+00 CG   1
iter  3 act 2.627e-02 pre 2.269e-02 delta 2.508e-01 f 1.445e-01 |g| 6.847e-01 CG   1
iter  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.bin
solver_type L2R_LR
nr_class 2
label 1 2
nr_feature 5
bias 0
w
0.19420510395364846
0
0.19420510395364846
-0.19420510395364846
-0.19420510395364846
0
> predict -b 1 newtest.txt newmodel.bin newtest.out
Accuracy = 0% (0/1)
> cat newtest.out
labels 1 2
2 0.125423 0.874577

对于第 2 类的预测仍然可以:0.87

【问题讨论】:

【参考方案1】:

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 paper 的附录 L。

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

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

根本原因是f(x)的值,或者可以简单的看成x到超平面的距离。只有当距离无限大时,才能 100% 确信 x 属于某个类别(参见 prob(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)) 

(eq(3) of LIBLINEAR paper)

在大多数情况下,yi w^T xi 是正数,更大的xi 意味着更小的∑i log(1+exp(−yi w^T xi))。 所以效果有点类似于拥有更小的 C,而更小的 C 意味着更小的 |w|。

另一方面,扩大测试集与拥有较大的|w| 相同。因此,同时扩大训练和测试集的效果基本是

(1). Having smaller |w| when training
(2). Then, having larger |w| when testing

由于 (2) 中的效果比 (1) 中的效果更显着,因此总体而言,扩大训练集和测试集就像拥有更大的 |w|,或者拥有更大的 C。

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

> cat model.bin.m1e12.c1
solver_type L2R_LR
nr_class 2
label 1 2
nr_feature 5
bias 0
w
3.0998430106024949e-12 
0 
3.0998430106024949e-12 
-3.0998430106024949e-12 
-3.0998430106024949e-12 
0 
> cat test.out.m1e12.c1
labels 1 2
2 0.0431137 0.956886

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

> cat model.bin.m1.c1e12
solver_type L2R_LR
nr_class 2
label 1 2
nr_feature 5
bias 0
w
3.0998430101989314 
0 
3.0998430101989314 
-3.0998430101989314 
-3.0998430101989314 
0 
> cat test.out.m1.c1e12
labels 1 2
2 0.0431137 0.956886

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

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

从 (c) 我们知道您的更改就像拥有更大的 C,这将导致更好的训练准确性。但是当 C 太大时,几乎可以肯定该模型是over fitting 训练集。结果,该模型无法承受训练集中的噪声,并且在测试精度上表现不佳。

至于找到一个好的C,一个流行的方法是cross validation(-v选项)。


最后,

这可能是题外话,但你可能想看看如何预处理文本数据。对数据进行实例化标准化是很常见的(例如,liblinear here 的作者建议)。

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

【讨论】:

感谢您的回答。 liblinear-java 中的这种方法会是找到最佳 C 的方法吗? github.com/bwaldvogel/liblinear-java/blob/master/src/main/java/… - 如果是这样,我想知道 nr_folds 是什么 我不熟悉liblinear-java,但是在liblinear或者libsvm中,nr_folds是交叉验证的折叠数。你可以用谷歌搜索 k-folds 交叉验证。

以上是关于是否有原因为啥仅存在于给定类中的特征没有被强烈预测到该类中?的主要内容,如果未能解决你的问题,请参考以下文章

java 接口

java编译 为啥显示找不到文件

概率学习——朴素贝叶斯算法

将类划分为子类会提高图像分类的预测准确性吗?

需要机器学习方法:在给定特征向量中的所有其他特征的情况下预测最可能的特征值

给定一个特征向量,如何找出我的数据点是不是线性可分