我对进行一些文档聚类感兴趣,现在我正在考虑使用 TF-IDF 来实现此目的。
如果我没记错的话,TF-IDF 特别用于评估给定查询的文档的相关性。如果我没有特定的查询,如何将 tf-idf 应用于聚类?
language-agnostic algorithm text-processing information-retrieval tf-idf
我正在尝试找出一组政府文件中的重要术语。生成术语频率没有问题。
对于文档频率,我希望使用Peter Norvig 在“美丽数据”一章中发布的方便的 Python 脚本和随附数据,其中包括来自 Web 的庞大数据语料库中一元语法的频率。
然而,我对 tf-idf 的理解是,“文档频率”是指包含某个术语的文档数量,而不是该术语的总单词数,这是我们从 Norvig 脚本中得到的。我仍然可以使用这些数据进行粗略的 tf-idf 操作吗?
这是一些示例数据:
word tf global frequency
china 1684 0.000121447
the 352385 0.022573582
economy 6602 0.0000451130774123
and 160794 0.012681757
iran 2779 0.0000231482902018
romney 1159 0.000000678497795593
Run Code Online (Sandbox Code Playgroud)
简单地用 tf 除以 gf 会得到“the”比“economy”更高的分数,这是不对的。也许我缺少一些基本的数学知识?
假设我有一个用户搜索查询,如下所示:
"the happy bunny"
我已经计算了 tf-idf 并为我正在搜索的每个文档提供了类似的内容(以下是示例值)(当然 idf 始终相同):
tf idf score
the 0.06 1 0.06 * 1 = 0.06
happy 0.002 20 0.002 * 20 = 0.04
bunny 0.0005 60 0.0005 * 60 = 0.03
Run Code Online (Sandbox Code Playgroud)
我有两个问题关于下一步该怎么做。
首先,the仍然具有最高分数,尽管 idf 根据稀有性进行了调整,但它仍然不是很重要 - 您认为我应该idf根据稀有词对值进行平方权重,还是会产生不好的结果?否则,我担心 与和the同等重要,而且很明显,它是搜索中最重要的词。只要稀有总是等于重要,那么根据稀有程度进行加权总是一个好主意,但如果情况并非总是如此,那么这样做可能真的会弄乱结果。happybunnybunny
其次,更重要的是:将每个单词的分数组合在一起以给每个文档一个表示其反映整个搜索查询的程度的单个分数的最佳/首选方法是什么?我正在考虑添加它们,但很明显,这将为包含 10,000happy但仅 1的文档提供更高的优先级bunny,而不是另一个包含500happy 和 500 的文档bunny(这将是更好的匹配)。
我正在尝试破译 elasticsearch 响应中的解释 API。但是有点失落。对我来说有点难以遵循。任何简单的指针或链接将更具体地解释 JSON?我对 VSM 中的 TF、IDF 和余弦相似度有所了解。但更具体地需要一些关于 JSON 的指针。理想的情况是,如果我能找到对这个 JSON 的解释作为一个简单的数学表达式。
{
"_explanation": {
"value": 7.937373,
"description": "sum of:",
"details": [
{
"value": 2.4789724,
"description": "weight(FirstName:M80806 in 35) [PerFieldSimilarity], result of:",
"details": [
{
"value": 2.4789724,
"description": "score(doc=35,freq=1.0), product of:",
"details": [
{
"value": 0.37350902,
"description": "queryWeight, product of:",
"details": [
{
"value": 6.6369815,
"description": "idf(docFreq=720, maxDocs=202323)"
},
{
"value": 0.056276944,
"description": "queryNorm"
}
]
},
{
"value": 6.6369815,
"description": "fieldWeight in 35, product of:",
"details": [
{ …Run Code Online (Sandbox Code Playgroud) 我正在处理十万(100,000)份文件(平均文件长度约为 500 个术语)。对于每个文档,我想通过余弦相似度获得前 k 个(例如 k = 5)个相似文档。那么如何通过Python有效地做到这一点。
这是我所做的:
我在 i5-2.5GHz 上运行我的代码,12 小时过去了,但它仍然有效。所以我想知道如何优化我的代码或程序。
这是我的想法:
那么,你有什么好主意吗?
非常感谢。
我知道有一个类似的问题,但这不是我想要的。
感谢 @orange ,经过分析,我发现第 2 步是瓶颈!这是示例代码:
def construct_dt_matrix():
dt_matrix = pd.DataFrame(columns=['docid'])
docid = 0
for f in files:
# text segmentation for f
# remove stop words
# word count store …Run Code Online (Sandbox Code Playgroud) 我正在尝试对存储在格式键中的推文进行聚类,listofwords
我的第一步是使用数据框提取单词列表的 TF-IDF 值
dbURL = "hdfs://pathtodir"
file = sc.textFile(dbURL)
#Define data frame schema
fields = [StructField('key',StringType(),False),StructField('content',StringType(),False)]
schema = StructType(fields)
#Data in format <key>,<listofwords>
file_temp = file.map(lambda l : l.split(","))
file_df = sqlContext.createDataFrame(file_temp, schema)
#Extract TF-IDF From https://spark.apache.org/docs/1.5.2/ml-features.html
tokenizer = Tokenizer(inputCol='content', outputCol='words')
wordsData = tokenizer.transform(file_df)
hashingTF = HashingTF(inputCol='words',outputCol='rawFeatures',numFeatures=1000)
featurizedData = hashingTF.transform(wordsData)
idf = IDF(inputCol='rawFeatures',outputCol='features')
idfModel = idf.fit(featurizedData)
rescaled_data = idfModel.transform(featurizedData)
Run Code Online (Sandbox Code Playgroud)
根据在 spark 中为 LDA 准备数据的建议,我尝试将输出重新格式化为我期望作为 LDA 输入的内容,基于此示例,我开始时:
indexer = StringIndexer(inputCol='key',outputCol='KeyIndex')
indexed_data = indexer.fit(rescaled_data).transform(rescaled_data).drop('key').drop('content').drop('words').drop('rawFeatures')
Run Code Online (Sandbox Code Playgroud)
但是现在我没有设法找到一种好方法将我的数据帧转换为上一个示例或本示例中建议的格式 …
我有大约 2-3 百万种产品。每个产品都遵循这个结构
{
"sku": "Unique ID of Product ( String of 20 chars )"
"title":"Title of product eg Oneplus 5 - 6GB + 64GB ",
"brand":"Brand of product eg OnePlus",
"cat1":"First Category of Product Phone",
"cat2":"Second Category of Product Mobile Phones",
"cat3":"Third Category of Product Smart Phones",
"price":500.00,
"shortDescription":"Short description about the product ( Around 8 - 10 Lines )",
"longDescription":"Long description about the product ( Aroung 50 - 60 Lines )"
}
Run Code Online (Sandbox Code Playgroud)
问题陈述是
仅根据内容或产品数据查找类似产品。所以当电子商务用户点击一个产品(SKU)时,我会在推荐中展示与该SKU或产品相似的产品。
比如用户点击apple iphone 6s …
我正在使用 Gensim 进行向量空间模型。从 Gensim 创建字典和语料库后,我使用以下行计算了(术语频率*逆文档频率)TFIDF
Term_IDF = TfidfModel(corpus)
corpus_tfidf = Term_IDF[corpus]
Run Code Online (Sandbox Code Playgroud)
corpus_tfidf 包含具有术语 ID 和相应 TFIDF 的列表的列表。然后我使用以下几行将 TFIDF 与 id 分开:
for doc in corpus_tfidf:
for ids,tfidf in doc:
IDS.append(ids)
tfidfmtx.append(tfidf)
IDS=[]
Run Code Online (Sandbox Code Playgroud)
现在我想使用 k-means 聚类,所以我想执行 tfidf 矩阵的余弦相似性问题是 Gensim 不产生方阵,所以当我运行以下行时,它会产生错误。我想知道如何从 Gensim 获取方阵来计算向量空间模型中所有文档的相似性。还有如何将 tfidf 矩阵(在这种情况下是列表列表)转换为 2D NumPy 数组。任何评论都非常感谢。
dumydist = 1 - cosine_similarity(tfidfmtx)
ML.NET 的文档展示了如何使用context.Transforms.Text.ProduceWordBags获取词袋。该方法将Transforms.Text.NgramExtractingEstimator.WeightingCriteria作为参数之一,因此可以请求使用TfIdf权重。最简单的例子是:
// Get a small dataset as an IEnumerable and then read it as a ML.NET data set.
IEnumerable<SamplesUtils.DatasetUtils.SampleTopicsData> data = SamplesUtils.DatasetUtils.GetTopicsData();
var trainData = ml.Data.LoadFromEnumerable(data);
var pipeline = ml.Transforms.Text.ProduceWordBags("bags", review, ngramLength: 1, weighting: Transforms.Text.NgramExtractingEstimator.WeightingCriteria.TfIdf);
var transformer = pipeline.Fit(trainData);
var transformed_data = transformer.Transform(trainData);
Run Code Online (Sandbox Code Playgroud)
一切都很好,但我如何得到实际结果transformed_data呢?
我在调试器中做了一些挖掘,但我仍然对这里实际发生的事情感到困惑。
首先,运行管道会添加三个额外的列transformed_data:
预览数据后,我可以看到这些列中的内容。为了让事情更清楚,这里是GetTopicsData返回的内容,这就是我们运行转换的内容:
animals birds cats dogs fish horse
horse birds house fish duck cats
car truck driver bus pickup
car truck driver …Run Code Online (Sandbox Code Playgroud) 我想使用TFIDFVectorizer(或CountVectorizer后跟TFIDFTransformer)来获得我的术语的向量表示。这意味着,我想要一个术语的向量,其中文档是特征。这只是由 TFIDFVectorizer 创建的 TF-IDF 矩阵的转置。
>>> vectorizer = TfidfVectorizer()
>>> model = vectorizer.fit_transform(corpus)
>>> model.transpose()
Run Code Online (Sandbox Code Playgroud)
但是,我有 800k 个文档,这意味着我的术语向量非常稀疏且非常大(800k 维)。max_featuresCountVectorizer 中的标志将完全符合我的要求。我可以指定一个维度,而 CountVectorizer 会尝试将所有信息放入该维度。不幸的是,这个选项是针对文档向量而不是词汇表中的术语。因此,它减少了我的词汇量,因为术语就是特征。
有什么办法可以做相反的事情吗?比如,在 TFIDFVectorizer 对象开始切割和规范化所有内容之前对其执行转置?如果存在这种方法,我该怎么做?像这样的东西:
>>> countVectorizer = CountVectorizer(input='filename', max_features=300, transpose=True)
Run Code Online (Sandbox Code Playgroud)
我一直在寻找这种方法,但每个指南、代码示例,无论是在谈论文档 TF-IDF 向量而不是术语向量。非常感谢您!
tf-idf ×10
python ×3
algorithm ×2
apache-spark ×1
c# ×1
corpus ×1
gensim ×1
k-means ×1
lda ×1
lucene ×1
ml.net ×1
nlp ×1
numpy ×1
predictionio ×1
pyspark ×1
scikit-learn ×1
search ×1
similarity ×1
svd ×1