【问题标题】:How do I convert new data into the PCA components of my training data?如何将新数据转换为训练数据的 PCA 组件?
【发布时间】:2014-11-28 17:04:46
【问题描述】:

假设我有一些要使用 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

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

【问题讨论】:

    标签: python machine-learning scikit-learn pca


    【解决方案1】:

    使用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。)

    【讨论】:

      【解决方案2】:

      您想在将新数据输入模型之前对新数据使用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)
      

      【讨论】:

        猜你喜欢
        • 2021-07-30
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-16
        • 2014-11-03
        相关资源
        最近更新 更多