2017-01-26 32 views
1

我使用Sparkit學習的SparkCountVectorizerSparkTfidfVectorizer將一堆文件轉換爲TFIDF矩陣。奇怪的轉置行爲與Sparkit學習

我得到創建TFIDF矩陣和它具有正確的尺寸(496861個文檔由189398級不同的令牌):

>>> tfidf 
<class 'splearn.rdd.SparseRDD'> from PythonRDD[20] at RDD at PythonRDD.scala:48 
>>> tfidf.shape 
(496861, 189398) 

切片的單個載體返回正確的輸出(1個文件由189398級不同的令牌):

>>> tfidf.flatMap(lambda x: x).take(1) 
[<1x189398 sparse matrix of type '<class 'numpy.float64'>' 
     with 49 stored elements in Compressed Sparse Row format>] 

現在,我想每個文檔的轉置(即,由1維189398向量):

>>> tfidf.flatMap(lambda x: x.T).take(1) 

但是,這是我得到什麼,而不是:

[<1x7764 sparse matrix of type '<class 'numpy.float64'>' 
     with 77 stored elements in Compressed Sparse Row format>] 

因此,而不是一個189389x1載體,我得到一個1x7764載體。我瞭解7764:當我讀取數據I .repartition()時,它有64個部分,事實證明,496861(文件數)除以64是7763.4。我不明白的是爲什麼Sparkit-Learn在一種情況下(lambda x: x)和其他情況下的分區(lambda x: x.T)中的扁平行迭代。我完全困惑。

萬一它很重要,我的最終目標是過濾TFIDF矩陣,以便我只在某些列中得到具有非零值的向量(即,只有包含某些詞的文檔)並且索引未轉換的1x189389向量不起作用(無所謂多少[0]我把x後我總是拿回相同的1x189389載體)。

回答

1

您轉置了錯誤的東西。 splearn.rdd.SparseRDD存儲數據塊,因此您將塊轉換爲單個向量。如果塊有7764行和18938列,那麼轉置後的有18938行和7764列,這些列在展平時將逐行迭代。

你需要的是:

(tfidf 
    # Iterate over each block and yield the rows 
    # block-size x 18938 -> 1 x 18938 
    .flatMap(lambda x: x) 
    # Take each row and transpose it 
    # 1 x 18938 -> 1 x 18938 
    .map(lambda x: x.T)) 

(tfidf 
    # Iterate over each row in block (generator expression) 
    # and transpose it block-size x 18938 -> block-size x 18938 x 1 
    # 
    # and then flatten (with flatMap) yielding rows 18938 x 1 
    .flatMap(lambda xs: (x.T for x in xs))) 

注意:我不是真正熟悉Sparkit學習這樣可以有一些更優雅的解決方案在那裏。