前两个主成分解释了具有 300 个特征的数据集的 100% 方差

数据挖掘 机器学习 Python nlp 聚类 主成分分析
2022-02-25 15:26:48

我正在尝试使用 PCA 对我的数据集进行一些分析,以便我可以使用 kmeans 有效地对其进行聚类。

我的预处理数据被标记化、过滤(停用词、标点符号等)、POS 标记和词形还原

通过将平均词向量乘以它们的 tfidf 分数,我创建了一个包含大约 120 万个推文向量(每个 300 个特征)的数据集,如下所示:

# trained with same corpus as tfidf
# size=300, epochs=5, and min_count=10
tweet_w2v = Word2Vec.load('./models/tweet2vec_lemmatized_trained.model')

tweet_tfidf = TfidfVectorizer()
with open('./corpus/ttokens_doc_lemmatized.txt', 'r') as infile:
    tweet_tfidf.fit(infile)

tweet_tfidf_dict = dict(zip(tweet_tfidf.get_feature_names(), list(tweet_tfidf.idf_)))

tfidf_tweet_vectors = []

with open('./corpus/ttokens_doc_lemmatized.txt', 'r') as infile:
    for line in infile:
        word_vecs = []
        
        words = line.replace('\n', '').split(' ')
        
        if len(words) == 0:
            continue
            
        for word in words:
            try:
                word_vec = tweet_w2v.wv[word]
                word_weight = tweet_tfidf_dict[word]
                word_vecs.append(word_vec * word_weight)
            except KeyError:
                continue
                
        if len(word_vecs) != 0:
            tweet_vec = np.average(np.array(word_vecs), axis=0)
        else:
            continue
        tfidf_tweet_vectors.append(tweet_vec)

我还尝试了仅使用平均推文向量(无 tfidf)的上述代码,但我的问题最终仍然发生。

我开始认为也许我的数据集不够大,或者我没有正确训练我的 word2vec 模型?我可以使用大约 1 亿条推文,但在过滤掉转推并只获得英语后,大约有 130 万条。

我不确定发生了什么以及下一步应该采取什么步骤。任何解释表示赞赏。

# Load in the data
df = pd.read_csv('./models/tfidf_weighted_tweet_vectors.csv')
df.drop(df.columns[0], axis=1, inplace=True)

# Standardize the data to have a mean of ~0 and a variance of 1
X_std = StandardScaler().fit_transform(df)

# Create a PCA instance: pca
pca = PCA(n_components=20)
principalComponents = pca.fit_transform(X_std)

# Plot the explained variances
features = range(pca.n_components_)
plt.bar(features, pca.explained_variance_ratio_, color='black')
plt.xlabel('PCA features')
plt.ylabel('variance %')
plt.xticks(features)

PCA 特征方差

1个回答

所以问题是问为什么编码文本数据的前两个主要成分封装了数据中的所有变化。

一个潜在的问题可能是词向量的平均。

假设对于特定帖子的词向量中的特定特征f,可能存在正值和负值数组。当我们然后应用平均值时,f我们可以将维度归零,从而导致更大的数据稀疏性,这可以解释您所看到的(无论您是否将此平均值与 td-idf 相乘,这个零值都会存在)。这种情况可能是在您的文本嵌入/特征向量中的多个维度上发生的。

有了这个,你可能需要考虑另一种派生文本嵌入的方法,可能使用Doc2Vec代替,它遵循与 Word2Vec 相同的原则,但改为派生文档嵌入,它封装了一段文本的含义而不是词嵌入,它将单个单词的含义封装在一段文本中。