OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/translate/core/browser/translate_ranker_impl.h" | 5 #include "components/translate/core/browser/translate_ranker_impl.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
16 #include "base/metrics/metrics_hashes.h" | 16 #include "base/metrics/metrics_hashes.h" |
17 #include "base/profiler/scoped_tracker.h" | 17 #include "base/profiler/scoped_tracker.h" |
18 #include "base/strings/string_number_conversions.h" | |
19 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
20 #include "base/task_runner.h" | 19 #include "base/task_runner.h" |
21 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
22 #include "components/metrics/proto/translate_event.pb.h" | 21 #include "components/metrics/proto/translate_event.pb.h" |
23 #include "components/translate/core/browser/proto/ranker_model.pb.h" | 22 #include "components/translate/core/browser/proto/ranker_model.pb.h" |
24 #include "components/translate/core/browser/proto/translate_ranker_model.pb.h" | 23 #include "components/translate/core/browser/proto/translate_ranker_model.pb.h" |
25 #include "components/translate/core/browser/ranker_model.h" | 24 #include "components/translate/core/browser/ranker_model.h" |
26 #include "components/translate/core/browser/translate_download_manager.h" | |
27 #include "components/translate/core/browser/translate_prefs.h" | |
28 #include "components/translate/core/browser/translate_url_fetcher.h" | |
29 #include "components/translate/core/common/translate_switches.h" | 25 #include "components/translate/core/common/translate_switches.h" |
30 #include "components/ukm/public/ukm_entry_builder.h" | 26 #include "components/ukm/public/ukm_entry_builder.h" |
31 #include "components/ukm/public/ukm_recorder.h" | 27 #include "components/ukm/public/ukm_recorder.h" |
32 #include "components/variations/variations_associated_data.h" | 28 #include "components/variations/variations_associated_data.h" |
33 #include "url/gurl.h" | 29 #include "url/gurl.h" |
34 | 30 |
35 namespace translate { | 31 namespace translate { |
36 | 32 |
37 namespace { | 33 namespace { |
38 | 34 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 ignored_count(ignored), | 95 ignored_count(ignored), |
100 total_count(accepted_count + denied_count + ignored_count), | 96 total_count(accepted_count + denied_count + ignored_count), |
101 src_lang(src), | 97 src_lang(src), |
102 dst_lang(dst), | 98 dst_lang(dst), |
103 country(cntry), | 99 country(cntry), |
104 app_locale(locale), | 100 app_locale(locale), |
105 accepted_ratio(SafeRatio(accepted_count, total_count)), | 101 accepted_ratio(SafeRatio(accepted_count, total_count)), |
106 denied_ratio(SafeRatio(denied_count, total_count)), | 102 denied_ratio(SafeRatio(denied_count, total_count)), |
107 ignored_ratio(SafeRatio(ignored_count, total_count)) {} | 103 ignored_ratio(SafeRatio(ignored_count, total_count)) {} |
108 | 104 |
109 TranslateRankerFeatures::TranslateRankerFeatures(const TranslatePrefs& prefs, | 105 // TODO(hamelphi): Log locale in TranslateEventProtos. |
110 const std::string& src, | 106 TranslateRankerFeatures::TranslateRankerFeatures( |
111 const std::string& dst, | 107 const metrics::TranslateEventProto& translate_event) |
112 const std::string& locale) | 108 : TranslateRankerFeatures(translate_event.accept_count(), |
113 : TranslateRankerFeatures(prefs.GetTranslationAcceptedCount(src), | 109 translate_event.decline_count(), |
114 prefs.GetTranslationDeniedCount(src), | 110 translate_event.ignore_count(), |
115 prefs.GetTranslationIgnoredCount(src), | 111 translate_event.source_language(), |
116 src, | 112 translate_event.target_language(), |
117 dst, | 113 translate_event.country(), |
118 prefs.GetCountry(), | 114 "" /*locale*/) {} |
119 locale) {} | |
120 | 115 |
121 TranslateRankerFeatures::~TranslateRankerFeatures() {} | 116 TranslateRankerFeatures::~TranslateRankerFeatures() {} |
122 | 117 |
123 void TranslateRankerFeatures::WriteTo(std::ostream& stream) const { | 118 void TranslateRankerFeatures::WriteTo(std::ostream& stream) const { |
124 stream << "src_lang='" << src_lang << "', " | 119 stream << "src_lang='" << src_lang << "', " |
125 << "dst_lang='" << dst_lang << "', " | 120 << "dst_lang='" << dst_lang << "', " |
126 << "country='" << country << "', " | 121 << "country='" << country << "', " |
127 << "app_locale='" << app_locale << "', " | 122 << "app_locale='" << app_locale << "', " |
128 << "accept_count=" << accepted_count << ", " | 123 << "accept_count=" << accepted_count << ", " |
129 << "denied_count=" << denied_count << ", " | 124 << "denied_count=" << denied_count << ", " |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 183 |
189 void TranslateRankerImpl::EnableLogging(bool value) { | 184 void TranslateRankerImpl::EnableLogging(bool value) { |
190 is_logging_enabled_ = value; | 185 is_logging_enabled_ = value; |
191 } | 186 } |
192 | 187 |
193 uint32_t TranslateRankerImpl::GetModelVersion() const { | 188 uint32_t TranslateRankerImpl::GetModelVersion() const { |
194 return model_ ? model_->proto().translate().version() : 0; | 189 return model_ ? model_->proto().translate().version() : 0; |
195 } | 190 } |
196 | 191 |
197 bool TranslateRankerImpl::ShouldOfferTranslation( | 192 bool TranslateRankerImpl::ShouldOfferTranslation( |
198 const TranslatePrefs& translate_prefs, | |
199 const std::string& src_lang, | |
200 const std::string& dst_lang, | |
201 metrics::TranslateEventProto* translate_event) { | 193 metrics::TranslateEventProto* translate_event) { |
202 DCHECK(sequence_checker_.CalledOnValidSequence()); | 194 DCHECK(sequence_checker_.CalledOnValidSequence()); |
203 // The ranker is a gate in the "show a translation prompt" flow. To retain | 195 // The ranker is a gate in the "show a translation prompt" flow. To retain |
204 // the pre-existing functionality, it defaults to returning true in the | 196 // the pre-existing functionality, it defaults to returning true in the |
205 // absence of a model or if enforcement is disabled. As this is ranker is | 197 // absence of a model or if enforcement is disabled. As this is ranker is |
206 // subsumed into a more general assist ranker, this default will go away | 198 // subsumed into a more general assist ranker, this default will go away |
207 // (or become False). | 199 // (or become False). |
208 const bool kDefaultResponse = true; | 200 const bool kDefaultResponse = true; |
209 | 201 |
210 translate_event->set_ranker_request_timestamp_sec( | 202 translate_event->set_ranker_request_timestamp_sec( |
(...skipping 16 matching lines...) Expand all Loading... |
227 return kDefaultResponse; | 219 return kDefaultResponse; |
228 } | 220 } |
229 | 221 |
230 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation"); | 222 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation"); |
231 | 223 |
232 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed. | 224 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed. |
233 tracked_objects::ScopedTracker tracking_profile( | 225 tracked_objects::ScopedTracker tracking_profile( |
234 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 226 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
235 "646711 translate::TranslateRankerImpl::ShouldOfferTranslation")); | 227 "646711 translate::TranslateRankerImpl::ShouldOfferTranslation")); |
236 | 228 |
237 TranslateRankerFeatures features( | 229 bool result = GetModelDecision(*translate_event); |
238 translate_prefs, src_lang, dst_lang, | |
239 TranslateDownloadManager::GetInstance()->application_locale()); | |
240 | 230 |
241 bool result = GetModelDecision(features); | |
242 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result); | 231 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result); |
243 | 232 |
244 translate_event->set_ranker_response( | 233 translate_event->set_ranker_response( |
245 result ? metrics::TranslateEventProto::SHOW | 234 result ? metrics::TranslateEventProto::SHOW |
246 : metrics::TranslateEventProto::DONT_SHOW); | 235 : metrics::TranslateEventProto::DONT_SHOW); |
247 | 236 |
248 if (!is_enforcement_enabled_ && !is_decision_override_enabled_) { | 237 if (!is_enforcement_enabled_ && !is_decision_override_enabled_) { |
249 return kDefaultResponse; | 238 return kDefaultResponse; |
250 } | 239 } |
251 | 240 |
252 return result; | 241 return result; |
253 } | 242 } |
254 | 243 |
255 bool TranslateRankerImpl::GetModelDecision( | 244 bool TranslateRankerImpl::GetModelDecision( |
256 const TranslateRankerFeatures& features) { | 245 const metrics::TranslateEventProto& translate_event) { |
257 DCHECK(sequence_checker_.CalledOnValidSequence()); | 246 DCHECK(sequence_checker_.CalledOnValidSequence()); |
258 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore"); | 247 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore"); |
259 DCHECK(model_ != nullptr); | 248 DCHECK(model_ != nullptr); |
260 const TranslateRankerModel::LogisticRegressionModel& logit = | 249 |
| 250 // TODO(hamelphi): consider deprecating TranslateRankerFeatures and move the |
| 251 // logic here. |
| 252 const TranslateRankerFeatures features(translate_event); |
| 253 |
| 254 const TranslateRankerModel::LogisticRegressionModel& lr_model = |
261 model_->proto().translate().logistic_regression_model(); | 255 model_->proto().translate().logistic_regression_model(); |
262 | 256 |
263 double dot_product = | 257 double dot_product = |
264 (features.accepted_count * logit.accept_count_weight()) + | 258 (features.accepted_count * lr_model.accept_count_weight()) + |
265 (features.denied_count * logit.decline_count_weight()) + | 259 (features.denied_count * lr_model.decline_count_weight()) + |
266 (features.ignored_count * logit.ignore_count_weight()) + | 260 (features.ignored_count * lr_model.ignore_count_weight()) + |
267 (features.accepted_ratio * logit.accept_ratio_weight()) + | 261 (features.accepted_ratio * lr_model.accept_ratio_weight()) + |
268 (features.denied_ratio * logit.decline_ratio_weight()) + | 262 (features.denied_ratio * lr_model.decline_ratio_weight()) + |
269 (features.ignored_ratio * logit.ignore_ratio_weight()) + | 263 (features.ignored_ratio * lr_model.ignore_ratio_weight()) + |
270 ScoreComponent(logit.source_language_weight(), features.src_lang) + | 264 ScoreComponent(lr_model.source_language_weight(), features.src_lang) + |
271 ScoreComponent(logit.target_language_weight(), features.dst_lang) + | 265 ScoreComponent(lr_model.target_language_weight(), features.dst_lang) + |
272 ScoreComponent(logit.country_weight(), features.country) + | 266 ScoreComponent(lr_model.country_weight(), features.country) + |
273 ScoreComponent(logit.locale_weight(), features.app_locale); | 267 ScoreComponent(lr_model.locale_weight(), features.app_locale); |
274 | 268 |
275 double score = Sigmoid(dot_product + logit.bias()); | 269 double score = Sigmoid(dot_product + lr_model.bias()); |
276 | 270 |
277 DVLOG(2) << "TranslateRankerImpl::GetModelDecision: " | 271 DVLOG(2) << "TranslateRankerImpl::GetModelDecision: " |
278 << "Score = " << score << ", Features=[" << features << "]"; | 272 << "Score = " << score << ", Features=[" << features << "]"; |
279 | 273 |
280 float decision_threshold = kTranslationOfferDefaultThreshold; | 274 float decision_threshold = kTranslationOfferDefaultThreshold; |
281 if (logit.threshold() > 0) { | 275 if (lr_model.threshold() > 0) { |
282 decision_threshold = logit.threshold(); | 276 decision_threshold = lr_model.threshold(); |
283 } | 277 } |
284 | 278 |
285 return score >= decision_threshold; | 279 return score >= decision_threshold; |
286 } | 280 } |
287 | 281 |
288 void TranslateRankerImpl::FlushTranslateEvents( | 282 void TranslateRankerImpl::FlushTranslateEvents( |
289 std::vector<metrics::TranslateEventProto>* events) { | 283 std::vector<metrics::TranslateEventProto>* events) { |
290 DCHECK(sequence_checker_.CalledOnValidSequence()); | 284 DCHECK(sequence_checker_.CalledOnValidSequence()); |
291 DVLOG(3) << "Flushing translate ranker events."; | 285 DVLOG(3) << "Flushing translate ranker events."; |
292 events->swap(event_cache_); | 286 events->swap(event_cache_); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 } | 365 } |
372 } | 366 } |
373 | 367 |
374 } // namespace translate | 368 } // namespace translate |
375 | 369 |
376 std::ostream& operator<<(std::ostream& stream, | 370 std::ostream& operator<<(std::ostream& stream, |
377 const translate::TranslateRankerFeatures& features) { | 371 const translate::TranslateRankerFeatures& features) { |
378 features.WriteTo(stream); | 372 features.WriteTo(stream); |
379 return stream; | 373 return stream; |
380 } | 374 } |
OLD | NEW |