Commit fbc743ee authored by Mark Pearson's avatar Mark Pearson Committed by Commit Bot

Omnibox - Launch Aggressively Suggest Infrequently Visited URLs

Sets default values for all relevant parameters to the ones we decided
to launch.  In particular, this change:
* makes it so that URLs that match the input--even if only visited
  once or twice--are likely to score above low quality query suggestions
  that come from the server.
* boosts a URL suggestion if it appears the URL suggestion is clearly
  seeking that URL.  In particular, if the omnibox input only matches that
  single URL from history, it gets a 3x boost (in effect we count it as
  having three times as many visits).  This boost decreases as the number of
  matching URLs increases, so that if the user input matches five or more
  items from history, nothing gets a boost.
* lowers the threshold for how well a URL must match the input in order
  to be displayed.  Previously, for example, we wouldn't return URLs that
  match a word in the input if the word matches in the ?query or #hash
  section of the URL.  Now we do.
* reduces the relative weight of a "typed visit" (a time the URL is selected
  from the omnibox) compared with a regular visit (click on a link).
  It used to be that the former was worth 20x the latter.  Now it's only
  1.5x.
* changes to a scoring model in which additional visits to a URL are
  guaranteed to increase its score.  Previously we used a model based on
  the average quality of a visit, which means that if a URL has many
  typed visits and then gets a new untyped visit, its score (the average)
  will go down.  Now we use simply a sum, which means the score will
  definitely increase.

Precisely, in terms of code / config, we're launching the following settings:
  "HQPExperimentalScoringBuckets": "0.0:550,1:625,9.0:1300,90.0:1399",
  "HQPTypedValue": "1.5",
  "HQPFreqencyUsesSum": "true",
  "HQPNumMatchesScores": "1:3,2:2.5,3:2,4:1.5",
  "HQPExperimentalScoringTopicalityThreshold": "0.5"

In the process, removes some of the flags for frequency scoring that
I don't think are useful (not the right model for scoring) and aren't
worth going back to.

