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/ntp_snippets/user_classifier.h" | 5 #include "components/ntp_snippets/user_classifier.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cfloat> | 8 #include <cfloat> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 arraysize(kMetricKeys) == | 84 arraysize(kMetricKeys) == |
85 static_cast<int>(UserClassifier::Metric::COUNT) && | 85 static_cast<int>(UserClassifier::Metric::COUNT) && |
86 arraysize(kLastTimeKeys) == | 86 arraysize(kLastTimeKeys) == |
87 static_cast<int>(UserClassifier::Metric::COUNT) && | 87 static_cast<int>(UserClassifier::Metric::COUNT) && |
88 arraysize(kInitialHoursBetweenEvents) == | 88 arraysize(kInitialHoursBetweenEvents) == |
89 static_cast<int>(UserClassifier::Metric::COUNT) && | 89 static_cast<int>(UserClassifier::Metric::COUNT) && |
90 arraysize(kInitialHoursBetweenEventsParams) == | 90 arraysize(kInitialHoursBetweenEventsParams) == |
91 static_cast<int>(UserClassifier::Metric::COUNT), | 91 static_cast<int>(UserClassifier::Metric::COUNT), |
92 "Fill in info for all metrics."); | 92 "Fill in info for all metrics."); |
93 | 93 |
94 double GetParamValue(const char* param_name, double default_value) { | |
95 std::string param_value_str = variations::GetVariationParamValueByFeature( | |
96 kArticleSuggestionsFeature, param_name); | |
97 double param_value = 0; | |
98 if (!base::StringToDouble(param_value_str, ¶m_value)) { | |
99 LOG_IF(WARNING, !param_value_str.empty()) | |
100 << "Invalid variation parameter for " << param_name; | |
101 return default_value; | |
102 } | |
103 return param_value; | |
104 } | |
105 | |
106 // Computes the discount rate. | 94 // Computes the discount rate. |
107 double GetDiscountRatePerHour() { | 95 double GetDiscountRatePerHour() { |
108 double discount_rate_per_day = | 96 double discount_rate_per_day = variations::GetVariationParamByFeatureAsDouble( |
109 GetParamValue(kDiscountRatePerDayParam, kDiscountRatePerDay); | 97 kArticleSuggestionsFeature, kDiscountRatePerDayParam, |
| 98 kDiscountRatePerDay); |
110 // Check for illegal values. | 99 // Check for illegal values. |
111 if (discount_rate_per_day <= 0 || discount_rate_per_day >= 1) { | 100 if (discount_rate_per_day <= 0 || discount_rate_per_day >= 1) { |
112 DLOG(WARNING) << "Illegal value " << discount_rate_per_day | 101 DLOG(WARNING) << "Illegal value " << discount_rate_per_day |
113 << " for the parameter " << kDiscountRatePerDayParam | 102 << " for the parameter " << kDiscountRatePerDayParam |
114 << " (must be strictly between 0 and 1; the default " | 103 << " (must be strictly between 0 and 1; the default " |
115 << kDiscountRatePerDay << " is used, instead)."; | 104 << kDiscountRatePerDay << " is used, instead)."; |
116 discount_rate_per_day = kDiscountRatePerDay; | 105 discount_rate_per_day = kDiscountRatePerDay; |
117 } | 106 } |
118 // Compute discount_rate_per_hour such that | 107 // Compute discount_rate_per_hour such that |
119 // discount_rate_per_day = 1 - e^{-discount_rate_per_hour * 24}. | 108 // discount_rate_per_day = 1 - e^{-discount_rate_per_hour * 24}. |
120 return std::log(1.0 / (1.0 - discount_rate_per_day)) / 24.0; | 109 return std::log(1.0 / (1.0 - discount_rate_per_day)) / 24.0; |
121 } | 110 } |
122 | 111 |
123 double GetInitialHoursBetweenEvents(UserClassifier::Metric metric) { | 112 double GetInitialHoursBetweenEvents(UserClassifier::Metric metric) { |
124 return GetParamValue( | 113 return variations::GetVariationParamByFeatureAsDouble( |
| 114 kArticleSuggestionsFeature, |
125 kInitialHoursBetweenEventsParams[static_cast<int>(metric)], | 115 kInitialHoursBetweenEventsParams[static_cast<int>(metric)], |
126 kInitialHoursBetweenEvents[static_cast<int>(metric)]); | 116 kInitialHoursBetweenEvents[static_cast<int>(metric)]); |
127 } | 117 } |
128 | 118 |
129 double GetMinHours() { | 119 double GetMinHours() { |
130 return GetParamValue(kMinHoursParam, kMinHours); | 120 return variations::GetVariationParamByFeatureAsDouble( |
| 121 kArticleSuggestionsFeature, kMinHoursParam, kMinHours); |
131 } | 122 } |
132 | 123 |
133 double GetMaxHours() { | 124 double GetMaxHours() { |
134 return GetParamValue(kMaxHoursParam, kMaxHours); | 125 return variations::GetVariationParamByFeatureAsDouble( |
| 126 kArticleSuggestionsFeature, kMaxHoursParam, kMaxHours); |
135 } | 127 } |
136 | 128 |
137 // Returns the new value of the metric using its |old_value|, assuming | 129 // Returns the new value of the metric using its |old_value|, assuming |
138 // |hours_since_last_time| hours have passed since it was last discounted. | 130 // |hours_since_last_time| hours have passed since it was last discounted. |
139 double DiscountMetric(double old_value, | 131 double DiscountMetric(double old_value, |
140 double hours_since_last_time, | 132 double hours_since_last_time, |
141 double discount_rate_per_hour) { | 133 double discount_rate_per_hour) { |
142 // Compute the new discounted average according to the formula | 134 // Compute the new discounted average according to the formula |
143 // avg_events := e^{-discount_rate_per_hour * hours_since} * avg_events | 135 // avg_events := e^{-discount_rate_per_hour * hours_since} * avg_events |
144 return std::exp(-discount_rate_per_hour * hours_since_last_time) * old_value; | 136 return std::exp(-discount_rate_per_hour * hours_since_last_time) * old_value; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 } | 180 } |
189 | 181 |
190 } // namespace | 182 } // namespace |
191 | 183 |
192 UserClassifier::UserClassifier(PrefService* pref_service) | 184 UserClassifier::UserClassifier(PrefService* pref_service) |
193 : pref_service_(pref_service), | 185 : pref_service_(pref_service), |
194 discount_rate_per_hour_(GetDiscountRatePerHour()), | 186 discount_rate_per_hour_(GetDiscountRatePerHour()), |
195 min_hours_(GetMinHours()), | 187 min_hours_(GetMinHours()), |
196 max_hours_(GetMaxHours()), | 188 max_hours_(GetMaxHours()), |
197 active_consumer_scrolls_at_least_once_per_hours_( | 189 active_consumer_scrolls_at_least_once_per_hours_( |
198 GetParamValue(kActiveConsumerScrollsAtLeastOncePerHoursParam, | 190 variations::GetVariationParamByFeatureAsDouble( |
199 kActiveConsumerScrollsAtLeastOncePerHours)), | 191 kArticleSuggestionsFeature, |
| 192 kActiveConsumerScrollsAtLeastOncePerHoursParam, |
| 193 kActiveConsumerScrollsAtLeastOncePerHours)), |
200 rare_user_opens_ntp_at_most_once_per_hours_( | 194 rare_user_opens_ntp_at_most_once_per_hours_( |
201 GetParamValue(kRareUserOpensNTPAtMostOncePerHoursParam, | 195 variations::GetVariationParamByFeatureAsDouble( |
202 kRareUserOpensNTPAtMostOncePerHours)) { | 196 kArticleSuggestionsFeature, |
| 197 kRareUserOpensNTPAtMostOncePerHoursParam, |
| 198 kRareUserOpensNTPAtMostOncePerHours)) { |
203 // The pref_service_ can be null in tests. | 199 // The pref_service_ can be null in tests. |
204 if (!pref_service_) { | 200 if (!pref_service_) { |
205 return; | 201 return; |
206 } | 202 } |
207 | 203 |
208 // TODO(jkrcal): Store the current discount rate per hour into prefs. If it | 204 // TODO(jkrcal): Store the current discount rate per hour into prefs. If it |
209 // differs from the previous value, rescale the metric values so that the | 205 // differs from the previous value, rescale the metric values so that the |
210 // expectation does not change abruptly! | 206 // expectation does not change abruptly! |
211 | 207 |
212 // Initialize the prefs storing the last time: the counter has just started! | 208 // Initialize the prefs storing the last time: the counter has just started! |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 | 373 |
378 void UserClassifier::SetMetricValue(Metric metric, double metric_value) { | 374 void UserClassifier::SetMetricValue(Metric metric, double metric_value) { |
379 pref_service_->SetDouble(kMetricKeys[static_cast<int>(metric)], metric_value); | 375 pref_service_->SetDouble(kMetricKeys[static_cast<int>(metric)], metric_value); |
380 } | 376 } |
381 | 377 |
382 void UserClassifier::ClearMetricValue(Metric metric) { | 378 void UserClassifier::ClearMetricValue(Metric metric) { |
383 pref_service_->ClearPref(kMetricKeys[static_cast<int>(metric)]); | 379 pref_service_->ClearPref(kMetricKeys[static_cast<int>(metric)]); |
384 } | 380 } |
385 | 381 |
386 } // namespace ntp_snippets | 382 } // namespace ntp_snippets |
OLD | NEW |