我有一个自然语言处理任务(文本分类)。我提取了一些二元组,如下所示:
training_data = [[('this', 'is'), ('is', 'a'), ('a', 'text')], [('and', 'one'), ('one', 'more')]]
然后我可以使用如下所示的向量化器:
from sklearn.feature_extraction import FeatureHasherfh = FeatureHasher(input_type='string')X = fh.transform(((' '.join(x) for x in sample) for sample in training_data))print X.toarray()[[ 0. 0. 0. ..., 0. 0. 0.] [ 0. 0. 0. ..., 0. 0. 0.]]
这是如何使用svm算法进行分类的示例:
from sklearn import svms = svm.SVC()lables = [HAM, SPAM] s.fit(training_data, labels)
如何在上述二元组(即training_data
)中使用标签进行分类?例如:
data = [[('this', 'is'), ('is', 'a'), ('a', 'text'), 'SPAM'], [('and', 'one'), ('one', 'more'), 'HAM']]
回答:
在上面的代码中,假设我们有一个名为doc
的特征向量,如果你写:
result = s.predict (doc)
result
应该为’0’或’1’。因此,预测结果是数值的。因此,最好相应地分配标签。然而,如果你仍然想分配一个字符串标签,那么你可以假设例如标签’a’相当于’1’,’b’相当于’0’。我知道与scikit
不同,nltk
中的标签默认是字符串,但有什么区别吗?
编辑1: 从你的第一次编辑中,我可以看出你可能对特征向量及其标签存在误解。首先,你分配的标签类型不会影响结果,这意味着如果你将一个类别标签标记为垃圾邮件,另一个标记为非垃圾邮件,分类器不会自动检测垃圾邮件和非垃圾邮件;分类取决于你的特征向量,然后为了比较的目的使用一个类别标签。所以如果你说,我会假设在我的代码中0代表垃圾邮件,1代表非垃圾邮件,并且你会相应地标记你的数据,这样做是有效的,足够了。第二个问题是我不确定你是否知道二元特征向量应该是什么样子,因为你表示数据的方式如下所示:
data = [[('this', 'is'), ('is', 'a'), ('a', 'text'), 'SPAM'], [('and', 'one'), ('one', 'more'), 'HAM']]
二元特征向量应该包含数据集中存在的所有可能特征,然后为了表示每个文档,你必须对该文档中存在的每个特征分配1,对其余的分配0。作为一个例子,我将以上示例重写为正确形式:
特征: 'this is' 'is a' 'a text' 'and one' 'one more' 标签文档1: 1 1 1 0 0 垃圾邮件(或如我所解释的0)文档2: 0 0 0 1 1 非垃圾邮件(或如我所解释的1)
现在,我们可以将上述文档的特征向量写成以下形式:
data = [([1,1,1,0,0),(0)],[(0,0,0,1,1),(1)]]
请注意,第一个文档的标签是0(或垃圾邮件),第二个文档的标签是1(或非垃圾邮件)。我试图做一个非常清晰的例子。使用scikit时,你可能更喜欢使用numpy数组而不是列表。但我的例子是清晰的。阅读这里关于二元组的问题以及我的回答可能会对你有帮助。如果你有进一步的问题,请告诉我,但请尝试思考上面的例子。
编辑2: 万一你想知道如何在你的代码中的labels
变量中写入标签:对于每个文档(转换为特征向量表示),你必须有一个相应的标签。在你的代码中,数组X
包含特征向量,因此在labels
中,你必须有与X
中每个特征向量对应的相同位置的标签。因此,假设你有100个文档(50个垃圾邮件或0和50个非垃圾邮件或1),你的标签应该如下所示:
labels = [0,0,0,0,0,0,0,0,...,1,1,1,1,1,1,1,...]
但这取决于你如何排序你的数据。一些分类器会接受如上的标签,而一些会接受交错的0和1,例如:
labels = [0,1,0,1,0,1, ...]
在svm.SVC()中你可以使用后者,但是,请确保你的特征向量也是交错的,并且对应正确的标签。