This is an automated email from the ASF dual-hosted git repository.

zhengruifeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new e7470b4b41ce [SPARK-58912][ML] Use integer counts in CountVectorizer 
transform
e7470b4b41ce is described below

commit e7470b4b41ce72d6164cbc784b0a459d5deb6851
Author: Ruifeng Zheng <[email protected]>
AuthorDate: Fri Aug 21 08:13:52 2026 +0800

    [SPARK-58912][ML] Use integer counts in CountVectorizer transform
    
    ### What changes were proposed in this pull request?
    
    This PR changes the temporary per-row count map used by 
`CountVectorizerModel.transform` from
    `OpenHashMap[Int, Double]` to `OpenHashMap[Int, Int]`.
    
    The transform path only increments word counts by one while scanning the 
input document. The
    counts are converted to `Double` when constructing the output sparse vector.
    
    ### Why are the changes needed?
    
    Using integer values in the temporary map reduces memory used while 
counting words for each input
    document. The output vector still uses `Double` values, so the external 
behavior is unchanged.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Not run; change is covered by existing `CountVectorizerSuite` transform 
coverage.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Codex (GPT-5)
    
    Closes #58170 from 
zhengruifeng/spark-58912-count-vectorizer-transform-int-counts.
    
    Authored-by: Ruifeng Zheng <[email protected]>
    Signed-off-by: Ruifeng Zheng <[email protected]>
---
 .../org/apache/spark/ml/feature/CountVectorizer.scala    | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git 
a/mllib/src/main/scala/org/apache/spark/ml/feature/CountVectorizer.scala 
b/mllib/src/main/scala/org/apache/spark/ml/feature/CountVectorizer.scala
index 033c53d5afd7..f7d63faeea79 100644
--- a/mllib/src/main/scala/org/apache/spark/ml/feature/CountVectorizer.scala
+++ b/mllib/src/main/scala/org/apache/spark/ml/feature/CountVectorizer.scala
@@ -326,25 +326,23 @@ class CountVectorizerModel(
       broadcastDict = Some(dataset.sparkSession.sparkContext.broadcast(dict))
     }
     val dictBr = broadcastDict.get
-    // SPARK-48837: capture parameter values here so that we only evaulate 
once-per-transform
-    // rather than once-per-row:
-    val minTf = $(minTF)
-    val isBinary = $(binary)
+    val localMinTF = $(minTF)
+    val localBinary = $(binary)
     val vectorizer = udf { document: Seq[String] =>
-      val termCounts = new OpenHashMap[Int, Double]
+      val termCounts = new OpenHashMap[Int, Int]
       var tokenCount = 0L
       document.foreach { term =>
         dictBr.value.get(term) match {
-          case Some(index) => termCounts.changeValue(index, 1.0, _ + 1.0)
+          case Some(index) => termCounts.changeValue(index, 1, _ + 1)
           case None => // ignore terms not in the vocabulary
         }
         tokenCount += 1
       }
-      val effectiveMinTF = if (minTf >= 1.0) minTf else tokenCount * minTf
-      val effectiveCounts = if (isBinary) {
+      val effectiveMinTF = if (localMinTF >= 1.0) localMinTF else tokenCount * 
localMinTF
+      val effectiveCounts = if (localBinary) {
         termCounts.filter(_._2 >= effectiveMinTF).map(p => (p._1, 1.0)).toSeq
       } else {
-        termCounts.filter(_._2 >= effectiveMinTF).toSeq
+        termCounts.filter(_._2 >= effectiveMinTF).map(p => (p._1, 
p._2.toDouble)).toSeq
       }
 
       Vectors.sparse(dictBr.value.size, effectiveCounts)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to