【问题标题】:AttributeError: lower not found; using a Pipeline with a CountVectorizer in scikit-learnAttributeError:未找到下限;在 scikit-learn 中使用带有 CountVectorizer 的管道
【发布时间】:2016-02-09 21:52:12
【问题描述】:

我有一个这样的语料库:

X_train = [ ['this is an dummy example'] 
      ['in reality this line is very long']
      ...
      ['here is a last text in the training set']
    ]

还有一些标签:

y_train = [1, 5, ... , 3]

我想按如下方式使用 Pipeline 和 GridSearch:

pipeline = Pipeline([
    ('vect', CountVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('reg', SGDRegressor())
])


parameters = {
    'vect__max_df': (0.5, 0.75, 1.0),
    'tfidf__use_idf': (True, False),
    'reg__alpha': (0.00001, 0.000001),
}

grid_search = GridSearchCV(pipeline, parameters, n_jobs=1, verbose=1)

grid_search.fit(X_train, y_train)

当我运行它时,我收到一条错误消息 AttributeError: lower not found

我搜索并发现了一个关于此错误 here 的问题,这让我相信我的文本没有被标记化(这听起来像是一针见血,因为我使用的是列表列表作为输入数据,其中每个列表包含一个完整的字符串)。

我制作了一个快速而肮脏的标记器来测试这个理论:

def my_tokenizer(X):
    newlist = []
    for alist in X:
        newlist.append(alist[0].split(' '))
    return newlist

它做了它应该做的,但是当我在CountVectorizer的参数中使用它时:

pipeline = Pipeline([
    ('vect', CountVectorizer(tokenizer=my_tokenizer)),

...我仍然得到同样的错误,就好像什么都没发生一样。

我确实注意到我可以通过在我的管道中注释掉 CountVectorizer 来规避错误。这很奇怪......我不认为你可以使用TfidfTransformer() 而不首先有一个数据结构来转换......在这种情况下是计数矩阵。

为什么我总是收到这个错误?实际上,很高兴知道这个错误意味着什么! (是否调用了lower 将文本转换为小写或其他内容?我无法通过阅读堆栈跟踪来判断)。我是在滥用管道......还是这个问题真的是单独 CountVectorizer 的参数的问题?

任何建议将不胜感激。

【问题讨论】:

    标签: python scikit-learn pipeline


    【解决方案1】:

    这是因为您的数据集格式错误,您应该将"An iterable which yields either str, unicode or file objects" 传递给 CountVectorizer 的 fit 函数(或传递给管道,无所谓)。不可迭代其他带有文本的可迭代对象(如您的代码中所示)。在您的情况下 List 是可迭代的,您应该传递其成员是字符串(而不是其他列表)的平面列表。

    即您的数据集应如下所示:

    X_train = ['this is an dummy example',
          'in reality this line is very long',
          ...
          'here is a last text in the training set'
        ]
    

    看这个例子,很有用:Sample pipeline for text feature extraction and evaluation

    【讨论】:

    • 巧合的是,我的代码基于此示例。由于该示例从sklearn.datasets.fetch_20newsgroups 中提取数据,因此尚不清楚该数据的格式(列表?矩阵?)。文档在这个细节上也不是很有帮助。
    • @MattO'Brien 是的,我只能推荐使用 IPython 控制台或 Jupyter 笔记本(或者简单的标准 python 解释器/调试器,如果你不想安装额外的软件),来查看中间结果,对理解这些小细节很有帮助。
    • 我确实使用了 iPython notebook,但只是阅读了示例并出于我自己的目的对其进行了修改。假设输入是列表列表,我实际上并没有在原始示例中执行它。我应该尽职尽责。
    【解决方案2】:

    你可以这样传递数据:

    from sklearn import metrics
    text_clf.fit(list(X_train), list(y_train))
    predicted = text_clf.predict(list(X_test))
    print(metrics.classification_report(list(y_test), predicted))
    

    【讨论】:

      猜你喜欢
      • 2020-05-05
      • 2017-03-24
      • 2017-06-12
      • 2020-11-09
      • 2017-02-25
      • 1970-01-01
      • 2021-03-17
      • 2015-08-14
      • 2020-01-15
      相关资源
      最近更新 更多