我有一个NLP任务(文本分类)。我提取了一些这样的双字母:
training_data = [[('this', 'is'), ('is', 'a'), ('a', 'text')],
[('and', 'one'), ('one', 'more')]]
然后我可以使用这样的矢量化器:
from sklearn.feature_extraction import FeatureHasher
fh = 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 svm
s = svm.SVC()
lables = [HAM, SPAM]
s.fit(training_data, labels)
我如何使用上面的brigam中的标签(即training_data
)来分类?,例如:
data = [[('this', 'is'), ('is', 'a'), ('a', 'text'), 'SPAM'],
[('and', 'one'), ('one', 'more'), 'HAM']]
答案 0 :(得分:3)
在上面的代码中,假设我们有一个名为doc
的特征向量,如果你写:
result = s.predict (doc)
result
应为“0”或“1”。所以预测结果是数字的。因此,最好相应地分配标签。但是,如果您仍想分配字符串标签,则可以假设例如标签'a'等于'1'而'b'等于'0'。我知道,与scikit
中的nltk
不同,默认情况下标签是字符串,但有什么区别吗?
编辑1:我可以从您的第一次编辑中看到您可能对特征向量及其标签存在误解。首先,您指定的标签类型不会影响结果,这意味着如果您将类标签指定为垃圾邮件而将其分配为非垃圾邮件,则分类器不会自动检测垃圾邮件和非垃圾邮件;分类取决于您的特征向量,然后为了比较,一个类标签。所以如果你说,我会假设在我的代码中0代表一个垃圾邮件,1代表一个HAM,你会相应地标记你的数据,它的工作原理和足够的。第二个问题是,我不确定你是否知道一个二元组特征向量应该是什么样子,因为你通过编写波纹管代码来表示你的数据:
data = [[('this', 'is'), ('is', 'a'), ('a', 'text'), 'SPAM'],
[('and', 'one'), ('one', 'more'), 'HAM']]
bigram特征向量应包含数据集中存在的所有可能特征,然后为了表示每个文档,您必须为该文档中的所有特征分配1,其余为0。举个例子,我将以正确的形式重写上面的例子:
Features: 'this is' 'is a' 'a text' 'and one' 'one more' Label
doc 1: 1 1 1 0 0 SPAM (or as I explained 0)
doc 2: 0 0 0 1 1 HAM (or as I explained 1)
现在,我们可以用以下形式编写上述文件的特征向量:
data = [([1,1,1,0,0),(0)],[(0,0,0,1,1),(1)]]
请注意,第一个文档的标签是0(或SPAM),第二个文档的标签是1(或HAM)。我试图做一个非常明确的例子。使用scikit时,您可能更喜欢使用numpy数组而不是list。但我的例子很清楚。阅读这个问题here关于bigrams以及我的回答可能会对你有所帮助。如果您有其他问题,请告诉我,但请尝试考虑上述示例。
编辑2:以防万一您想知道如何在代码中的变量labels
中编写标签:对于每个文档(转换为特征向量表示),您必须有一个相应的标签。在代码数组X
中包含要素向量,因此在labels
中,您必须在数组中具有与每个要素向量对应的X
相同位置的标注。因此,假设您有100个文档(50个SPAM或0和50个HAM或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()中你可以使用后者,但是,请确保你的特征向量也是中间的并且对应于正确的标签。