如何将新数据转换为我的训练数据的PCA成分?

11

假设我有一些文本句子,想要使用kmeans进行聚类。

sentences = [
    "fix grammatical or spelling errors",
    "clarify meaning without changing it",
    "correct minor mistakes",
    "add related resources or links",
    "always respect the original author"
]

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.cluster import KMeans

vectorizer = CountVectorizer(min_df=1)
X = vectorizer.fit_transform(sentences)
num_clusters = 2
km = KMeans(n_clusters=num_clusters, init='random', n_init=1,verbose=1)
km.fit(X)

现在,我可以预测一个新文本将属于哪个类别。

new_text = "hello world"
vec = vectorizer.transform([new_text])
print km.predict(vec)[0]

然而,假设我应用PCA将10,000个特征降至50个。

from sklearn.decomposition import RandomizedPCA

pca = RandomizedPCA(n_components=50,whiten=True)
X2 = pca.fit_transform(X)
km.fit(X2)

我不能再像以前那样预测新文本的聚类,因为向量化器的结果不再相关。

new_text = "hello world"
vec = vectorizer.transform([new_text]) ##
print km.predict(vec)[0]
ValueError: Incorrect number of features. Got 10000 features, expected 50

那么,我如何将我的新文本转换为较低维度的特征空间?

2个回答

10

在将数据馈送到模型之前,您可以使用pca.transform来处理新的数据。这将使用与在原始数据上运行pca.fit_transform时拟合的相同PCA模型执行降维。然后,您可以使用已拟合的模型对此缩小的数据进行预测。

基本上,将其视为拟合一个大模型,其中包含三个较小的模型。首先有一个CountVectorizer模型确定如何处理数据。接下来运行RandomizedPCA模型执行降维。最后运行KMeans模型进行聚类。在拟合模型时,逐层向下拟合每个模型。当您想要进行预测时,还必须逐层向下应用每个模型。

# Initialize models
vectorizer = CountVectorizer(min_df=1)
pca = RandomizedPCA(n_components=50, whiten=True)
km = KMeans(n_clusters=2, init='random', n_init=1, verbose=1)

# Fit models
X = vectorizer.fit_transform(sentences)
X2 = pca.fit_transform(X)
km.fit(X2)

# Predict with models
X_new = vectorizer.transform(["hello world"])
X2_new = pca.transform(X_new)
km.predict(X2_new)

4

使用 Pipeline

>>> from sklearn.cluster import KMeans
>>> from sklearn.decomposition import RandomizedPCA
>>> from sklearn.decomposition import TruncatedSVD
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> from sklearn.pipeline import make_pipeline
>>> sentences = [
...     "fix grammatical or spelling errors",
...     "clarify meaning without changing it",
...     "correct minor mistakes",
...     "add related resources or links",
...     "always respect the original author"
... ]
>>> vectorizer = CountVectorizer(min_df=1)
>>> svd = TruncatedSVD(n_components=5)
>>> km = KMeans(n_clusters=2, init='random', n_init=1)
>>> pipe = make_pipeline(vectorizer, svd, km)
>>> pipe.fit(sentences)
Pipeline(steps=[('countvectorizer', CountVectorizer(analyzer=u'word', binary=False, decode_error=u'strict',
        dtype=<type 'numpy.int64'>, encoding=u'utf-8', input=u'content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,...n_init=1,
    n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001,
    verbose=1))])
>>> pipe.predict(["hello, world"])
array([0], dtype=int32)

这里展示的是TruncatedSVD,因为在即将发布的版本中,RandomizedPCA 将无法处理文本频率矩阵;而且实际上它执行的是SVD,而不是完整的PCA。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接