scikit-learn中的k-means向量是内部归一化的吗,还是TfidfVectorizer归一化失效?

3 投票
1 回答
2058 浏览
提问于 2025-04-18 09:49

在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标准化的数据向量化:

分类错误率与聚类大小的关系图

误差条表示在进行10次独立运行km.fit(Vectorized)步骤后分类错误的标准差。这两个结果基本相同。聚类的其他指标(ARI分数、AMI分数、NMI分数)也给出了基本相同的结果。

那么,Kmeans内部是否将向量标准化到L2范数为1,还是TfidfVectorizernorm参数没有按预期工作?(我使用的是scikit-learn 0.14.1)

补充:我发现问题可能不在Kmeans上。如果我使用L1标准化约束进行向量化(在TfidfVectorizer中设置norm=u'l1'),聚类错误率从45%增加到大约80%。我改了标题以反映这一点。

1 个回答

2

Kmeans内部是否会把向量归一化到L2范数为1,还是说TfidfVectorizer的norm参数没有按预期工作?

都不是。正如@YS-L在评论中提到的,TfidfVectorizer的默认行为是对它生成的向量进行L2归一化:

norm : 'l1', 'l2' or None, optional
    Norm used to normalize term vectors. None for no normalization.

而且默认值是'l2',所以如果不想进行归一化,可以明确设置norm=None

撰写回答