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 <float.h> | 7 #include <float.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <string> | 10 #include <string> |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 // Ignore events within the same "browsing session". | 108 // Ignore events within the same "browsing session". |
109 if (hours_since_last_time < kMinHours) | 109 if (hours_since_last_time < kMinHours) |
110 return; | 110 return; |
111 SetLastTimeToNow(last_time_pref_name); | 111 SetLastTimeToNow(last_time_pref_name); |
112 | 112 |
113 double avg_events_per_hour = pref_service_->GetDouble(metric_pref_name); | 113 double avg_events_per_hour = pref_service_->GetDouble(metric_pref_name); |
114 // Compute and store the new discounted average according to the formula | 114 // Compute and store the new discounted average according to the formula |
115 // avg_events := 1 + e^{-discount_rate_per_hour * hours_since} * avg_events. | 115 // avg_events := 1 + e^{-discount_rate_per_hour * hours_since} * avg_events. |
116 double new_avg_events_per_hour = | 116 double new_avg_events_per_hour = |
117 1 + | 117 1 + |
118 std::exp(discount_rate_per_hour_ * hours_since_last_time) * | 118 std::exp(-discount_rate_per_hour_ * hours_since_last_time) * |
119 avg_events_per_hour; | 119 avg_events_per_hour; |
120 pref_service_->SetDouble(metric_pref_name, new_avg_events_per_hour); | 120 pref_service_->SetDouble(metric_pref_name, new_avg_events_per_hour); |
121 } | 121 } |
122 | 122 |
123 double UserClassifier::GetEstimateHoursBetweenEvents( | 123 double UserClassifier::GetEstimateHoursBetweenEvents( |
124 const char* metric_pref_name) { | 124 const char* metric_pref_name) { |
125 double avg_events_per_hour = pref_service_->GetDouble(metric_pref_name); | 125 double avg_events_per_hour = pref_service_->GetDouble(metric_pref_name); |
126 | 126 |
127 // Right after the first update, the metric is equal to 1. | 127 // Right after the first update, the metric is equal to 1. |
128 if (avg_events_per_hour <= 1) | 128 if (avg_events_per_hour <= 1) |
129 return kMaxHours; | 129 return kMaxHours; |
130 | 130 |
131 // This is the estimate with the assumption that last event happened right | 131 // This is the estimate with the assumption that last event happened right |
132 // now and the system is in the steady-state. Solve estimate_hours in the | 132 // now and the system is in the steady-state. Solve estimate_hours in the |
133 // steady-state equation: | 133 // steady-state equation: |
134 // avg_events = 1 + e^{-discount_rate * estimate_hours} * avg_events. | 134 // avg_events = 1 + e^{-discount_rate * estimate_hours} * avg_events, |
| 135 // i.e. |
| 136 // -discount_rate * estimate_hours = log((avg_events - 1) / avg_events), |
| 137 // discount_rate * estimate_hours = log(avg_events / (avg_events - 1)), |
| 138 // estimate_hours = log(avg_events / (avg_events - 1)) / discount_rate. |
135 return std::min(kMaxHours, | 139 return std::min(kMaxHours, |
136 std::log(avg_events_per_hour / (avg_events_per_hour - 1)) / | 140 std::log(avg_events_per_hour / (avg_events_per_hour - 1)) / |
137 discount_rate_per_hour_); | 141 discount_rate_per_hour_); |
138 } | 142 } |
139 | 143 |
140 double UserClassifier::GetHoursSinceLastTime( | 144 double UserClassifier::GetHoursSinceLastTime( |
141 const char* last_time_pref_name) { | 145 const char* last_time_pref_name) { |
142 if (!pref_service_->HasPrefPath(last_time_pref_name)) | 146 if (!pref_service_->HasPrefPath(last_time_pref_name)) |
143 return DBL_MAX; | 147 return DBL_MAX; |
144 | 148 |
145 base::TimeDelta since_last_time = | 149 base::TimeDelta since_last_time = |
146 base::Time::Now() - base::Time::FromInternalValue( | 150 base::Time::Now() - base::Time::FromInternalValue( |
147 pref_service_->GetInt64(last_time_pref_name)); | 151 pref_service_->GetInt64(last_time_pref_name)); |
148 return since_last_time.InSecondsF() / 3600; | 152 return since_last_time.InSecondsF() / 3600; |
149 } | 153 } |
150 | 154 |
151 void UserClassifier::SetLastTimeToNow(const char* last_time_pref_name) { | 155 void UserClassifier::SetLastTimeToNow(const char* last_time_pref_name) { |
152 pref_service_->SetInt64(last_time_pref_name, | 156 pref_service_->SetInt64(last_time_pref_name, |
153 base::Time::Now().ToInternalValue()); | 157 base::Time::Now().ToInternalValue()); |
154 } | 158 } |
155 | 159 |
156 } // namespace ntp_snippets | 160 } // namespace ntp_snippets |
OLD | NEW |