Sklearn Pipeline:如何构建kmeans,聚类文本?
Posted
技术标签:
【中文标题】Sklearn Pipeline:如何构建kmeans,聚类文本?【英文标题】:Sklearn Pipeline: How to build for kmeans, clustering text? 【发布时间】:2015-01-10 06:09:32 【问题描述】:我有如图所示的文字:
list1 = ["My name is xyz", "My name is pqr", "I work in abc"]
以上将是使用 kmeans 对文本进行聚类的训练集。
list2 = ["My name is xyz", "I work in abc"]
以上是我的测试集。
我已经建立了一个矢量化器和模型如下所示:
vectorizer = TfidfVectorizer(min_df = 0, max_df=0.5, stop_words = "english", charset_error = "ignore", ngram_range = (1,3))
vectorized = vectorizer.fit_transform(list1)
km=KMeans(n_clusters=2, init='k-means++', n_init=10, max_iter=1000, tol=0.0001, precompute_distances=True, verbose=0, random_state=None, copy_x=True, n_jobs=1)
km.fit(vectorized)
如果我尝试为我的“list2”测试集预测集群:
km.predict(list2)
我收到以下错误:
ValueError: Incorrect number of features. Got 2 features, expected 5
有人告诉我使用Pipeline
来解决这个问题。所以我写了下面的代码:
pipe = Pipeline([('vect', vectorizer), ('vectorized', vectorized), ('kmeans',km )])
但我得到了错误:
TypeError Traceback (most recent call last)
/mnt/folder/Text_Mining/<ipython-input-14-321cabc3bf35> in <module>()
----> 1 pipe = Pipeline([('vect', vectorizer), ('vectorized', vectorized), ('kmeans',km )])
/usr/local/lib/python2.7/dist-packages/scikit_learn-0.13-py2.7-linux-x86_64.egg/sklearn/pipeline.pyc in __init__(self, steps)
87 raise TypeError("All intermediate steps a the chain should "
88 "be transforms and implement fit and transform"
---> 89 "'%s' (type %s) doesn't)" % (t, type(t)))
90
91 if not hasattr(estimator, "fit"):
TypeError: All intermediate steps a the chain should be transforms and implement fit and transform' (0, 2) 1.0
(1, 4) 0.57735026919
(1, 3) 0.57735026919
(1, 1) 0.57735026919
(2, 0) 1.0' (type <class 'scipy.sparse.csr.csr_matrix'>) doesn't)
我认为vectorized
的输出可能没有实现拟合和转换,但在这种特殊情况下我该怎么做呢?我是机器学习的新手。
另外,如何从 kmeans 模型中获取标签?当我运行 kmeans 时,我可以使用 km.labels_
访问集群标签。如何在 Pipeline 中做类似的事情?
【问题讨论】:
('vectorized', vectorized)
部分不是管道的有效部分。在管道中,您只需要具有fit
的对象以及除最后一个transform
方法之外的所有对象。你不要像你所做的那样在成分上调用fit
,你应该在pipe
上调用它:pipe.fit(list1)
【参考方案1】:
您需要做的是使用list1
训练vectorizer
,然后使用相同的vectorizer、transform
list1
和list2
。这将解决问题。演示:
>>> list1 = ["My name is xyz", "My name is pqr", "I work in abc"]
>>> list2 = ["My name is xyz", "I work in abc"]
>>> vectorizer = TfidfVectorizer(min_df = 0, max_df=0.5, stop_words = "english", charset_error = "ignore", ngram_range = (1,3))
>>> vec=vectorizer.fit(list1) # train vec using list1
>>> vectorized = vec.transform(list1) # transform list1 using vec
>>> km=KMeans(n_clusters=2, init='k-means++', n_init=10, max_iter=1000, tol=0.0001, precompute_distances=True, verbose=0, random_state=None, cpy_x=True, n_jobs=1)
>>> km.fit(vectorized)
>>> list2Vec=vec.transform(list2) # transform list2 using vec
>>> km.predict(list2Vec)
array([0, 0], dtype=int32)
【讨论】:
我仍然希望通过 Pipeline 实现这一点。这不是更容易(单线过程)通过相同的步骤运行新数据,例如用于预测,并且更容易根据需要在中间添加新步骤? @nealmcb 我也是!所以……见下文。 :-)【参考方案2】:你很亲密!跳过中间显式的vectorizer.fit()
步骤,并在管道中完成所有操作:
list1 = ["My name is xyz", "My name is pqr", "I work in abc"]
list2 = ["My name is xyz", "I work in abc"]
vectorizer = TfidfVectorizer(min_df = 0, max_df=0.5, stop_words = "english", ngram_range = (1,3))
km = KMeans(n_clusters=2, init='k-means++', n_init=10, max_iter=1000, tol=0.0001, precompute_distances=True, verbose=0, random_state=None, copy_x=True, n_jobs=1)
pipe = Pipeline([('vect', vectorizer), ('kmeans', km)])
pipe.fit(list1)
pipe.transform(list2)
结果:
注意:调整了几个参数,使其可以在我当前版本的 sklearn (0.22.1) 上运行...已经有几年了 :-)数组([[0.70710678, 1.41421356], [0.70710678, 1.41421356]])
【讨论】:
谢谢你!我必须用最新的 sklearn 重新审视这个。对我来说也有一段时间了! :-)以上是关于Sklearn Pipeline:如何构建kmeans,聚类文本?的主要内容,如果未能解决你的问题,请参考以下文章
将 Sklearn GridSearchCV 与 Pipeline 一起使用时如何传递权重
如何将 SHAP 与 sklearn 中的线性 SVC 模型一起使用 Pipeline?
如何使用 GridSearchCV 和 sklearn Pipeline 用训练数据的估算值估算测试数据