如何在Lenskit 3.0中配置Crossfold生成仅含关联项且剔除热门项的测试集
1. Configuring Crossfold to Test Only Relevant Items & Exclude Popular Ones
Great question—let’s walk through how to set this up with LensKit’s flexible cross-validation tools. You’ll need to combine two custom filters: one to keep only items a user rated above their own average (your "relevant" items), and another to exclude top popular items. Here’s a practical breakdown using Groovy (LensKit’s common configuration DSL):
Step 1: Precompute user average ratings
First, calculate each user’s average rating to define what counts as "relevant" for them:def userAverages = ratings.groupBy { it.user } .collectEntries { user, userRatings -> def avg = userRatings*.rating.sum() / userRatings.size() [user, avg] }Step 2: Filter for relevant items
Create a predicate to keep only ratings where the score exceeds the user’s average:def isRelevant = { rating -> rating.rating > userAverages[rating.user] }Step 3: Identify and exclude popular items
Define "popular" (e.g., top 10% most-rated items) and build a filter to exclude them:def itemCounts = ratings.groupBy { it.item }.collectEntries { item, itemRatings -> [item, itemRatings.size()] } // Set threshold to the lowest count in the top 10% popular items def threshold = itemCounts.values().sort().reverse().take((int)(itemCounts.size() * 0.1)).last() def isNotPopular = { rating -> itemCounts[rating.item] <= threshold }Step 4: Apply filters to your Crossfold task
Chain both filters in the Crossfold configuration to shape your test set:crossfold("cv") { source csvfile("ratings.csv") partitions 5 testFraction 0.2 // Combine filters to keep only relevant, non-popular test ratings testFilter { rating -> isRelevant(rating) && isNotPopular(rating) } // Guard against empty test sets (adjust filters if this triggers) ensureTestSetSize 1 }
2. Is This Feasible in LensKit 3.0?
Absolutely! LensKit 3.0 (including the M2 milestone) is built for this kind of custom cross-validation setup. The testFilter hook in the Crossfold task lets you apply arbitrary predicates to filter which ratings make it into the test set—exactly what we’re using here to enforce your relevant/non-popular rules.
You can tweak the definitions of "relevant" (e.g., use a fixed rating threshold instead of user averages) or "popular" (e.g., base it on total rating sum instead of count) to match your use case. Just make sure to validate that your filters don’t result in empty test partitions—the ensureTestSetSize flag helps catch this early so you can adjust your thresholds if needed.
内容的提问来源于stack exchange,提问作者Carlos Rios

