如何在sklearn.svm.libsvm.fit()分类器中包含列表类型功能?

时间:2016-07-30 05:32:19

标签: python-2.7 machine-learning scikit-learn svm

我试图循环浏览大量文本文档并通过录制创建功能集:

    文字
  • 职位列表
  • 关键词
  • 的词性 每个关键短语的
  • 长度(其中的字数)
  • 每个关键短语的
  • 频率

附加功能的代码段:

#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_listpos_list

我认为它不起作用,因为这两个是列表。所以,我尝试将它们转换为数组:

data.append([np.array(position_list[i]),np.array(pos_list[i]),len_list[i],freq_list[i]])

但我仍然得到同样的错误。

1 个答案:

答案 0 :(得分:0)

在功能提取代码的最后一个for循环中,您尝试向data附加四个元素的列表,即position_list[i]pos_list[i]len_list[i],{ {1}}。问题是前两个元素本身就是列表,但个别特征必须是escalars (这就是为什么通过将子列表转换为numpy数组不能解决问题的原因)。每个都需要不同的解决方法:

  1. freq_list[i]
    这是一个浮点数列表。您可以通过从中计算的一些统计数据替换此列表,例如平均值和标准差。
  2. position_list[i]
    这是从pos_list[i]产生的表单(标记,标记) * 的元组列表中提取的标记列表。标签(字符串)可以通过计算出现次数以直接的方式转换为数字。为简单起见,我只会添加nltk.pos_tag'NN'标记 ** 的频率。
  3. 要使代码正常工作,您只需将最后一个for循环更改为:

    'NNS'

    通过这样做,得到的特征向量变为6维。毋庸置疑,您可以使用更多或更少数量的统计数据和/或标记频率,甚至使用不同的标记集。

    * 您在创建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]]) 的for循环中使用的标识符w,pos有点误导。

    ** 您可以利用collections.Counter更有效地计算每个标签的出现次数。