Scala 如何使用Spark为文本分类创建TF-IDF?
我有一个CSV文件,格式如下:Scala 如何使用Spark为文本分类创建TF-IDF?,scala,apache-spark,apache-spark-mllib,tf-idf,Scala,Apache Spark,Apache Spark Mllib,Tf Idf,我有一个CSV文件,格式如下: product_id1,product_title1 product_id2,product_title2 product_id3,product_title3 product_id4,product_title4 product_id5,product_title5 [...] 乘积_idX是整数,乘积_titleX是字符串,例如: 453478692, Apple iPhone 4 8Go 我正试图从我的文件中创建TF-IDF,以便在MLlib中将其用于朴
product_id1,product_title1
product_id2,product_title2
product_id3,product_title3
product_id4,product_title4
product_id5,product_title5
[...]
乘积_idX是整数,乘积_titleX是字符串,例如:
453478692, Apple iPhone 4 8Go
我正试图从我的文件中创建TF-IDF,以便在MLlib中将其用于朴素贝叶斯分类器
到目前为止,我正在使用Spark for Scala,并使用我在官方页面和Berkley AmpCamp上找到的教程
所以我在读文件:
val file = sc.textFile("offers.csv")
然后我将它映射到元组RDD[Array[String]]
val tuples = file.map(line => line.split(",")).cache
在我将元组转换成成对之后RDD[(Int,String)]
但我被困在这里,我不知道如何从中创建向量,将其转换为TFIDF
感谢我自己(使用pyspark)这样做,我首先从语料库中创建两个数据结构开始。第一个是关键的价值结构
document_id, [token_ids]
第二种是倒排索引,类似
token_id, [document_ids]
我将分别称之为语料库和inv_索引
为了获得tf,我们需要计算每个文档中每个令牌的出现次数。所以
从集合导入计数器
每行定义wc_(行):
cnt=计数器()
对于第行中的单词:
cnt[word]+=1
返回cnt.items()
tf=corpus.map(lambda(x,y):(x,wc_每行(y)))
df只是每个术语的倒排索引的长度。由此我们可以计算出idf
df=inv_index.map(λ(x,y):(x,len(y)))
num_documnents=tf.count()
#在此步骤中,您还可以应用一些过滤器,以确保
#仅限df“良好”范围内的术语。
导入math.log10
idf=df.map(lambda(k,v):(k,1.+log10(num_documents/v)).collect()
现在,我们只需对术语_id进行连接:
def calc_tfidf(tf_元组,idf_元组):
返回[(k1,v1*v2)for(k1,v1)的tf_元组for
(k2,v2)在idf_元组中,如果k1==k2]
tfidf=tf.map(lambda(k,v):(k,calc_tfidf(v,idf)))
不过,这并不是一个特别有效的解决方案。调用collect将idf引入驱动程序程序,使其可供加入看起来是错误的
当然,它需要首先标记化并创建从词汇表中的每个uniq标记到某个标记id的映射
如果有人能在这方面有所改进,我很感兴趣 如果我能很好地理解您的问题,每个产品都可以出现多次。每个产品的发生次数是您的频率(TF),我无法理解在您的情况下,IDF是什么。你能详细说明一下吗?tf–idf,术语频率的缩写–反向文档频率,是一种数字统计,旨在反映一个词对集合或语料库中的文档有多重要。在信息检索和文本挖掘中,它经常被用作权重因子。我不明白的是,在您的示例中,我没有提到集合或语料库。我最后的评论是tf idf的定义,集合或语料库是一组您希望使用数据挖掘技术的文档。在我的例子中,我们认为CSV线是一个文档,收集或语料库是包含这些文档的CSV文件。抱歉,但我仍然没有得到。我的理解是:您需要每个产品的TF-IDF。每条生产线有一种产品。您可以多次使用同一产品。知道,根据您最后的评论,一种产品的IDF将与包含该产品的行数成反比。在这种情况下,TF将是什么?
token_id, [document_ids]