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

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

Issue 2565873002: [translate] Add translate ranker model loader. (Closed)
Patch Set: for asan testing only - DO NOT COMMIT Created 3 years, 10 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/translate_download_manager.h"
25 #include "components/translate/core/browser/translate_prefs.h"
26 #include "components/translate/core/browser/translate_url_fetcher.h"
27 #include "components/translate/core/common/translate_switches.h"
28 #include "components/variations/variations_associated_data.h"
29 #include "url/gurl.h"
30
31 namespace translate {
32
33 namespace {
34
35 const double kTranslationOfferThreshold = 0.5;
36
37 const char kTranslateRankerModelFileName[] = "Translate Ranker Model";
38 const char kUmaPrefix[] = "Translate.Ranker";
39 const char kUnknown[] = "UNKNOWN";
40
41 double Sigmoid(double x) {
42 return 1.0 / (1.0 + exp(-x));
43 }
44
45 double ScoreComponent(const google::protobuf::Map<std::string, float>& weights,
46 const std::string& key) {
47 auto i = weights.find(base::ToLowerASCII(key));
48 if (i == weights.end())
49 i = weights.find(kUnknown);
50 return i == weights.end() ? 0.0 : i->second;
51 }
52
53 RankerModelStatus ValidateModel(const chrome_intelligence::RankerModel& model) {
54 if (model.model_case() != chrome_intelligence::RankerModel::kTranslate)
55 return RankerModelStatus::VALIDATION_FAILED;
56
57 if (model.translate().model_revision_case() !=
58 chrome_intelligence::TranslateRankerModel::kLogisticRegressionModel) {
59 return RankerModelStatus::INCOMPATIBLE;
60 }
61
62 return RankerModelStatus::OK;
63 }
64
65 } // namespace
66
67 const base::Feature kTranslateRankerQuery{"TranslateRankerQuery",
68 base::FEATURE_DISABLED_BY_DEFAULT};
69
70 const base::Feature kTranslateRankerEnforcement{
71 "TranslateRankerEnforcement", base::FEATURE_DISABLED_BY_DEFAULT};
72
73 const base::Feature kTranslateRankerLogging{"TranslateRankerLogging",
74 base::FEATURE_DISABLED_BY_DEFAULT};
75
76 TranslateRankerFeatures::TranslateRankerFeatures() {}
77
78 TranslateRankerFeatures::TranslateRankerFeatures(const TranslatePrefs& prefs,
79 const std::string& src,
80 const std::string& dst,
81 const std::string& locale)
82 : accepted_count(prefs.GetTranslationAcceptedCount(src)),
83 denied_count(prefs.GetTranslationDeniedCount(src)),
84 ignored_count(prefs.GetTranslationIgnoredCount(src)),
85 total_count(accepted_count + denied_count + ignored_count),
86 src_lang(src),
87 dst_lang(dst),
88 country(prefs.GetCountry()),
89 app_locale(locale),
90 accepted_ratio(total_count ? (accepted_count / total_count) : 0.0),
91 denied_ratio(total_count ? (denied_count / total_count) : 0.0),
92 ignored_ratio(total_count ? (ignored_count / total_count) : 0.0) {}
93
94 TranslateRankerFeatures::~TranslateRankerFeatures() {}
95
96 void TranslateRankerFeatures::WriteTo(std::ostream& stream) const {
97 stream << "src_lang='" << src_lang << "', "
98 << "dst_lang='" << dst_lang << "', "
99 << "country='" << country << "', "
100 << "app_locale='" << app_locale << "', "
101 << "accept_count=" << accepted_count << ", "
102 << "denied_count=" << denied_count << ", "
103 << "ignored_count=" << ignored_count << ", "
104 << "total_count=" << total_count << ", "
105 << "accept_ratio=" << accepted_ratio << ", "
106 << "decline_ratio=" << denied_ratio << ", "
107 << "ignore_ratio=" << ignored_ratio;
108 }
109
110 TranslateRankerImpl::TranslateRankerImpl(const base::FilePath& model_path,
111 const GURL& model_url)
112 : weak_ptr_factory_(this) {
113 model_loader_ = base::MakeUnique<RankerModelLoader>(
114 base::Bind(&ValidateModel),
115 base::Bind(&TranslateRankerImpl::OnModelAvailable,
116 weak_ptr_factory_.GetWeakPtr()),
117 model_path, model_url, kUmaPrefix);
118 model_loader_->Start();
119 }
120
121 TranslateRankerImpl::~TranslateRankerImpl() {}
122
123 // static
124 base::FilePath TranslateRankerImpl::GetModelPath(
125 const base::FilePath& data_dir) {
126 if (data_dir.empty())
127 return base::FilePath();
128
129 // Otherwise, look for the file in data dir.
130 return data_dir.AppendASCII(kTranslateRankerModelFileName);
131 }
132
133 // static
134 GURL TranslateRankerImpl::GetModelURL() {
135 // Allow override of the ranker model URL from the command line.
136 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
137 if (command_line->HasSwitch(switches::kTranslateRankerModelURL)) {
138 return GURL(
139 command_line->GetSwitchValueASCII(switches::kTranslateRankerModelURL));
140 }
141
142 // Otherwise take the ranker model URL from the ranker query variation.
143 const std::string raw_url = variations::GetVariationParamValueByFeature(
144 kTranslateRankerQuery, switches::kTranslateRankerModelURL);
145
146 DVLOG(3) << switches::kTranslateRankerModelURL << " = " << raw_url;
147
148 return GURL(raw_url);
149 }
150
151 bool TranslateRankerImpl::IsLoggingEnabled() {
152 return base::FeatureList::IsEnabled(kTranslateRankerLogging);
153 }
154
155 bool TranslateRankerImpl::IsQueryEnabled() {
156 return base::FeatureList::IsEnabled(kTranslateRankerQuery) ||
157 IsEnforcementEnabled() || IsLoggingEnabled();
158 }
159
160 bool TranslateRankerImpl::IsEnforcementEnabled() {
161 return base::FeatureList::IsEnabled(kTranslateRankerEnforcement);
162 }
163
164 int TranslateRankerImpl::GetModelVersion() const {
165 return model_ ? model_->translate().version() : 0;
166 }
167
168 bool TranslateRankerImpl::ShouldOfferTranslation(
169 const TranslatePrefs& translate_prefs,
170 const std::string& src_lang,
171 const std::string& dst_lang) {
172 DCHECK(sequence_checker_.CalledOnValidSequence());
173 // The ranker is a gate in the "show a translation prompt" flow. To retain
174 // the pre-existing functionality, it defaults to returning true in the
175 // absence of a model or if enforcement is disabled. As this is ranker is
176 // subsumed into a more general assist ranker, this default will go away
177 // (or become False).
178 const bool kDefaultResponse = true;
179
180 // If we don't have a model, request one and return the default.
181 if (model_ == nullptr) {
182 return kDefaultResponse;
183 }
184
185 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation");
186
187 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed.
188 tracked_objects::ScopedTracker tracking_profile(
189 FROM_HERE_WITH_EXPLICIT_FUNCTION(
190 "646711 translate::TranslateRankerImpl::ShouldOfferTranslation"));
191
192 TranslateRankerFeatures features(
193 translate_prefs, src_lang, dst_lang,
194 TranslateDownloadManager::GetInstance()->application_locale());
195
196 double score = CalculateScore(features);
197
198 DVLOG(2) << "TranslateRankerImpl::ShouldOfferTranslation: "
199 << "Score = " << score << ", Features=[" << features << "]";
200
201 bool result = (score >= kTranslationOfferThreshold);
202
203 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result);
204
205 return result;
206 }
207
208 double TranslateRankerImpl::CalculateScore(
209 const TranslateRankerFeatures& features) {
210 DCHECK(sequence_checker_.CalledOnValidSequence());
211 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore");
212 DCHECK(model_ != nullptr);
213 const chrome_intelligence::TranslateRankerModel::LogisticRegressionModel&
214 logit = model_->translate().logistic_regression_model();
215
216 double dot_product =
217 (features.accepted_ratio * logit.accept_ratio_weight()) +
218 (features.denied_ratio * logit.decline_ratio_weight()) +
219 (features.ignored_ratio * logit.ignore_ratio_weight()) +
220 ScoreComponent(logit.source_language_weight(), features.src_lang) +
221 ScoreComponent(logit.dest_language_weight(), features.dst_lang) +
222 ScoreComponent(logit.country_weight(), features.country) +
223 ScoreComponent(logit.locale_weight(), features.app_locale);
224
225 return Sigmoid(dot_product + logit.bias());
226 }
227
228 void TranslateRankerImpl::FlushTranslateEvents(
229 std::vector<metrics::TranslateEventProto>* events) {
230 DCHECK(sequence_checker_.CalledOnValidSequence());
231 DVLOG(3) << "Flushing translate ranker events.";
232 events->swap(event_cache_);
233 event_cache_.clear();
234 }
235
236 void TranslateRankerImpl::AddTranslateEvent(
237 const metrics::TranslateEventProto& event) {
238 DCHECK(sequence_checker_.CalledOnValidSequence());
239 DVLOG(3) << "Adding translate ranker event.";
240 if (IsLoggingEnabled())
241 event_cache_.push_back(event);
242 }
243
244 void TranslateRankerImpl::OnModelAvailable(
245 std::unique_ptr<chrome_intelligence::RankerModel> model) {
246 DCHECK(sequence_checker_.CalledOnValidSequence());
247 model_ = std::move(model);
248 }
249
250 } // namespace translate
251
252 std::ostream& operator<<(std::ostream& stream,
253 const translate::TranslateRankerFeatures& features) {
254 features.WriteTo(stream);
255 return stream;
256 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698