Commit 13699353 authored by Tarun Bansal's avatar Tarun Bansal Committed by Commit Bot

Navigation predictor: Normalize anchor elements score

Normalize the score across all anchor elements. This makes
it simpler to use anchor element score when predicting the
next navigation when there are many anchors on the webpage,
and all of them may have high score.

Also, includes minor cleanups where some of the variables
are added to the header file. These will be used in the next CL.

Change-Id: Iad914682ef6d96c1b4d3cab040b555a6723f05de
Bug: 903945
TBR: ryansturm@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/c/1328561
Commit-Queue: Tarun Bansal <tbansal@chromium.org>
Reviewed-by: default avatarTarun Bansal <tbansal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607020}
parent 5d46b77a
......@@ -8,6 +8,7 @@
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/sys_info.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
......@@ -36,7 +37,7 @@ struct NavigationPredictor::NavigationScore {
const size_t area_rank;
// Calculated navigation score, based on |area_rank| and other metrics.
const double score;
double score;
// Multiple anchor elements may point to the same |url|. |contains_image| is
// true if at least one of the anchor elements pointing to |url| contains an
......@@ -87,7 +88,8 @@ NavigationPredictor::NavigationPredictor(
sum_scales_(ratio_area_scale_ + is_in_iframe_scale_ +
is_same_host_scale_ + contains_image_scale_ +
is_url_incremented_scale_ + source_engagement_score_scale_ +
target_engagement_score_scale_ + area_rank_scale_) {
target_engagement_score_scale_ + area_rank_scale_),
is_low_end_device_(base::SysInfo::IsLowEndDevice()) {
DCHECK(browser_context_);
DETACH_FROM_SEQUENCE(sequence_checker_);
}
......@@ -155,6 +157,11 @@ void NavigationPredictor::ReportAnchorElementMetricsOnClick(
return;
}
source_is_default_search_engine_page_ =
GetTemplateURLService() &&
GetTemplateURLService()->IsSearchResultsPageFromDefaultSearchProvider(
metrics->source_url);
RecordTimingOnClick();
SiteEngagementService* engagement_service = GetEngagementService();
......@@ -202,10 +209,7 @@ void NavigationPredictor::ReportAnchorElementMetricsOnClick(
(number_of_anchors_same_host_ * 100) / number_of_anchors);
}
bool source_is_search_results_page =
GetTemplateURLService()->IsSearchResultsPageFromDefaultSearchProvider(
metrics->source_url);
if (source_is_search_results_page) {
if (source_is_default_search_engine_page_) {
UMA_HISTOGRAM_BOOLEAN("AnchorElementMetrics.Clicked.OnDSE.SameHost",
metrics->is_same_host);
} else {
......@@ -353,6 +357,10 @@ void NavigationPredictor::ReportAnchorElementMetricsOnLoad(
document_loaded_timing_ = base::TimeTicks::Now();
source_is_default_search_engine_page_ =
GetTemplateURLService() &&
GetTemplateURLService()->IsSearchResultsPageFromDefaultSearchProvider(
metrics[0]->source_url);
MergeMetricsSameTargetUrl(&metrics);
if (metrics.empty())
......@@ -388,6 +396,7 @@ void NavigationPredictor::ReportAnchorElementMetricsOnLoad(
// Loop |metrics| to compute navigation scores.
std::vector<std::unique_ptr<NavigationScore>> navigation_scores;
navigation_scores.reserve(metrics.size());
double total_score = 0.0;
for (size_t i = 0; i != metrics.size(); ++i) {
const auto& metric = metrics[i];
RecordMetricsOnLoad(*metric);
......@@ -413,11 +422,20 @@ void NavigationPredictor::ReportAnchorElementMetricsOnLoad(
double score = CalculateAnchorNavigationScore(
*metric, document_engagement_score, target_engagement_score, area_rank,
metrics.size());
total_score += score;
navigation_scores.push_back(std::make_unique<NavigationScore>(
metric->target_url, area_rank, score, metric->contains_image));
}
// Normalize |score| to a total sum of 100.0 across all anchor elements
// received.
if (total_score > 0.0) {
for (auto& navigation_score : navigation_scores) {
navigation_score->score = navigation_score->score / total_score * 100.0;
}
}
// Sort scores by the calculated navigation score in descending order. This
// score rank is used by MaybeTakeActionOnLoad, and stored in
// |navigation_scores_map_|.
......@@ -476,17 +494,13 @@ double NavigationPredictor::CalculateAnchorNavigationScore(
DCHECK_LE(0, area_rank_score);
DCHECK_GE(1, area_rank_score);
bool source_is_search_results_page =
GetTemplateURLService()->IsSearchResultsPageFromDefaultSearchProvider(
metrics.source_url);
double host_score = 0.0;
// On pages from default search engine, give higher weight to target URLs that
// link to a different host. On non-default search engine pages, give higher
// weight to target URLs that link to the same host.
if (!source_is_search_results_page && metrics.is_same_host) {
if (!source_is_default_search_engine_page_ && metrics.is_same_host) {
host_score = is_same_host_scale_;
} else if (source_is_search_results_page && !metrics.is_same_host) {
} else if (source_is_default_search_engine_page_ && !metrics.is_same_host) {
host_score = is_same_host_scale_;
}
......
......@@ -119,10 +119,17 @@ class NavigationPredictor : public blink::mojom::AnchorElementMetricsHost {
// Sum of all scales. Used to normalize the final computed weight.
const int sum_scales_;
// True if device is a low end device.
const bool is_low_end_device_;
// Timing of document loaded and last click.
base::TimeTicks document_loaded_timing_;
base::TimeTicks last_click_timing_;
// True if the source webpage (i.e., the page on which we are trying to
// predict the next navigation) is a page from user's default search engine.
bool source_is_default_search_engine_page_ = false;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(NavigationPredictor);
......
......@@ -183,8 +183,10 @@ TEST_F(NavigationPredictorTest, MultipleAnchorElementMetricsOnLoad) {
EXPECT_EQ(4, area_rank_map.find(GURL(href_xsmall))->second);
// The highest score is 100 (scale factor) * 0.1 (largest area) = 10.
// After scaling the navigation score across all anchor elements, the score
// becomes 38.
histogram_tester.ExpectUniqueSample(
"AnchorElementMetrics.Visible.HighestNavigationScore", 10, 1);
"AnchorElementMetrics.Visible.HighestNavigationScore", 38, 1);
histogram_tester.ExpectTotalCount("AnchorElementMetrics.Visible.RatioArea",
5);
}
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