对 python 中 libsvm/scikit-learn 库的一些特征建模存在疑问

Some doubts modelling some features for the libsvm/scikit-learn library in python

我搜集了很多像这样的 ebay 标题:

Apple iPhone 5 White 16GB Dual-Core

而且我已经用这种方式手动标记了所有这些

B M C S NA

其中 B=Brand (Apple) M=Model (iPhone 5) C=Color (White) S=Size (Size) NA=Not Assigned (Dual Core)

现在我需要使用 python 中的 libsvm 库训练 SVM 分类器,以学习 ebay 标题中出现的序列模式。

我需要通过将问题视为分类问题来提取该属性(品牌、型号、颜色、尺码)的新值。这样我就可以预测新模型了。

我想表示这些特征以将它们用作 libsvm 库的输入。我在 python 工作:D。

  1. Identity of the current word

我觉得可以这么理解

0 --> Brand
1 --> Model
2 --> Color
3 --> Size 
4 --> NA

如果我知道这个词是一个品牌,我会将该变量设置为 1 (true)。在训练测试中这样做是可以的(因为我已经标记了所有的词)但是我怎么能为测试集做呢?我不知道一个词的类别是什么(这就是我学习它的原因:D)。

  1. N-gram substring features of current word (N=4,5,6)

不知道,这是什么意思?

  1. Identity of 2 words before the current word.

如何为这个特征建模?

考虑到我为第一个特征创建的图例,我有 5^(5) 个组合)

00 10 20 30 40
01 11 21 31 41
02 12 22 32 42
03 13 23 33 43
04 14 24 34 44

如何将其转换为 libsvm(或 scikit-learn)可以理解的格式?

4. Membership to the 4 dictionaries of attributes

我该怎么做呢?有 4 个词典(颜色、尺寸、型号和品牌)我认为我必须创建一个 bool 变量,当且仅当我在 4 个词典之一中匹配当前单词时,我才会将其设置为 true。

  1. Exclusive membership to dictionary of brand names

我认为就像在 4. 功能中一样,我必须使用 bool 变量。你同意吗?

如果这个问题缺少一些信息,请在这个地址阅读我之前的问题:

最后一个疑问:如果我有一个像 iPhone 这样的多标记值 5... 57=] 5} 都是一个品牌??

在测试数据集中 iPhone 和 5 将是 2 个分隔词...那么最好做什么?

在上一个问题中向您提出的解决方案结果不充分(我假设)的原因是该问题的功能很差。

如果我没理解错的话,你要的是:

给定句子 -

Apple iPhone 5 White 16GB Dual-Core

你得到-

B M C S NA

你在这里描述的问题相当于自然语言处理中的part of speech tagging (POS)。

考虑以下英文句子:

We saw the yellow dog

POS 的任务是为每个单词提供适当的标签。在这种情况下:

We(PRP) saw(VBD) the(DT) yellow(JJ) dog(NN)

不要花时间理解这里的英文标签,因为我在这里给出它只是为了告诉你你的问题和 POS 是平等的。

在我解释如何使用 SVM 解决它之前,我想让你了解其他方法:将句子 Apple iPhone 5 White 16GB Dual-Core 视为测试数据。当您标记单词 iPhone 时,您为单词 Apple 设置的标记必须作为标记器的输入提供。但是,将单词标记为单词后,您将不会更改它。因此,进行序列标记的模型通常会收到更好的结果。最简单的示例是隐马尔可夫模型 (HMM)。 Here 是对 POS 中 HMM 的简短介绍。

现在我们将这个问题建模为分类问题。让我们定义什么是 window -

`W-2,W-1,W0,W1,W2`

在这里,我们有一个大小为 2 的 window。在对单词 W0 进行分类时,我们将需要 window(串联)中所有单词的特征。请注意,对于句子的第一个单词,我们将使用:

`START-2,START-1,W0,W1,W2`

为了模拟这是第一个词的事实。对于第二个词,我们有:

`START-1,W-1,W0,W1,W2`

句末的词也是如此。标签START-2START-1STOP1STOP2必须添加到模型二中。

现在,让我们描述一下用于标记 W0 的特征是什么:

Features(W-2),Features(W-1),Features(W0),Features(W1),Features(W2)

token的特征应该是词本身,以及tag(给前一个词的)。我们将使用二进制特征。

示例 - 如何构建特征表示:

第 1 步 - 为每个标记构建单词表示:

让 window 大小为 1。对标记进行分类时,我们使用 W-1,W0,W1。假设你建立了一个字典,并给语料库中的每个单词一个编号:

n['Apple'] = 0
n['iPhone 5'] = 1
n['White'] = 2
n['16GB'] = 3
n['Dual-Core'] = 4
n['START-1'] = 5
n['STOP1'] = 6

第 2 步 - 每个标签的特征标记:

我们为以下标签创建特征:

n['B'] = 7 
n['M'] = 8
n['C'] = 9 
n['S'] = 10 
n['NA'] = 11
n['START-1'] = 12
n['STOP1'] = 13

让我们为 START-1,Apple,iPhone 5 构建一个特征向量:第一个标记是一个具有已知标签的单词(START-1 将始终具有标签 START-1)。所以这个令牌的特点是:

(0,0,0,0,0,0,1,0,0,0,0,0,1,0)

(1的特征:有单词START-1,标签START-1)

对于代币Apple

(1,0,0,0,0,0,0)

请注意,我们对 W0 之前的每个单词都使用了 already-calculated-tags 特征(因为我们已经计算过了)。同样,代币的特征 iPhone 5:

(0,1,0,0,0,0,0)

第 3 步连接所有特征:

通常,1-window 的特征为:

word(W-1),tag(W-1),word(W0),word(W1)

关于您的问题 - 我会再使用一个标记 - number - 这样当您标记单词 5 时(因为您将标题拆分为 space),该功能W0 将在某些数字特征上有 1,在 W-1model 标签中有 1 - 以防先前的标记被正确标记为模型。

总结一下,你应该做什么:

  1. 给数据中的每个单词一个数字
  2. 为列车数据构建特征表示(使用您已经手动计算的标签)
  3. 训练模型
  4. 标注测试数据

最后的说明 - 现有代码的温馨提示:

您可以找到 python here 中实现的词性标注器。它包括对问题和代码的解释,它还执行我刚刚为您描述的特征提取。此外,他们使用 set 来表示每个单词的特征,因此代码更易于阅读。

此标记器收到的数据应如下所示:

Apple_B iPhone_M 5_NUMBER White_C 16GB_S Dual-Core_NA

特征提取是以这种方式进行的(更多信息参见上面的 link):

def get_features(i, word, context, prev):
    '''Map tokens-in-contexts into a feature representation, implemented as a
    set. If the features change, a new model must be trained.'''
    def add(name, *args):
        features.add('+'.join((name,) + tuple(args)))

    features = set()
    add('bias') # This acts sort of like a prior
    add('i suffix', word[-3:])
    add('i-1 tag', prev)
    add('i word', context[i])
    add('i-1 word', context[i-1])
    add('i+1 word', context[i+1])
    return features

对于上面的例子:

context = ["Apple","iPhone","5","White","16GB","Dual-Core"]
prev = "B"
i = 1
word = "iPhone"

一般来说,word 是当前单词的字符串,context 是拆分成列表的标题,prev 是你收到的前一个单词的标签。

我过去使用过这段代码,它运行速度很快,效果很好。 希望它清楚,祝你标签愉快!