2014-10-03 7 views
5

Załóżmy, że mam kilka zdań tekstowych, które chcę zgrupować za pomocą kmeans.Jak przekonwertować nowe dane na komponenty PCA moich danych treningowych?

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) 

Teraz mogłem przewidzieć, które z klas nowy tekst będzie wpaść,

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

jednak powiedzieć, że stosuje się w celu zmniejszenia PCA 10.000 możliwości do 50.

from sklearn.decomposition import RandomizedPCA 

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

I nie można już zrobić tego samego, aby przewidzieć klaster dla nowego tekstu, ponieważ wyniki wektoryzacji nie są już istotne

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

Jak zatem przekształcić mój nowy tekst w przestrzeń o mniejszych wymiarach?

Odpowiedz

4

Chcesz użyć pca.transform na swoich nowych danych przed wprowadzeniem go do modelu. Spowoduje to zmniejszenie wymiarów przy użyciu tego samego modelu PCA, który został dopasowany po uruchomieniu pca.fit_transform na oryginalnych danych. Następnie możesz użyć dopasowanego modelu, aby przewidzieć te zredukowane dane.

Zasadniczo pomyśl o tym, jak dopasować jeden duży model, który składa się z trzech mniejszych modeli. Najpierw masz model CountVectorizer, który określa sposób przetwarzania danych. Następnie uruchamiasz model RandomizedPCA, który wykonuje redukcję wymiarów. I na koniec uruchamiasz model klastrowania KMeans. Po dopasowaniu modeli idziesz w dół stosu i pasujesz do każdego z nich. A jeśli chcesz przewidzieć, musisz również przejść do stosu i zastosować każdy z nich.

# 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) 
3

Użyj 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) 

(. Pokazuje TruncatedSVD ponieważ RandomizedPCA przestanie działać na macierzach częstotliwości tekst w kolejnej wersji, to faktycznie wykonał SVD, nie jest pełna PCA, w każdym razie)

Powiązane problemy