-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[merge-103][segmentation] Add Feed user segment
It is useful to anlyze the impact of start surface split by the Feed user segments. Also useful to identify which users would like different modules. BUG=1325414 (cherry picked from commit 72e7d84) Change-Id: I8175a7a75e2fe673b348c47c694c8702ae509c97 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3630696 Reviewed-by: Shakti Sahu <shaktisahu@chromium.org> Reviewed-by: Sophie Chang <sophiechang@chromium.org> Commit-Queue: Siddhartha S <ssid@chromium.org> Cr-Original-Commit-Position: refs/heads/main@{#1003883} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3657486 Auto-Submit: Siddhartha S <ssid@chromium.org> Commit-Queue: Shakti Sahu <shaktisahu@chromium.org> Reviewed-by: Min Qin <qinmin@chromium.org> Cr-Commit-Position: refs/branch-heads/5060@{#189} Cr-Branched-From: b83393d-refs/heads/main@{#1002911}
- Loading branch information
1 parent
e319b46
commit 1cd2bda
Showing
14 changed files
with
358 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 153 additions & 0 deletions
153
chrome/browser/segmentation_platform/default_model/feed_user_segment.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/segmentation_platform/default_model/feed_user_segment.h" | ||
|
||
#include "base/metrics/field_trial_params.h" | ||
#include "base/threading/sequenced_task_runner_handle.h" | ||
#include "chrome/browser/segmentation_platform/default_model/metadata_writer.h" | ||
#include "components/segmentation_platform/internal/proto/model_metadata.pb.h" | ||
#include "components/segmentation_platform/public/model_provider.h" | ||
|
||
namespace segmentation_platform { | ||
|
||
namespace { | ||
using optimization_guide::proto::OptimizationTarget; | ||
|
||
// Default parameters for Chrome Start model. | ||
constexpr OptimizationTarget kFeedUserOptimizationTarget = | ||
OptimizationTarget::OPTIMIZATION_TARGET_SEGMENTATION_FEED_USER; | ||
constexpr proto::TimeUnit kFeedUserTimeUnit = proto::TimeUnit::DAY; | ||
constexpr uint64_t kFeedUserBucketDuration = 1; | ||
constexpr int64_t kFeedUserSignalStorageLength = 28; | ||
constexpr int64_t kFeedUserMinSignalCollectionLength = 7; | ||
constexpr int64_t kFeedUserResultTTL = 1; | ||
|
||
// Discrete mapping parameters. | ||
constexpr char kFeedUserDiscreteMappingKey[] = "feed_user_segment"; | ||
constexpr float kFeedUserDiscreteMappingMinResult = 1; | ||
constexpr int64_t kFeedUserDiscreteMappingRank = 1; | ||
constexpr std::pair<float, int> kDiscreteMappings[] = { | ||
{kFeedUserDiscreteMappingMinResult, kFeedUserDiscreteMappingRank}}; | ||
|
||
// InputFeatures. | ||
constexpr MetadataWriter::UMAFeature kFeedUserUMAFeatures[] = { | ||
MetadataWriter::UMAFeature{ | ||
.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "ContentSuggestions.Feed.CardAction.Open", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{ | ||
.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "ContentSuggestions.Feed.CardAction.OpenInNewIncognitoTab", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{ | ||
.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "ContentSuggestions.Feed.CardAction.OpenInNewTab", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "MobileNTPMostVisited", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "MobileNewTabOpened", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "Home", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "MobileMenuRecentTabs", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "MobileMenuHistory", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}, | ||
MetadataWriter::UMAFeature{.signal_type = proto::SignalType::USER_ACTION, | ||
.name = "MobileTabReturnedToCurrentTab", | ||
.bucket_count = 14, | ||
.tensor_length = 1, | ||
.aggregation = proto::Aggregation::COUNT, | ||
.enum_ids_size = 0}}; | ||
|
||
#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0])) | ||
|
||
} // namespace | ||
|
||
FeedUserSegment::FeedUserSegment() | ||
: ModelProvider(kFeedUserOptimizationTarget) {} | ||
|
||
void FeedUserSegment::InitAndFetchModel( | ||
const ModelUpdatedCallback& model_updated_callback) { | ||
proto::SegmentationModelMetadata chrome_start_metadata; | ||
MetadataWriter writer(&chrome_start_metadata); | ||
writer.SetSegmentationMetadataConfig( | ||
kFeedUserTimeUnit, kFeedUserBucketDuration, kFeedUserSignalStorageLength, | ||
kFeedUserMinSignalCollectionLength, kFeedUserResultTTL); | ||
|
||
// Set discrete mapping. | ||
writer.AddDiscreteMappingEntries(kFeedUserDiscreteMappingKey, | ||
kDiscreteMappings, 1); | ||
|
||
// Set features. | ||
writer.AddUmaFeatures(kFeedUserUMAFeatures, ARRAY_SIZE(kFeedUserUMAFeatures)); | ||
|
||
constexpr int kModelVersion = 1; | ||
base::SequencedTaskRunnerHandle::Get()->PostTask( | ||
FROM_HERE, | ||
base::BindRepeating(model_updated_callback, kFeedUserOptimizationTarget, | ||
std::move(chrome_start_metadata), kModelVersion)); | ||
} | ||
|
||
void FeedUserSegment::ExecuteModelWithInput(const std::vector<float>& inputs, | ||
ExecutionCallback callback) { | ||
// Invalid inputs. | ||
if (inputs.size() != ARRAY_SIZE(kFeedUserUMAFeatures)) { | ||
base::SequencedTaskRunnerHandle::Get()->PostTask( | ||
FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt)); | ||
return; | ||
} | ||
|
||
float result = 0; | ||
const bool feed_opened = (inputs[0] + inputs[1] + inputs[2]) >= 2; | ||
const bool mv_tiles_used = inputs[3] >= 2; | ||
const bool home_or_ntp_used = (inputs[4] + inputs[5]) >= 4; | ||
|
||
if (feed_opened) { | ||
result = 1; | ||
} else if (mv_tiles_used) { | ||
result = 0.75; | ||
} else if (home_or_ntp_used) { | ||
result = 0.5; | ||
} | ||
|
||
base::SequencedTaskRunnerHandle::Get()->PostTask( | ||
FROM_HERE, base::BindOnce(std::move(callback), result)); | ||
} | ||
|
||
bool FeedUserSegment::ModelAvailable() { | ||
return true; | ||
} | ||
|
||
} // namespace segmentation_platform |
32 changes: 32 additions & 0 deletions
32
chrome/browser/segmentation_platform/default_model/feed_user_segment.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_SEGMENTATION_PLATFORM_DEFAULT_MODEL_FEED_USER_SEGMENT_H_ | ||
#define CHROME_BROWSER_SEGMENTATION_PLATFORM_DEFAULT_MODEL_FEED_USER_SEGMENT_H_ | ||
|
||
#include "components/segmentation_platform/public/model_provider.h" | ||
|
||
namespace segmentation_platform { | ||
|
||
// Segmentation Chrome Feed user model provider. Provides a default model and | ||
// metadata for the Feed user optimization target. | ||
class FeedUserSegment : public ModelProvider { | ||
public: | ||
FeedUserSegment(); | ||
~FeedUserSegment() override = default; | ||
|
||
FeedUserSegment(FeedUserSegment&) = delete; | ||
FeedUserSegment& operator=(FeedUserSegment&) = delete; | ||
|
||
// ModelProvider implementation. | ||
void InitAndFetchModel( | ||
const ModelUpdatedCallback& model_updated_callback) override; | ||
void ExecuteModelWithInput(const std::vector<float>& inputs, | ||
ExecutionCallback callback) override; | ||
bool ModelAvailable() override; | ||
}; | ||
|
||
} // namespace segmentation_platform | ||
|
||
#endif // CHROME_BROWSER_SEGMENTATION_PLATFORM_DEFAULT_MODEL_FEED_USER_SEGMENT_H_ |
101 changes: 101 additions & 0 deletions
101
chrome/browser/segmentation_platform/default_model/feed_user_segment_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/segmentation_platform/default_model/feed_user_segment.h" | ||
|
||
#include "base/run_loop.h" | ||
#include "base/test/task_environment.h" | ||
#include "components/segmentation_platform/internal/database/metadata_utils.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace segmentation_platform { | ||
|
||
class FeedUserModelTest : public testing::Test { | ||
public: | ||
FeedUserModelTest() = default; | ||
~FeedUserModelTest() override = default; | ||
|
||
void SetUp() override { | ||
feed_user_model_ = std::make_unique<FeedUserSegment>(); | ||
} | ||
|
||
void TearDown() override { | ||
feed_user_model_.reset(); | ||
RunUntilIdle(); | ||
} | ||
|
||
void RunUntilIdle() { task_environment_.RunUntilIdle(); } | ||
|
||
void ExpectInitAndFetchModel() { | ||
base::RunLoop loop; | ||
feed_user_model_->InitAndFetchModel( | ||
base::BindRepeating(&FeedUserModelTest::OnInitFinishedCallback, | ||
base::Unretained(this), loop.QuitClosure())); | ||
loop.Run(); | ||
} | ||
|
||
void OnInitFinishedCallback( | ||
base::RepeatingClosure closure, | ||
optimization_guide::proto::OptimizationTarget target, | ||
proto::SegmentationModelMetadata metadata, | ||
int64_t) { | ||
EXPECT_EQ(metadata_utils::ValidateMetadataAndFeatures(metadata), | ||
metadata_utils::ValidationResult::kValidationSuccess); | ||
std::move(closure).Run(); | ||
} | ||
|
||
void ExpectExecutionWithInput(const std::vector<float>& inputs, | ||
bool expected_error, | ||
float expected_result) { | ||
base::RunLoop loop; | ||
feed_user_model_->ExecuteModelWithInput( | ||
inputs, base::BindOnce(&FeedUserModelTest::OnExecutionFinishedCallback, | ||
base::Unretained(this), loop.QuitClosure(), | ||
expected_error, expected_result)); | ||
loop.Run(); | ||
} | ||
|
||
void OnExecutionFinishedCallback(base::RepeatingClosure closure, | ||
bool expected_error, | ||
float expected_result, | ||
const absl::optional<float>& result) { | ||
if (expected_error) { | ||
EXPECT_FALSE(result.has_value()); | ||
} else { | ||
EXPECT_TRUE(result.has_value()); | ||
EXPECT_EQ(result.value(), expected_result); | ||
} | ||
std::move(closure).Run(); | ||
} | ||
|
||
protected: | ||
base::test::TaskEnvironment task_environment_; | ||
std::unique_ptr<FeedUserSegment> feed_user_model_; | ||
}; | ||
|
||
TEST_F(FeedUserModelTest, InitAndFetchModel) { | ||
ExpectInitAndFetchModel(); | ||
} | ||
|
||
TEST_F(FeedUserModelTest, ExecuteModelWithInput) { | ||
std::vector<float> input(9, 0); | ||
|
||
ExpectExecutionWithInput(input, false, 0); | ||
|
||
input[4] = 3; | ||
input[5] = 2; | ||
ExpectExecutionWithInput(input, false, 0.5); | ||
|
||
input[3] = 3; | ||
ExpectExecutionWithInput(input, false, 0.75); | ||
|
||
input[0] = 1; | ||
input[2] = 2; | ||
ExpectExecutionWithInput(input, false, 1); | ||
|
||
ExpectExecutionWithInput({}, true, 0); | ||
ExpectExecutionWithInput({1, 2}, true, 0); | ||
} | ||
|
||
} // namespace segmentation_platform |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.