Bug: 695560, 327085, 369989, 508262, 580688, 591981, 598184
Change-Id: Id349c5aaa2e09e6b5284c55fc5790f4b14b8fa7b
Reviewed-on: https://chromium-review.googlesource.com/585377
Commit-Queue: Mark Pearson <mpearson@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491089}
parent 28cefc4b
...@@ -788,7 +788,7 @@ HQPOrderingTest::GetTestData() { ...@@ -788,7 +788,7 @@ HQPOrderingTest::GetTestData() {
{"http://store.steampowered.com/", "", 6, 6, 1}, {"http://store.steampowered.com/", "", 6, 6, 1},
{"http://techmeme.com/", "techmeme", 111, 110, 4}, {"http://techmeme.com/", "techmeme", 111, 110, 4},
{"http://www.teamliquid.net/tlpd", "team liquid progaming database", 15, {"http://www.teamliquid.net/tlpd", "team liquid progaming database", 15,
15, 2}, 15, 4},
{"http://store.steampowered.com/", "the steam summer camp sale", 6, 6, 1}, {"http://store.steampowered.com/", "the steam summer camp sale", 6, 6, 1},
{"http://www.teamliquid.net/tlpd/korean/players", {"http://www.teamliquid.net/tlpd/korean/players",
"tlpd - bw korean - player index", 25, 7, 219}, "tlpd - bw korean - player index", 25, 7, 219},
...@@ -823,7 +823,7 @@ TEST_F(HQPOrderingTest, TEAMatch) { ...@@ -823,7 +823,7 @@ TEST_F(HQPOrderingTest, TEAMatch) {
std::vector<std::string> expected_urls; std::vector<std::string> expected_urls;
expected_urls.push_back("http://www.teamliquid.net/"); expected_urls.push_back("http://www.teamliquid.net/");
expected_urls.push_back("http://www.teamliquid.net/tlpd"); expected_urls.push_back("http://www.teamliquid.net/tlpd");
expected_urls.push_back("http://www.teamliquid.net/tlpd/korean/players"); expected_urls.push_back("http://teamliquid.net/");
RunTest(ASCIIToUTF16("tea"), false, expected_urls, true, RunTest(ASCIIToUTF16("tea"), false, expected_urls, true,
ASCIIToUTF16("www.teamliquid.net"), ASCIIToUTF16("www.teamliquid.net"),
ASCIIToUTF16("mliquid.net")); ASCIIToUTF16("mliquid.net"));
......
...@@ -530,11 +530,22 @@ TEST_F(InMemoryURLIndexTest, Retrieval) { ...@@ -530,11 +530,22 @@ TEST_F(InMemoryURLIndexTest, Retrieval) {
EXPECT_EQ(ASCIIToUTF16("Practically Perfect Search Result"), EXPECT_EQ(ASCIIToUTF16("Practically Perfect Search Result"),
matches[0].url_info.title()); matches[0].url_info.title());
// Search which should result in very poor result. // Search which should result in very poor result. (It's a mid-word match
// No results since it will be suppressed by default scoring. // in a hostname.) No results since it will be suppressed by default scoring.
matches = url_index_->HistoryItemsForTerms(ASCIIToUTF16("qui c"), matches = url_index_->HistoryItemsForTerms(ASCIIToUTF16("heinqui"),
base::string16::npos, kMaxMatches); base::string16::npos, kMaxMatches);
EXPECT_EQ(0U, matches.size()); EXPECT_EQ(0U, matches.size());
// But if the user adds a term that matches well against the same result,
// the result should be returned.
matches =
url_index_->HistoryItemsForTerms(ASCIIToUTF16("heinqui microprocessor"),
base::string16::npos, kMaxMatches);
ASSERT_EQ(1U, matches.size());
EXPECT_EQ(18, matches[0].url_info.id());
EXPECT_EQ("http://www.theinquirer.net/", matches[0].url_info.url().spec());
EXPECT_EQ(ASCIIToUTF16("THE INQUIRER - Microprocessor, Server, Memory, PCS, "
"Graphics, Networking, Storage"),
matches[0].url_info.title());
// A URL that comes from the default search engine should not be returned. // A URL that comes from the default search engine should not be returned.
matches = url_index_->HistoryItemsForTerms(ASCIIToUTF16("query"), matches = url_index_->HistoryItemsForTerms(ASCIIToUTF16("query"),
......
...@@ -508,7 +508,7 @@ float OmniboxFieldTrial::HQPExperimentalTopicalityThreshold() { ...@@ -508,7 +508,7 @@ float OmniboxFieldTrial::HQPExperimentalTopicalityThreshold() {
double topicality_threshold; double topicality_threshold;
if (topicality_threshold_str.empty() || if (topicality_threshold_str.empty() ||
!base::StringToDouble(topicality_threshold_str, &topicality_threshold)) !base::StringToDouble(topicality_threshold_str, &topicality_threshold))
return 0.8f; return 0.5f;
return static_cast<float>(topicality_threshold); return static_cast<float>(topicality_threshold);
} }
...@@ -526,17 +526,6 @@ int OmniboxFieldTrial::MaxNumHQPUrlsIndexedAtStartup() { ...@@ -526,17 +526,6 @@ int OmniboxFieldTrial::MaxNumHQPUrlsIndexedAtStartup() {
return -1; return -1;
} }
bool OmniboxFieldTrial::HQPFixFewVisitsBug() {
return variations::GetVariationParamValue(
kBundledExperimentFieldTrialName,
kHQPFixFewVisitsBugRule) == "true";
}
bool OmniboxFieldTrial::HQPFreqencyUsesSum() {
return variations::GetVariationParamValue(kBundledExperimentFieldTrialName,
kHQPFreqencyUsesSumRule) == "true";
}
size_t OmniboxFieldTrial::HQPMaxVisitsToScore() { size_t OmniboxFieldTrial::HQPMaxVisitsToScore() {
std::string max_visits_str = variations::GetVariationParamValue( std::string max_visits_str = variations::GetVariationParamValue(
kBundledExperimentFieldTrialName, kHQPMaxVisitsToScoreRule); kBundledExperimentFieldTrialName, kHQPMaxVisitsToScoreRule);
...@@ -558,7 +547,7 @@ float OmniboxFieldTrial::HQPTypedValue() { ...@@ -558,7 +547,7 @@ float OmniboxFieldTrial::HQPTypedValue() {
std::string typed_value_str = variations::GetVariationParamValue( std::string typed_value_str = variations::GetVariationParamValue(
kBundledExperimentFieldTrialName, kHQPTypedValueRule); kBundledExperimentFieldTrialName, kHQPTypedValueRule);
if (typed_value_str.empty()) if (typed_value_str.empty())
return 20; return 1.5;
// This is a best-effort conversion; we trust the hand-crafted parameters // This is a best-effort conversion; we trust the hand-crafted parameters
// downloaded from the server to be perfect. There's no need for handle // downloaded from the server to be perfect. There's no need for handle
// errors smartly. // errors smartly.
...@@ -570,8 +559,11 @@ float OmniboxFieldTrial::HQPTypedValue() { ...@@ -570,8 +559,11 @@ float OmniboxFieldTrial::HQPTypedValue() {
OmniboxFieldTrial::NumMatchesScores OmniboxFieldTrial::HQPNumMatchesScores() { OmniboxFieldTrial::NumMatchesScores OmniboxFieldTrial::HQPNumMatchesScores() {
std::string str = variations::GetVariationParamValue( std::string str = variations::GetVariationParamValue(
kBundledExperimentFieldTrialName, kHQPNumMatchesScoresRule); kBundledExperimentFieldTrialName, kHQPNumMatchesScoresRule);
// The parameter is a comma-separated list of (number, value) pairs, e.g. static constexpr char kDefaultNumMatchesScores[] = "1:3,2:2.5,3:2,4:1.5";
// "1:3,2:2.5,3:2,4:1.5". if (str.empty())
str = kDefaultNumMatchesScores;
// The parameter is a comma-separated list of (number, value) pairs such as
// listed above.
// This is a best-effort conversion; we trust the hand-crafted parameters // This is a best-effort conversion; we trust the hand-crafted parameters
// downloaded from the server to be perfect. There's no need to handle // downloaded from the server to be perfect. There's no need to handle
// errors smartly. // errors smartly.
...@@ -755,8 +747,6 @@ OmniboxFieldTrial::kMeasureSuggestPollingDelayFromLastKeystrokeRule[] = ...@@ -755,8 +747,6 @@ OmniboxFieldTrial::kMeasureSuggestPollingDelayFromLastKeystrokeRule[] =
"MeasureSuggestPollingDelayFromLastKeystroke"; "MeasureSuggestPollingDelayFromLastKeystroke";
const char OmniboxFieldTrial::kSuggestPollingDelayMsRule[] = const char OmniboxFieldTrial::kSuggestPollingDelayMsRule[] =
"SuggestPollingDelayMs"; "SuggestPollingDelayMs";
const char OmniboxFieldTrial::kHQPFixFewVisitsBugRule[] = "HQPFixFewVisitsBug";
const char OmniboxFieldTrial::kHQPFreqencyUsesSumRule[] = "HQPFreqencyUsesSum";
const char OmniboxFieldTrial::kHQPMaxVisitsToScoreRule[] = const char OmniboxFieldTrial::kHQPMaxVisitsToScoreRule[] =
"HQPMaxVisitsToScoreRule"; "HQPMaxVisitsToScoreRule";
const char OmniboxFieldTrial::kHQPNumMatchesScoresRule[] = const char OmniboxFieldTrial::kHQPNumMatchesScoresRule[] =
......
...@@ -311,7 +311,7 @@ class OmniboxFieldTrial { ...@@ -311,7 +311,7 @@ class OmniboxFieldTrial {
static std::string HQPExperimentalScoringBuckets(); static std::string HQPExperimentalScoringBuckets();
// Returns the topicality threshold for HQP experiments. Returns a default // Returns the topicality threshold for HQP experiments. Returns a default
// value of 0.8 if no threshold is specified in the field trial. // value of 0.5 if no threshold is specified in the field trial.
static float HQPExperimentalTopicalityThreshold(); static float HQPExperimentalTopicalityThreshold();
// --------------------------------------------------------- // ---------------------------------------------------------
...@@ -327,25 +327,18 @@ class OmniboxFieldTrial { ...@@ -327,25 +327,18 @@ class OmniboxFieldTrial {
// For the HQPFixFrequencyScoring experiment that's part of the // For the HQPFixFrequencyScoring experiment that's part of the
// bundled omnibox field trial. // bundled omnibox field trial.
// Returns true if HQP should apply the bug fix to discount the visits to
// pages visited less than ten times.
static bool HQPFixFewVisitsBug();
// Returns true if HQP should use the weighted sum when computing frequency
// scores. False means to use the weighted average. Returns false if the
// experiment isn't active.
static bool HQPFreqencyUsesSum();
// Returns the number of visits HQP should use when computing frequency // Returns the number of visits HQP should use when computing frequency
// scores. Returns 10 if the epxeriment isn't active. // scores. Returns 10 if the epxeriment isn't active.
static size_t HQPMaxVisitsToScore(); static size_t HQPMaxVisitsToScore();
// Returns the score that should be given to typed transitions. (The score // Returns the score that should be given to typed transitions. (The score
// of non-typed transitions is 1.) Returns 20 if the experiment isn't active. // of non-typed transitions is 1.) Returns 1.5 if the experiment isn't
// active.
static float HQPTypedValue(); static float HQPTypedValue();
// Returns NumMatchesScores; see comment by the declaration of it. // Returns NumMatchesScores; see comment by the declaration of it.
// Returns an empty NumMatchesScores if the experiment isn't active. // If the experiment isn't active, returns an NumMatchesScores of
// {{1, 3}, {2, 2.5}, {3, 2}, {4, 1.5}}.
static NumMatchesScores HQPNumMatchesScores(); static NumMatchesScores HQPNumMatchesScores();
// --------------------------------------------------------- // ---------------------------------------------------------
...@@ -466,7 +459,6 @@ class OmniboxFieldTrial { ...@@ -466,7 +459,6 @@ class OmniboxFieldTrial {
static const char kDemoteByTypeRule[]; static const char kDemoteByTypeRule[];
static const char kHQPBookmarkValueRule[]; static const char kHQPBookmarkValueRule[];
static const char kHQPTypedValueRule[]; static const char kHQPTypedValueRule[];
static const char kHQPDiscountFrecencyWhenFewVisitsRule[];
static const char kHQPAllowMatchInTLDRule[]; static const char kHQPAllowMatchInTLDRule[];
static const char kHQPAllowMatchInSchemeRule[]; static const char kHQPAllowMatchInSchemeRule[];
static const char kZeroSuggestRule[]; static const char kZeroSuggestRule[];
...@@ -475,8 +467,6 @@ class OmniboxFieldTrial { ...@@ -475,8 +467,6 @@ class OmniboxFieldTrial {
static const char kDisableResultsCachingRule[]; static const char kDisableResultsCachingRule[];
static const char kMeasureSuggestPollingDelayFromLastKeystrokeRule[]; static const char kMeasureSuggestPollingDelayFromLastKeystrokeRule[];
static const char kSuggestPollingDelayMsRule[]; static const char kSuggestPollingDelayMsRule[];
static const char kHQPFixFewVisitsBugRule[];
static const char kHQPFreqencyUsesSumRule[];
static const char kHQPMaxVisitsToScoreRule[]; static const char kHQPMaxVisitsToScoreRule[];
static const char kHQPNumMatchesScoresRule[]; static const char kHQPNumMatchesScoresRule[];
static const char kHQPNumTitleWordsRule[]; static const char kHQPNumTitleWordsRule[];
......
...@@ -119,8 +119,6 @@ size_t GetAdjustedOffsetForComponent( ...@@ -119,8 +119,6 @@ size_t GetAdjustedOffsetForComponent(
bool ScoredHistoryMatch::also_do_hup_like_scoring_; bool ScoredHistoryMatch::also_do_hup_like_scoring_;
float ScoredHistoryMatch::bookmark_value_; float ScoredHistoryMatch::bookmark_value_;
float ScoredHistoryMatch::typed_value_; float ScoredHistoryMatch::typed_value_;
bool ScoredHistoryMatch::fix_few_visits_bug_;
bool ScoredHistoryMatch::frequency_uses_sum_;
size_t ScoredHistoryMatch::max_visits_to_score_; size_t ScoredHistoryMatch::max_visits_to_score_;
bool ScoredHistoryMatch::allow_tld_matches_; bool ScoredHistoryMatch::allow_tld_matches_;
bool ScoredHistoryMatch::allow_scheme_matches_; bool ScoredHistoryMatch::allow_scheme_matches_;
...@@ -428,8 +426,6 @@ void ScoredHistoryMatch::Init() { ...@@ -428,8 +426,6 @@ void ScoredHistoryMatch::Init() {
bookmark_value_ = OmniboxFieldTrial::HQPBookmarkValue(); bookmark_value_ = OmniboxFieldTrial::HQPBookmarkValue();
typed_value_ = OmniboxFieldTrial::HQPTypedValue(); typed_value_ = OmniboxFieldTrial::HQPTypedValue();
max_visits_to_score_ = OmniboxFieldTrial::HQPMaxVisitsToScore(); max_visits_to_score_ = OmniboxFieldTrial::HQPMaxVisitsToScore();
frequency_uses_sum_ = OmniboxFieldTrial::HQPFreqencyUsesSum();
fix_few_visits_bug_ = OmniboxFieldTrial::HQPFixFewVisitsBug();
allow_tld_matches_ = OmniboxFieldTrial::HQPAllowMatchInTLDValue(); allow_tld_matches_ = OmniboxFieldTrial::HQPAllowMatchInTLDValue();
allow_scheme_matches_ = OmniboxFieldTrial::HQPAllowMatchInSchemeValue(); allow_scheme_matches_ = OmniboxFieldTrial::HQPAllowMatchInSchemeValue();
num_title_words_to_allow_ = OmniboxFieldTrial::HQPNumTitleWordsToAllow(); num_title_words_to_allow_ = OmniboxFieldTrial::HQPNumTitleWordsToAllow();
...@@ -613,6 +609,24 @@ float ScoredHistoryMatch::GetFrequency(const base::Time& now, ...@@ -613,6 +609,24 @@ float ScoredHistoryMatch::GetFrequency(const base::Time& now,
// Compute the weighted sum of |value_of_transition| over the last at most // Compute the weighted sum of |value_of_transition| over the last at most
// |max_visits_to_score_| visits, where each visit is weighted using // |max_visits_to_score_| visits, where each visit is weighted using
// GetRecencyScore() based on how many days ago it happened. // GetRecencyScore() based on how many days ago it happened.
//
// Here are example frequency scores, assuming |max_visits_to_score_| is 10.
// - a single typed visit more than three months ago, no other visits -> 0.45
// ( = 1.5 typed visit score * 0.3 recency score)
// - a single visit recently -> 1.0
// ( = 1.0 visit score * 1.0 recency score)
// - a single typed visit recently -> 1.5
// ( = 1.5 typed visit score * 1.0 recency score)
// - 10+ visits, once every three days, no typed visits -> about 7.5
// ( 10+ visits, averaging about 0.75 recency score each)
// - 10+ typed visits, once a week -> about 7.5
// ( 10+ visits, average of 1.5 typed visit score * 0.5 recency score)
// - 10+ visit, once every day, no typed visits -> about 9.0
// ( 10+ visits, average about 0.9 recency score each)
// - 10+ typed visit, once every three days -> about 11
// ( 10+ visits, averaging about 1.5 typed visit * 0.75 recency score each)
// - 10+ typed visits today -> 15
// ( 10+ visits, each worth 1.5 typed visit score)
float summed_visit_points = 0; float summed_visit_points = 0;
auto visits_end = auto visits_end =
visits.begin() + std::min(visits.size(), max_visits_to_score_); visits.begin() + std::min(visits.size(), max_visits_to_score_);
...@@ -631,17 +645,7 @@ float ScoredHistoryMatch::GetFrequency(const base::Time& now, ...@@ -631,17 +645,7 @@ float ScoredHistoryMatch::GetFrequency(const base::Time& now,
const float bucket_weight = GetRecencyScore((now - i->first).InDays()); const float bucket_weight = GetRecencyScore((now - i->first).InDays());
summed_visit_points += (value_of_transition * bucket_weight); summed_visit_points += (value_of_transition * bucket_weight);
} }
if (frequency_uses_sum_) return summed_visit_points;
return summed_visit_points;
// Compute the average weighted value_of_transition and return it.
// Use |max_visits_to_score_| as the denominator for the average regardless of
// how many visits there were in order to penalize a match that has
// fewer visits than kMaxVisitsToScore.
if (fix_few_visits_bug_)
return summed_visit_points / ScoredHistoryMatch::max_visits_to_score_;
return visits.size() * summed_visit_points /
ScoredHistoryMatch::max_visits_to_score_;
} }
float ScoredHistoryMatch::GetDocumentSpecificityScore( float ScoredHistoryMatch::GetDocumentSpecificityScore(
...@@ -679,29 +683,26 @@ float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score, ...@@ -679,29 +683,26 @@ float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score,
if (topicality_score == 0) if (topicality_score == 0)
return 0; return 0;
// Here's how to interpret intermediate_score: Suppose the omnibox has one
// input term. Suppose the input matches many documents. (This implies // Compute an intermediate score by multiplying the topicality, specificity,
// specificity_score == 1.0.) Suppose we have a URL for which the omnibox // and frequency scores, then map it to the range [0, 1399]. For typical
// input term has a single URL hostname hit at a word boundary. (This // ranges, remember:
// implies topicality_score = 1.0.). Then the intermediate_score for // * topicality score is usually around 1.0; typical range is [0.5, 2.5].
// this URL will depend entirely on the frequency_score with // 1.0 is the value assigned when a single-term input matches in the
// this interpretation: // hostname. For more details, see GetTopicalityScore().
// - a single typed visit more than three months ago, no other visits -> 0.2 // * specificity score is usually 1.0; typical range is [1.0, 3.0].
// - a visit every three days, no typed visits -> 0.706 // 1.0 is the default value when the user's input matches many documents.
// - a visit every day, no typed visits -> 0.916 // For more details, see GetDocumentSpecificityScore().
// - a single typed visit yesterday, no other visits -> 2.0 // * frequency score has a much wider range depending on the number of
// - a typed visit once a week -> 11.77 // visits; typical range is [0.3, 15.0]. For more details, see
// - a typed visit every three days -> 14.12 // GetFrequency().
// - at least ten typed visits today -> 20.0 (maximum score)
// //
// The below code maps intermediate_score to the range [0, 1399]. // The default scoring buckets: "0.0:550,1:625,9.0:1300,90.0:1399"
// For example: // will linearly interpolate the scores between:
// The default scoring buckets: "0.0:400,1.5:600,12.0:1300,20.0:1399" // 0.0 to 1.0 --> 550 to 625
// We will linearly interpolate the scores between: // 1.0 to 9.0 --> 625 to 1300
// 0 to 1.5 --> 400 to 600 // 9.0 to 90.0 --> 1300 to 1399
// 1.5 to 12.0 --> 600 to 1300 // >= 90.0 --> 1399
// 12.0 to 20.0 --> 1300 to 1399
// >= 20.0 --> 1399
// //
// The score maxes out at 1399 (i.e., cannot beat a good inlineable result // The score maxes out at 1399 (i.e., cannot beat a good inlineable result
// from HistoryURL provider). // from HistoryURL provider).
...@@ -729,13 +730,12 @@ float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score, ...@@ -729,13 +730,12 @@ float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score,
// static // static
std::vector<ScoredHistoryMatch::ScoreMaxRelevance> std::vector<ScoredHistoryMatch::ScoreMaxRelevance>
ScoredHistoryMatch::GetHQPBuckets() { ScoredHistoryMatch::GetHQPBuckets() {
// Start with the default buckets and override them if appropriate.
std::string relevance_buckets_str = std::string relevance_buckets_str =
"0.0:400,1.5:600,5.0:900,10.5:1203,15.0:1300,20.0:1399";
std::string experimental_scoring_buckets =
OmniboxFieldTrial::HQPExperimentalScoringBuckets(); OmniboxFieldTrial::HQPExperimentalScoringBuckets();
if (!experimental_scoring_buckets.empty()) static constexpr char kDefaultHQPBuckets[] =
relevance_buckets_str = experimental_scoring_buckets; "0.0:550,1:625,9.0:1300,90.0:1399";
if (relevance_buckets_str.empty())
relevance_buckets_str = kDefaultHQPBuckets;
return GetHQPBucketsFromString(relevance_buckets_str); return GetHQPBucketsFromString(relevance_buckets_str);
} }
......
...@@ -176,14 +176,6 @@ struct ScoredHistoryMatch : public history::HistoryMatch { ...@@ -176,14 +176,6 @@ struct ScoredHistoryMatch : public history::HistoryMatch {
// Typed visits to page score this, compared to 1 for untyped visits. // Typed visits to page score this, compared to 1 for untyped visits.
static float typed_value_; static float typed_value_;
// True if we should fix a bug in frequency scoring relating to how we
// extrapolate frecency when the URL has been visited few times.
static bool fix_few_visits_bug_;
// Determines whether GetFrequency() returns a score based on on the weighted
// sum of visit scores instead of the weighted average.
static bool frequency_uses_sum_;
// The maximum number of recent visits to examine in GetFrequency(). // The maximum number of recent visits to examine in GetFrequency().
static size_t max_visits_to_score_; static size_t max_visits_to_score_;
......
...@@ -570,78 +570,30 @@ TEST_F(ScoredHistoryMatchTest, GetFrequency) { ...@@ -570,78 +570,30 @@ TEST_F(ScoredHistoryMatchTest, GetFrequency) {
// Now consider pages visited twice, with one visit being typed and one // Now consider pages visited twice, with one visit being typed and one
// untyped. // untyped.
// With default scoring, a two-visit score should have a higher score than the // A two-visit score should have a higher score than the single typed visit
// single typed visit score. // score.
visits = {{now, ui::PAGE_TRANSITION_TYPED}, visits = {{now, ui::PAGE_TRANSITION_TYPED},
{now - base::TimeDelta::FromDays(1), ui::PAGE_TRANSITION_LINK}}; {now - base::TimeDelta::FromDays(1), ui::PAGE_TRANSITION_LINK}};
const float two_visits_score = match.GetFrequency(now, false, visits); const float two_visits_score = match.GetFrequency(now, false, visits);
EXPECT_GT(two_visits_score, one_typed_score); EXPECT_GT(two_visits_score, one_typed_score);
// Likewise, with |frequency_uses_sum_|, the two-visit score should be higher
// than the single typed visit score because the sum is greater.
float two_visits_score_uses_sum;
{
base::AutoReset<bool> tmp(&ScoredHistoryMatch::frequency_uses_sum_, true);
two_visits_score_uses_sum = match.GetFrequency(now, false, visits);
EXPECT_GT(two_visits_score_uses_sum, one_typed_score);
}
// With |fix_few_visits_bug_|, its two-visit score should be higher than the
// one-visit score but lower than the regular two-visit score because the
// fix-few-visits score computes the average visit score and the untyped
// visit brings the average down.
float two_visits_score_fix_few_visits;
{
base::AutoReset<bool> tmp(&ScoredHistoryMatch::fix_few_visits_bug_, true);
two_visits_score_fix_few_visits = match.GetFrequency(now, false, visits);
EXPECT_GT(two_visits_score_fix_few_visits, one_typed_score);
EXPECT_LT(two_visits_score_fix_few_visits, two_visits_score);
}
// Add an third untyped visit. // Add an third untyped visit.
visits.push_back( visits.push_back(
{now - base::TimeDelta::FromDays(2), ui::PAGE_TRANSITION_LINK}); {now - base::TimeDelta::FromDays(2), ui::PAGE_TRANSITION_LINK});
// With default scoring and with |frequency_uses_sum_|, the score should be // The score should be higher than the two-visit score.
// higher than the two-visit score.
const float three_visits_score = match.GetFrequency(now, false, visits); const float three_visits_score = match.GetFrequency(now, false, visits);
EXPECT_GT(three_visits_score, two_visits_score); EXPECT_GT(three_visits_score, two_visits_score);
{
base::AutoReset<bool> tmp(&ScoredHistoryMatch::frequency_uses_sum_, true);
const float three_visits_score_uses_sum =
match.GetFrequency(now, false, visits);
EXPECT_GT(three_visits_score_uses_sum, two_visits_score);
EXPECT_GT(three_visits_score_uses_sum, two_visits_score_uses_sum);
}
// With |fix_few_visits_bug_|, the score should also go up but not as much as
// under regular scoring.
{
base::AutoReset<bool> tmp(&ScoredHistoryMatch::fix_few_visits_bug_, true);
const float three_visits_score_fix_few_visits =
match.GetFrequency(now, false, visits);
EXPECT_GT(three_visits_score_fix_few_visits,
two_visits_score_fix_few_visits);
EXPECT_LT(three_visits_score_fix_few_visits, three_visits_score);
}
// In the uses-sum case, if we're only supposed to consider the most recent // If we're only supposed to consider the most recent two visits, then the
// two visits, then all the scores should be the same as in the two-visit // score should be the same as in the two-visit case.
// case. (For the regular scoring and the fix-few-visits cases, the
// situation is more complicated because in these cases both the numerator--
// the value of the visits used--and the denominator--the number of visits
// used--changed. We don't test this complicated logic separately from having
// tested the simpler components already.)
{ {
base::AutoReset<size_t> tmp1(&ScoredHistoryMatch::max_visits_to_score_, 2); base::AutoReset<size_t> tmp1(&ScoredHistoryMatch::max_visits_to_score_, 2);
base::AutoReset<bool> tmp2(&ScoredHistoryMatch::frequency_uses_sum_, true); EXPECT_EQ(two_visits_score, match.GetFrequency(now, false, visits));
EXPECT_EQ(two_visits_score_uses_sum,
match.GetFrequency(now, false, visits));
// Check again with the third visit being typed. // Check again with the third visit being typed.
visits[2].second = ui::PAGE_TRANSITION_TYPED; visits[2].second = ui::PAGE_TRANSITION_TYPED;
EXPECT_EQ(two_visits_score_uses_sum, EXPECT_EQ(two_visits_score, match.GetFrequency(now, false, visits));
match.GetFrequency(now, false, visits));
} }
} }
...@@ -655,7 +607,7 @@ TEST_F(ScoredHistoryMatchTest, GetDocumentSpecificityScore) { ...@@ -655,7 +607,7 @@ TEST_F(ScoredHistoryMatchTest, GetDocumentSpecificityScore) {
ScoredHistoryMatch match(row, visits, ASCIIToUTF16("foo"), Make1Term("foo"), ScoredHistoryMatch match(row, visits, ASCIIToUTF16("foo"), Make1Term("foo"),
WordStarts{0}, row_word_starts, false, 1, now); WordStarts{0}, row_word_starts, false, 1, now);
EXPECT_EQ(1.0, match.GetDocumentSpecificityScore(1)); EXPECT_EQ(3.0, match.GetDocumentSpecificityScore(1));
EXPECT_EQ(1.0, match.GetDocumentSpecificityScore(5)); EXPECT_EQ(1.0, match.GetDocumentSpecificityScore(5));
EXPECT_EQ(1.0, match.GetDocumentSpecificityScore(50)); EXPECT_EQ(1.0, match.GetDocumentSpecificityScore(50));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment