如何在 sklearn.svm.libsvm.fit() 分类器中包含列表类型特征?
How do I include a list type feature in sklearn.svm.libsvm.fit() classifier?
我正在尝试遍历大量文本文档并通过录制创建一个功能集:
- 位置列表 文本
- 关键短语的词性
- 每个关键词的长度(其中的字数)
- 每个关键词的频率
提取特征的代码片段:
#Take list of Keywords
keyword_list = [line.split(':')[1].lower().strip() for line in keywords.splitlines() if ':' in line ]
#Position
position_list = [ [m.start()/float(len(document)) for m in re.finditer(re.escape(kw),document,flags=re.IGNORECASE)] for kw in keyword_list]
#Part of Speech
pos_list = []
for key in keyword_list:
pos_list.append([pos for w,pos in nltk.pos_tag(nltk.word_tokenize(key))])
#Length of each keyword
len_list = [ len(k.split(' ')) for k in keyword_list]
#Text Frequency
freq_list = [ len(pos)/float(len(document)) for pos in position_list]
target.extend(keyword_list)
for i in range(0,len(keyword_list)):
data.append([position_list[i],pos_list[i],len_list[i],freq_list[i]])
在哪里
- 目标:关键字列表
- 数据:特征列表
我通过分类器传递了这个:
from sklearn.cross_validation import train_test_split
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.25,random_state = 42)
import numpy as np
X_train = np.array(X_train)
y_train = np.array(y_train)
from sklearn import svm
cls = svm.SVC(gamma=0.001,C=100) # Parameter values Matter!
cls.fit(X_train,y_train)
predictions = cls.predict(X_test)
但是我得到一个错误:
Traceback (most recent call last):
File "supervised_3.py", line 113, in <module>
cls.fit(X_train,y_train)
File "/Library/Python/2.7/site-packages/sklearn/svm/base.py", line 150, in fit
X = check_array(X, accept_sparse='csr', dtype=np.float64, order='C')
File "/Library/Python/2.7/site-packages/sklearn/utils/validation.py", line 373, in check_array
array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: setting an array element with a sequence
因此,我通过更改
删除了所有列表项
data.append([position_list[i],pos_list[i],len_list[i],freq_list[i]])
到
data.append([len_list[i],freq_list[i]])
成功了。
但我需要包括 position_list
和 pos_list
我认为它不起作用,因为这 2 个是列表。所以,我尝试将它们转换为数组:
data.append([np.array(position_list[i]),np.array(pos_list[i]),len_list[i],freq_list[i]])
但我仍然得到同样的错误。
在特征提取代码的最后一个 for 循环中,您试图向 data
附加一个包含四个元素的列表,即 position_list[i]
、pos_list[i]
、len_list[i]
, freq_list[i]
。问题是前两个元素本身就是列表,但是 个别特征必须是 escalars (这就是为什么通过将子列表转换为 numpy 数组无法解决问题)。他们每个人都需要不同的解决方法:
position_list[i]
这是一个浮点数列表。您可以用从中计算出的一些统计数据替换此列表,例如平均值和标准差。
pos_list[i]
这是从 nltk.pos_tag
产生的 (token, tag)* 形式的元组列表中提取的标签列表。标签(是字符串)可以通过计算它们的出现次数以直接的方式转换为数字。为了简单起见,我将只添加 'NN'
和 'NNS'
标签的频率 **.
为了让您的代码正常工作,您只需将最后一个 for 循环更改为:
for i in range(0, len(keyword_list)):
positions_i = position_list[i]
tags_i = pos_list[i]
len_tags_i = float(len(tags_i))
m = np.mean(positions_i)
s = np.std(positions_i)
nn = tags_i.count('NN')/len_tags_i
nns = tags_i.count('NNS')/len_tags_i
data.append([m, s, nn, nns, len_list[i], freq_list[i]])
这样,生成的特征向量就变成了 6 维的。不用说,您可以使用更多或更少的统计数据 and/or 标签频率,甚至不同的标签集。
* 您在创建 pos_list
的 for 循环中使用的标识符 w,pos
有点误导。
** 您可以利用 collections.Counter
更有效地计算每个标签的出现次数。
我正在尝试遍历大量文本文档并通过录制创建一个功能集:
- 位置列表 文本
- 关键短语的词性
- 每个关键词的长度(其中的字数)
- 每个关键词的频率
提取特征的代码片段:
#Take list of Keywords
keyword_list = [line.split(':')[1].lower().strip() for line in keywords.splitlines() if ':' in line ]
#Position
position_list = [ [m.start()/float(len(document)) for m in re.finditer(re.escape(kw),document,flags=re.IGNORECASE)] for kw in keyword_list]
#Part of Speech
pos_list = []
for key in keyword_list:
pos_list.append([pos for w,pos in nltk.pos_tag(nltk.word_tokenize(key))])
#Length of each keyword
len_list = [ len(k.split(' ')) for k in keyword_list]
#Text Frequency
freq_list = [ len(pos)/float(len(document)) for pos in position_list]
target.extend(keyword_list)
for i in range(0,len(keyword_list)):
data.append([position_list[i],pos_list[i],len_list[i],freq_list[i]])
在哪里
- 目标:关键字列表
- 数据:特征列表
我通过分类器传递了这个:
from sklearn.cross_validation import train_test_split
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.25,random_state = 42)
import numpy as np
X_train = np.array(X_train)
y_train = np.array(y_train)
from sklearn import svm
cls = svm.SVC(gamma=0.001,C=100) # Parameter values Matter!
cls.fit(X_train,y_train)
predictions = cls.predict(X_test)
但是我得到一个错误:
Traceback (most recent call last):
File "supervised_3.py", line 113, in <module>
cls.fit(X_train,y_train)
File "/Library/Python/2.7/site-packages/sklearn/svm/base.py", line 150, in fit
X = check_array(X, accept_sparse='csr', dtype=np.float64, order='C')
File "/Library/Python/2.7/site-packages/sklearn/utils/validation.py", line 373, in check_array
array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: setting an array element with a sequence
因此,我通过更改
删除了所有列表项data.append([position_list[i],pos_list[i],len_list[i],freq_list[i]])
到
data.append([len_list[i],freq_list[i]])
成功了。
但我需要包括 position_list
和 pos_list
我认为它不起作用,因为这 2 个是列表。所以,我尝试将它们转换为数组:
data.append([np.array(position_list[i]),np.array(pos_list[i]),len_list[i],freq_list[i]])
但我仍然得到同样的错误。
在特征提取代码的最后一个 for 循环中,您试图向 data
附加一个包含四个元素的列表,即 position_list[i]
、pos_list[i]
、len_list[i]
, freq_list[i]
。问题是前两个元素本身就是列表,但是 个别特征必须是 escalars (这就是为什么通过将子列表转换为 numpy 数组无法解决问题)。他们每个人都需要不同的解决方法:
position_list[i]
这是一个浮点数列表。您可以用从中计算出的一些统计数据替换此列表,例如平均值和标准差。pos_list[i]
这是从nltk.pos_tag
产生的 (token, tag)* 形式的元组列表中提取的标签列表。标签(是字符串)可以通过计算它们的出现次数以直接的方式转换为数字。为了简单起见,我将只添加'NN'
和'NNS'
标签的频率 **.
为了让您的代码正常工作,您只需将最后一个 for 循环更改为:
for i in range(0, len(keyword_list)):
positions_i = position_list[i]
tags_i = pos_list[i]
len_tags_i = float(len(tags_i))
m = np.mean(positions_i)
s = np.std(positions_i)
nn = tags_i.count('NN')/len_tags_i
nns = tags_i.count('NNS')/len_tags_i
data.append([m, s, nn, nns, len_list[i], freq_list[i]])
这样,生成的特征向量就变成了 6 维的。不用说,您可以使用更多或更少的统计数据 and/or 标签频率,甚至不同的标签集。
* 您在创建 pos_list
的 for 循环中使用的标识符 w,pos
有点误导。
** 您可以利用 collections.Counter
更有效地计算每个标签的出现次数。