Commit a0becd4f authored by Charles Zhao's avatar Charles Zhao Committed by Commit Bot

cros: enable get bin weights from flag.

This will allow us to try different weights from finch.

Bug: 871674

Change-Id: I20412f7a0d15fab4c2f1fc45aba4e817b472ea0b
Reviewed-on: https://chromium-review.googlesource.com/1248404
Commit-Queue: Charles . <charleszhao@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594980}
parent 3446c856
......@@ -6,7 +6,9 @@
#include <cmath>
#include "ash/public/cpp/app_list/app_list_features.h"
#include "base/logging.h"
#include "base/metrics/field_trial_params.h"
#include "base/stl_util.h"
namespace app_list {
......@@ -16,12 +18,10 @@ constexpr int kHoursADay = 24;
constexpr base::TimeDelta kSaveInternal = base::TimeDelta::FromHours(1);
// A bin with index i has 5 adjacent bins as: i + 0, i + 1, i + 2, i + 22, and
// i + 23. They each contributes to the final Rank score with different level:
// 0.6 for i-th bin itself, 0.15 for i + 1 (one hour later) and i + 23 (
// one hour earlier), 0.05 for i + 2 (two hours later) and i + 22 (two hours
// earlier).
// i + 23 which stand for the bin i itself, 1 hour later, 2 hours later,
// 2 hours earlier and 1 hour earlier. Each adjacent bin contributes to the
// final Rank score with weights from BinWeightsFromFlagOrDefault();
constexpr int kAdjacentHourBin[] = {0, 1, 2, 22, 23};
constexpr float kAdjacentHourWeight[] = {0.6, 0.15, 0.05, 0.05, 0.15};
} // namespace
......@@ -157,6 +157,7 @@ base::flat_map<std::string, float> HourAppLaunchPredictor::Rank() {
const auto& frequency_table_map =
proto_.hour_app_launch_predictor().binned_frequency_table();
const std::vector<float> weights = BinWeightsFromFlagOrDefault();
for (size_t i = 0; i < base::size(kAdjacentHourBin); ++i) {
// Finds adjacent bin and weight.
const int adj_bin =
......@@ -166,7 +167,7 @@ base::flat_map<std::string, float> HourAppLaunchPredictor::Rank() {
continue;
const auto& frequency_table = find_frequency_table->second;
const float weight = kAdjacentHourWeight[i];
const float weight = weights[i];
// Accumulates the frequency to the output.
if (frequency_table.total_counts() > 0) {
......@@ -256,6 +257,44 @@ int HourAppLaunchPredictor::GetBin() const {
}
}
std::vector<float> HourAppLaunchPredictor::BinWeightsFromFlagOrDefault() {
const std::vector<float> default_weights = {0.6, 0.15, 0.05, 0.05, 0.15};
std::vector<float> weights(5);
// Get weights for adjacent bins. Every weight has to be within [0.0, 1.0]
// And the sum weights[1] + ..., + weights[4] also needs to be in [0.0, 1.0]
// so that the weight[0] is set to be 1.0 - (weights[1] + ..., + weights[4]).
weights[1] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
app_list_features::kEnableAppSearchResultRanker,
"weight_1_hour_later_bin", -1.0));
if (weights[1] < 0.0 || weights[1] > 1.0)
return default_weights;
weights[2] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
app_list_features::kEnableAppSearchResultRanker,
"weight_2_hour_later_bin", -1.0));
if (weights[2] < 0.0 || weights[2] > 1.0)
return default_weights;
weights[3] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
app_list_features::kEnableAppSearchResultRanker,
"weight_2_hour_earlier_bin", -1.0));
if (weights[3] < 0.0 || weights[3] > 1.0)
return default_weights;
weights[4] = static_cast<float>(base::GetFieldTrialParamByFeatureAsDouble(
app_list_features::kEnableAppSearchResultRanker,
"weight_1_hour_earlier_bin", -1.0));
if (weights[4] < 0.0 || weights[4] > 1.0)
return default_weights;
weights[0] = 1.0 - weights[1] - weights[2] - weights[3] - weights[4];
if (weights[0] < 0.0 || weights[0] > 1.0)
return default_weights;
return weights;
}
void FakeAppLaunchPredictor::SetShouldSave(bool should_save) {
should_save_ = should_save;
}
......
......@@ -138,11 +138,17 @@ class HourAppLaunchPredictor : public AppLaunchPredictor {
FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, GetTheRightBin);
FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, RankFromSingleBin);
FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, RankFromMultipleBin);
FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, CheckDefaultWeights);
FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, SetWeightsFromFlag);
FRIEND_TEST_ALL_PREFIXES(HourAppLaunchPredictorTest, FromProtoDecay);
// Returns current bin index of this predictor.
int GetBin() const;
// Get weights of adjacent bins from flag which will be set using finch config
// for exploring possible options.
static std::vector<float> BinWeightsFromFlagOrDefault();
// The proto for this predictor.
AppLaunchPredictorProto proto_;
// Last time the predictor was saved.
......
......@@ -4,11 +4,14 @@
#include "chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor.h"
#include "ash/public/cpp/app_list/app_list_features.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_mock_clock_override.h"
#include "chrome/browser/ui/app_list/search/search_result_ranker/app_launch_predictor_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::ElementsAre;
using testing::UnorderedElementsAre;
using testing::Pair;
using testing::FloatEq;
......@@ -153,6 +156,7 @@ TEST_F(HourAppLaunchPredictorTest, GetTheRightBin) {
// Checks the apps are ranked based on frequency in a single bin.
TEST_F(HourAppLaunchPredictorTest, RankFromSingleBin) {
HourAppLaunchPredictor predictor;
const auto& weights = HourAppLaunchPredictor::BinWeightsFromFlagOrDefault();
// Create a model that trained on kTarget1 3 times, and kTarget2 2 times.
SetLocalTime(1, 10);
......@@ -174,14 +178,16 @@ TEST_F(HourAppLaunchPredictorTest, RankFromSingleBin) {
SetLocalTime(1, 10);
EXPECT_THAT(predictor.Rank(),
UnorderedElementsAre(Pair(kTarget1, FloatEq(0.6 * 0.6)),
Pair(kTarget2, FloatEq(0.6 * 0.4))));
UnorderedElementsAre(Pair(kTarget1, FloatEq(weights[0] * 0.6)),
Pair(kTarget2, FloatEq(weights[0] * 0.4))));
}
// Checks the apps are ranked based on linearly combined scores from adjacent
// bins.
TEST_F(HourAppLaunchPredictorTest, RankFromMultipleBin) {
HourAppLaunchPredictor predictor;
const auto& weights = HourAppLaunchPredictor::BinWeightsFromFlagOrDefault();
// For bin 10
SetLocalTime(1, 10);
predictor.Train(kTarget1);
......@@ -210,15 +216,63 @@ TEST_F(HourAppLaunchPredictorTest, RankFromMultipleBin) {
EXPECT_THAT(
predictor.Rank(),
UnorderedElementsAre(
Pair(kTarget1, FloatEq(0.6 * 2.0 / 3.0 + 0.15 * 0.5)),
Pair(kTarget2, FloatEq(0.6 * 1.0 / 3.0 + 0.15 * 0.5 + 0.05 * 1.0))));
Pair(kTarget1, FloatEq(weights[0] * 2.0 / 3.0 + weights[1] * 0.5)),
Pair(kTarget2, FloatEq(weights[0] * 1.0 / 3.0 + weights[1] * 0.5 +
weights[2] * 1.0))));
// Check weekends.
SetLocalTime(0, 9);
EXPECT_THAT(
predictor.Rank(),
UnorderedElementsAre(Pair(kTarget1, FloatEq(0.15 * 1.0 / 2.0)),
Pair(kTarget2, FloatEq(0.15 * 1.0 / 2.0 + 0.05))));
UnorderedElementsAre(
Pair(kTarget1, FloatEq(weights[1] * 1.0 / 2.0)),
Pair(kTarget2, FloatEq(weights[1] * 1.0 / 2.0 + weights[2]))));
}
// Check the default weights are set correctly.
TEST_F(HourAppLaunchPredictorTest, CheckDefaultWeights) {
base::test::ScopedFeatureList scoped_feature_list_;
scoped_feature_list_.InitAndEnableFeature(
app_list_features::kEnableAppSearchResultRanker);
EXPECT_THAT(HourAppLaunchPredictor::BinWeightsFromFlagOrDefault(),
ElementsAre(FloatEq(0.6), FloatEq(0.15), FloatEq(0.05),
FloatEq(0.05), FloatEq(0.15)));
}
// Checks that the weights are set from flag correctly.
TEST_F(HourAppLaunchPredictorTest, SetWeightsFromFlag) {
base::test::ScopedFeatureList scoped_feature_list_;
scoped_feature_list_.InitAndEnableFeatureWithParameters(
app_list_features::kEnableAppSearchResultRanker,
{{"weight_1_hour_later_bin", "0.1"},
{"weight_2_hour_later_bin", "0.2"},
{"weight_2_hour_earlier_bin", "0.22"},
{"weight_1_hour_earlier_bin", "0.23"}});
HourAppLaunchPredictor predictor;
const auto& weights = HourAppLaunchPredictor::BinWeightsFromFlagOrDefault();
EXPECT_THAT(weights, ElementsAre(FloatEq(0.25), FloatEq(0.1), FloatEq(0.2),
FloatEq(0.22), FloatEq(0.23)));
// For bin 0
SetLocalTime(1, 0);
predictor.Train(kTarget1);
predictor.Train(kTarget1);
predictor.Train(kTarget2);
// For bin 1
SetLocalTime(1, 1);
predictor.Train(kTarget1);
predictor.Train(kTarget2);
SetLocalTime(1, 0);
EXPECT_THAT(
predictor.Rank(),
UnorderedElementsAre(
Pair(kTarget1, FloatEq(weights[0] * 2.0 / 3.0 + weights[1] * 0.5)),
Pair(kTarget2, FloatEq(weights[0] * 1.0 / 3.0 + weights[1] * 0.5))));
}
// Checks FromProto applies decay correctly.
......
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