Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: components/translate/core/browser/translate_ranker_impl.cc

Issue 2785493004: Integrate RankerModelLoader with TranslateRanker. (Closed)
Patch Set: disable logging on IOS Web View builds (attempt #1) Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/translate/core/browser/translate_ranker_impl.h"
6
7 #include <cmath>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/metrics/histogram_macros.h"
16 #include "base/profiler/scoped_tracker.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h"
19 #include "base/task_runner.h"
20 #include "base/threading/thread_task_runner_handle.h"
21 #include "components/metrics/proto/translate_event.pb.h"
22 #include "components/translate/core/browser/proto/ranker_model.pb.h"
23 #include "components/translate/core/browser/proto/translate_ranker_model.pb.h"
24 #include "components/translate/core/browser/ranker_model.h"
25 #include "components/translate/core/browser/translate_download_manager.h"
26 #include "components/translate/core/browser/translate_prefs.h"
27 #include "components/translate/core/browser/translate_url_fetcher.h"
28 #include "components/translate/core/common/translate_switches.h"
29 #include "components/variations/variations_associated_data.h"
30 #include "url/gurl.h"
31
32 namespace translate {
33
34 namespace {
35
36 using chrome_intelligence::RankerModel;
37 using chrome_intelligence::RankerModelProto;
38 using chrome_intelligence::TranslateRankerModel;
39
40 const double kTranslationOfferThreshold = 0.5;
41
42 const char kTranslateRankerModelFileName[] = "Translate Ranker Model";
43 const char kUmaPrefix[] = "Translate.Ranker";
44 const char kUnknown[] = "UNKNOWN";
45
46 double Sigmoid(double x) {
47 return 1.0 / (1.0 + exp(-x));
48 }
49
50 double SafeRatio(int numerator, int denominator) {
51 return denominator ? (numerator / static_cast<double>(denominator)) : 0.0;
52 }
53
54 double ScoreComponent(const google::protobuf::Map<std::string, float>& weights,
55 const std::string& key) {
56 auto i = weights.find(base::ToLowerASCII(key));
57 if (i == weights.end())
58 i = weights.find(kUnknown);
59 return i == weights.end() ? 0.0 : i->second;
60 }
61
62 RankerModelStatus ValidateModel(const RankerModel& model) {
63 if (model.proto().model_case() != RankerModelProto::kTranslate)
64 return RankerModelStatus::VALIDATION_FAILED;
65
66 if (model.proto().translate().model_revision_case() !=
67 TranslateRankerModel::kLogisticRegressionModel) {
68 return RankerModelStatus::INCOMPATIBLE;
69 }
70
71 return RankerModelStatus::OK;
72 }
73
74 } // namespace
75
76 const base::Feature kTranslateRankerQuery{"TranslateRankerQuery",
77 base::FEATURE_DISABLED_BY_DEFAULT};
78
79 const base::Feature kTranslateRankerEnforcement{
80 "TranslateRankerEnforcement", base::FEATURE_DISABLED_BY_DEFAULT};
81
82 #if defined(CWV_IMPLEMENTATION)
sdefresne 2017/04/04 09:40:23 This macro will not be defined when building the f
Roger McFarlane (Chromium) 2017/04/04 17:03:06 Thanks for clarifying that! Are you aware of any
Eugene But (OOO till 7-30) 2017/04/04 18:19:00 There is no way to check that. //component layer d
Roger McFarlane (Chromium) 2017/04/04 19:16:06 Fair enough. Added a member to track whether or n
83 const base::Feature kTranslateRankerLogging{"TranslateRankerLogging",
84 base::FEATURE_DISABLED_BY_DEFAULT};
85 #else
86 const base::Feature kTranslateRankerLogging{"TranslateRankerLogging",
87 base::FEATURE_ENABLED_BY_DEFAULT};
88 #endif
89
90 TranslateRankerFeatures::TranslateRankerFeatures() {}
91
92 TranslateRankerFeatures::TranslateRankerFeatures(int accepted,
93 int denied,
94 int ignored,
95 const std::string& src,
96 const std::string& dst,
97 const std::string& cntry,
98 const std::string& locale)
99 : accepted_count(accepted),
100 denied_count(denied),
101 ignored_count(ignored),
102 total_count(accepted_count + denied_count + ignored_count),
103 src_lang(src),
104 dst_lang(dst),
105 country(cntry),
106 app_locale(locale),
107 accepted_ratio(SafeRatio(accepted_count, total_count)),
108 denied_ratio(SafeRatio(denied_count, total_count)),
109 ignored_ratio(SafeRatio(ignored_count, total_count)) {}
110
111 TranslateRankerFeatures::TranslateRankerFeatures(const TranslatePrefs& prefs,
112 const std::string& src,
113 const std::string& dst,
114 const std::string& locale)
115 : TranslateRankerFeatures(prefs.GetTranslationAcceptedCount(src),
116 prefs.GetTranslationDeniedCount(src),
117 prefs.GetTranslationIgnoredCount(src),
118 src,
119 dst,
120 prefs.GetCountry(),
121 locale) {}
122
123 TranslateRankerFeatures::~TranslateRankerFeatures() {}
124
125 void TranslateRankerFeatures::WriteTo(std::ostream& stream) const {
126 stream << "src_lang='" << src_lang << "', "
127 << "dst_lang='" << dst_lang << "', "
128 << "country='" << country << "', "
129 << "app_locale='" << app_locale << "', "
130 << "accept_count=" << accepted_count << ", "
131 << "denied_count=" << denied_count << ", "
132 << "ignored_count=" << ignored_count << ", "
133 << "total_count=" << total_count << ", "
134 << "accept_ratio=" << accepted_ratio << ", "
135 << "decline_ratio=" << denied_ratio << ", "
136 << "ignore_ratio=" << ignored_ratio;
137 }
138
139 TranslateRankerImpl::TranslateRankerImpl(const base::FilePath& model_path,
140 const GURL& model_url)
141 : weak_ptr_factory_(this) {
142 if (IsQueryEnabled() || IsEnforcementEnabled()) {
143 model_loader_ = base::MakeUnique<RankerModelLoader>(
144 base::Bind(&ValidateModel),
145 base::Bind(&TranslateRankerImpl::OnModelAvailable,
146 weak_ptr_factory_.GetWeakPtr()),
147 model_path, model_url, kUmaPrefix);
148 model_loader_->Start();
149 }
150 }
151
152 TranslateRankerImpl::~TranslateRankerImpl() {}
153
154 // static
155 base::FilePath TranslateRankerImpl::GetModelPath(
156 const base::FilePath& data_dir) {
157 if (data_dir.empty())
158 return base::FilePath();
159
160 // Otherwise, look for the file in data dir.
161 return data_dir.AppendASCII(kTranslateRankerModelFileName);
162 }
163
164 // static
165 GURL TranslateRankerImpl::GetModelURL() {
166 // Allow override of the ranker model URL from the command line.
167 std::string raw_url;
168 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
169 if (command_line->HasSwitch(switches::kTranslateRankerModelURL)) {
170 raw_url =
171 command_line->GetSwitchValueASCII(switches::kTranslateRankerModelURL);
172 } else {
173 // Otherwise take the ranker model URL from the ranker query variation.
174 raw_url = variations::GetVariationParamValueByFeature(
175 kTranslateRankerQuery, switches::kTranslateRankerModelURL);
176 }
177
178 DVLOG(3) << switches::kTranslateRankerModelURL << " = " << raw_url;
179
180 return GURL(raw_url);
181 }
182
183 bool TranslateRankerImpl::IsLoggingEnabled() {
184 return base::FeatureList::IsEnabled(kTranslateRankerLogging);
185 }
186
187 bool TranslateRankerImpl::IsQueryEnabled() {
188 return base::FeatureList::IsEnabled(kTranslateRankerQuery);
189 }
190
191 bool TranslateRankerImpl::IsEnforcementEnabled() {
192 return base::FeatureList::IsEnabled(kTranslateRankerEnforcement);
193 }
194
195 int TranslateRankerImpl::GetModelVersion() const {
196 return model_ ? model_->proto().translate().version() : 0;
197 }
198
199 bool TranslateRankerImpl::ShouldOfferTranslation(
200 const TranslatePrefs& translate_prefs,
201 const std::string& src_lang,
202 const std::string& dst_lang) {
203 DCHECK(sequence_checker_.CalledOnValidSequence());
204 // The ranker is a gate in the "show a translation prompt" flow. To retain
205 // the pre-existing functionality, it defaults to returning true in the
206 // absence of a model or if enforcement is disabled. As this is ranker is
207 // subsumed into a more general assist ranker, this default will go away
208 // (or become False).
209 const bool kDefaultResponse = true;
210
211 if (model_loader_)
212 model_loader_->NotifyOfRankerActivity();
213
214 // If we don't have a model, request one and return the default.
215 if (model_ == nullptr) {
216 return kDefaultResponse;
217 }
218
219 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation");
220
221 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed.
222 tracked_objects::ScopedTracker tracking_profile(
223 FROM_HERE_WITH_EXPLICIT_FUNCTION(
224 "646711 translate::TranslateRankerImpl::ShouldOfferTranslation"));
225
226 TranslateRankerFeatures features(
227 translate_prefs, src_lang, dst_lang,
228 TranslateDownloadManager::GetInstance()->application_locale());
229
230 double score = CalculateScore(features);
231
232 DVLOG(2) << "TranslateRankerImpl::ShouldOfferTranslation: "
233 << "Score = " << score << ", Features=[" << features << "]";
234
235 bool result = (score >= kTranslationOfferThreshold);
236
237 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result);
238
239 return result;
240 }
241
242 double TranslateRankerImpl::CalculateScore(
243 const TranslateRankerFeatures& features) {
244 DCHECK(sequence_checker_.CalledOnValidSequence());
245 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore");
246 DCHECK(model_ != nullptr);
247 const TranslateRankerModel::LogisticRegressionModel& logit =
248 model_->proto().translate().logistic_regression_model();
249
250 double dot_product =
251 (features.accepted_count * logit.accept_count_weight()) +
252 (features.denied_count * logit.decline_count_weight()) +
253 (features.ignored_count * logit.ignore_count_weight()) +
254 (features.accepted_ratio * logit.accept_ratio_weight()) +
255 (features.denied_ratio * logit.decline_ratio_weight()) +
256 (features.ignored_ratio * logit.ignore_ratio_weight()) +
257 ScoreComponent(logit.source_language_weight(), features.src_lang) +
258 ScoreComponent(logit.dest_language_weight(), features.dst_lang) +
259 ScoreComponent(logit.country_weight(), features.country) +
260 ScoreComponent(logit.locale_weight(), features.app_locale);
261
262 return Sigmoid(dot_product + logit.bias());
263 }
264
265 void TranslateRankerImpl::FlushTranslateEvents(
266 std::vector<metrics::TranslateEventProto>* events) {
267 DCHECK(sequence_checker_.CalledOnValidSequence());
268 DVLOG(3) << "Flushing translate ranker events.";
269 events->swap(event_cache_);
270 event_cache_.clear();
271 }
272
273 void TranslateRankerImpl::AddTranslateEvent(
274 const metrics::TranslateEventProto& event) {
275 DCHECK(sequence_checker_.CalledOnValidSequence());
276 if (IsLoggingEnabled()) {
277 DVLOG(3) << "Adding translate ranker event.";
278 event_cache_.push_back(event);
279 }
280 }
281
282 void TranslateRankerImpl::OnModelAvailable(std::unique_ptr<RankerModel> model) {
283 DCHECK(sequence_checker_.CalledOnValidSequence());
284 model_ = std::move(model);
285 }
286
287 bool TranslateRankerImpl::CheckModelLoaderForTesting() {
288 return model_loader_ != nullptr;
289 }
290
291 } // namespace translate
292
293 std::ostream& operator<<(std::ostream& stream,
294 const translate::TranslateRankerFeatures& features) {
295 features.WriteTo(stream);
296 return stream;
297 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698