【发布时间】:2014-08-05 04:28:27
【问题描述】:
scikit-learn Kmeans 中的向量是否在内部标准化为单元 L2 范数或者 TfidfVectorizer 有什么问题?我对文本数据执行聚类,并使用 TF-IDF 矢量化器对其进行矢量化。代码太长,无法在此处复制,但本质上我对来自 20 个新闻组数据集的数据进行了矢量化和聚类。我将矢量化器实例化为(未标准化):
VectorizerUn = TfidfVectorizer(min_df=10,
max_df=0.5,
stop_words='english',
decode_error='ignore')
或作为(L2-标准化):
VectorizerL2 = TfidfVectorizer(min_df=10,
max_df=0.5,
stop_words='english',
decode_error='ignore',
norm=u'l2')
我实例化 k 意味着使用:
km = KMeans(n_clusters=num_clusters, init='random', n_init=1, verbose=0)
然后我继续拆分数据以进行交叉验证、矢量化并拟合训练数据集(矢量化器中的 X 下方代表“Un”或“L2”)
Vectorized = VectorizerX.fit_transform(TrainData.data)
km.fit(Vectorized)
并将数据分配给训练集中消息的集群
new_msg_vec = VectorizerX.transform([new_msg])
predicted_clust = km_clust.predict(new_msg_vec)[0]
new_msg 贯穿训练数据中的消息。然后我根据20个新闻组中消息的已知组标签将簇分配到组(每个簇属于其内容大部分的组),并使用测试数据来表征聚类/分类方案的性能。以下是未进行归一化和 L2 归一化的向量化数据的分类错误性能与聚类数的关系图:
误差条是km.fit(Vectorized) 步骤独立运行 10 次后分类误差的标准差。两个结果基本一致。聚类的其他指标(ARI 分数、AMI 分数、NMI 分数)基本上给出了相同的图景。
那么,Kmeans 是在内部将向量归一化为 L2 范数 1,还是 TfidfVectorizer norm 参数没有做它应该做的事情? (我使用的是 scikit-learn 0.14.1)
编辑:我发现问题可能与 Kmeans 无关。如果我使用 L1 归一化约束进行矢量化(在 TfidfVectorizer 中设置 norm=u'l1'),聚类误差会从 45% 增加到大约 80%。我更改了标题以反映这一点。
【问题讨论】:
-
看来
norm参数的默认值是'l2'而不是None(source),即VectorizerUn应该初始化为norm=None。
标签: python scikit-learn k-means tf-idf