/// <inheritdoc/> protected override void UpdateFactors(int u, int i, int j, bool update_u, bool update_i, bool update_j) { double x_uij = Predict(u, i) - Predict(u, j); double one_over_one_plus_ex = 1 / (1 + Math.Exp(x_uij)); double learn_rate_u = learn_rate; double learn_rate_i = learn_rate; double learn_rate_j = learn_rate; // TODO do this via sampling, not learn rate modification if (!TestUsers.Contains(u)) { learn_rate_u *= NonTestModifier; } if (!TestItems.Contains(i)) { learn_rate_i *= NonTestModifier; } if (!TestItems.Contains(j)) { learn_rate_j *= NonTestModifier; } // adjust bias terms if (update_i) { double bias_update = one_over_one_plus_ex - BiasReg * item_bias[i]; item_bias[i] += learn_rate * bias_update; } if (update_j) { double bias_update = -one_over_one_plus_ex - BiasReg * item_bias[j]; item_bias[j] += learn_rate * bias_update; } // adjust factors for (int f = 0; f < num_factors; f++) { double w_uf = user_factors[u, f]; double h_if = item_factors[i, f]; double h_jf = item_factors[j, f]; if (update_u) { double uf_update = (h_if - h_jf) * one_over_one_plus_ex - reg_u * w_uf; user_factors[u, f] = w_uf + learn_rate_u * uf_update; } if (update_i) { double if_update = w_uf * one_over_one_plus_ex - reg_i * h_if; item_factors[i, f] = h_if + learn_rate_i * if_update; } if (update_j) { double jf_update = -w_uf * one_over_one_plus_ex - reg_j * h_jf; item_factors[j, f] = h_jf + learn_rate_j * jf_update; } } }