public virtual float Predict(Feedback feedback) { int userId = UsersMap.ToInternalID(feedback.User.Id); int itemId = ItemsMap.ToInternalID(feedback.Item.Id); List <Tuple <int, float> > features = new List <Tuple <int, float> >(); if (!IgnoreFeaturesOnPrediction) { features = feedback.GetAllAttributes().Select(a => FeatureBuilder.TranslateAttribute(a)).NormalizeSumToOne().ToList(); } bool newUser = (userId > MaxUserID); bool newItem = (itemId > MaxItemID); float userAttrsTerm = 0, itemAttrsTerm = 0; foreach (var feat in features) { // if feat_index is greater than MaxFeatureId it means that the feature is new in test set so its factors has not been learnt if (feat.Item1 < NumTrainFeaturs) { float x_z = feat.Item2; userAttrsTerm += newUser ? 0 : x_z *MatrixExtensions.RowScalarProduct(feature_factors, feat.Item1, user_factors, userId); itemAttrsTerm += newItem ? 0 : x_z *MatrixExtensions.RowScalarProduct(feature_factors, feat.Item1, item_factors, itemId); } } float itemBias = newItem ? 0 : item_bias[itemId]; float userItemTerm = (newUser || newItem) ? 0 : MatrixExtensions.RowScalarProduct(user_factors, userId, item_factors, itemId); return(itemBias + userItemTerm + userAttrsTerm + itemAttrsTerm); }
public override float Predict(int user_id, int item_id) { string userIdOrg = UsersMap.ToOriginalID(user_id); string itemIdOrg = ItemsMap.ToOriginalID(item_id); List <Tuple <int, float> > features = new List <Tuple <int, float> >(); if (!IgnoreFeaturesOnPrediction && Split.Container.FeedbacksDic.ContainsKey(userIdOrg, itemIdOrg)) { var feedback = Split.Container.FeedbacksDic[userIdOrg, itemIdOrg]; features = feedback.GetAllAttributes().Select(a => FeatureBuilder.TranslateAttribute(a)).NormalizeSumToOne(Normalize).ToList(); } bool newUser = (user_id > MaxUserID); bool newItem = (item_id > MaxItemID); float userAttrsTerm = 0, itemAttrsTerm = 0; foreach (var feat in features) { // if feat_index is greater than MaxFeatureId it means that the feature is new in test set so its factors has not been learnt if (feat.Item1 < NumTrainFeaturs) { float x_z = feat.Item2; userAttrsTerm += newUser ? 0 : x_z *MatrixExtensions.RowScalarProduct(feature_factors, feat.Item1, user_factors, user_id); itemAttrsTerm += newItem ? 0 : x_z *MatrixExtensions.RowScalarProduct(feature_factors, feat.Item1, item_factors, item_id); } } float itemBias = newItem ? 0 : item_bias[item_id]; float userItemTerm = (newUser || newItem) ? 0 : MatrixExtensions.RowScalarProduct(user_factors, user_id, item_factors, item_id); return(itemBias + userItemTerm + userAttrsTerm + itemAttrsTerm); }
IList <float> PredictPercentages(int user_id, int item_id) { var percentages = new float[label_id_to_value.Count]; float percentage_sum = 0; for (int label = 0; label < percentages.Length - 1; label++) { double score = 0; if (user_id <= MaxUserID) { score += user_biases[label, user_id]; } if (item_id <= MaxItemID) { score += item_biases[label, item_id]; } if (user_id <= MaxUserID && item_id <= MaxItemID) { score += MatrixExtensions.RowScalarProduct(user_factors[label], user_id, item_factors[label], item_id); } float p = (float)(1 / (1 + Math.Exp(-score))); percentages[label] = p; percentage_sum += p; } percentages[percentages.Length - 1] = 1 - percentage_sum; return(percentages); }
/// public override float Predict(int user_id, int item_id) { if (user_id >= user_factors.dim1) { Console.Error.WriteLine("user is unknown: " + user_id); return(float.MinValue); } float[] est_factors = MapToLatentFactorSpace(item_id); return(MatrixExtensions.RowScalarProduct(user_factors, user_id, est_factors)); }
protected virtual void UpdatePosSampler() { double[] levelsAvg = new double[PosLevels.Count]; for (int i = 0; i < PosLevels.Count; i++) { foreach (Feedback f in LevelPosFeedback[PosLevels[i]]) { int user_id = UsersMap.ToInternalID(f.User.Id); int item_id = ItemsMap.ToInternalID(f.Item.Id); levelsAvg[i] += MatrixExtensions.RowScalarProduct(user_factors, user_id, item_factors, item_id); } //Console.WriteLine(levelsAvg[i]); levelsAvg[i] /= LevelPosFeedback[PosLevels[i]].Count; } double avgSum = levelsAvg.Sum(); double[] levelWeights = new double[PosLevels.Count]; for (int i = 0; i < PosLevels.Count; i++) { levelWeights[i] = levelsAvg[i] / avgSum; } double sum = 0; for (int i = 0; i < PosLevels.Count; i++) { sum += levelWeights[i] * LevelPosFeedback[PosLevels[i]].Count; } double[] levelPros = new double[PosLevels.Count]; for (int i = 0; i < PosLevels.Count; i++) { levelPros[i] = levelWeights[i] * LevelPosFeedback[PosLevels[i]].Count / sum; } string weights = levelWeights.Select(p => string.Format("{0:0.00}", p)).Aggregate((a, b) => a + " " + b); Logger.Current.Info(weights); //var temp = SampledCount.Values.Take(10).Select(i => i.ToString()).Aggregate((a, b) => a + " " + b); //Console.WriteLine(temp); _posLevelSampler = new Categorical(levelPros); }
[Test()] public void TestRowScalarProduct() { var matrix = new Matrix <float>(5, 5); float[] row = { 1, 2, 3, 4, 5 }; for (int i = 0; i < 5; i++) { matrix.SetRow(i, row); } float[] vector = { 1, 2, 3, 4, 5 }; Assert.AreEqual(55, MatrixExtensions.RowScalarProduct(matrix, 2, vector)); var matrix2 = new Matrix <float>(5, 5); for (int i = 0; i < 5; i++) { matrix2.SetRow(i, row); } Assert.AreEqual(55, MatrixExtensions.RowScalarProduct(matrix, 2, matrix2, 3)); }
public override float Predict(Feedback feedback) { int userId = UsersMap.ToInternalID(feedback.User.Id); int itemId = ItemsMap.ToInternalID(feedback.Item.Id); var featurs = feedback.GetAllAttributes().Select(a => FeatureBuilder.TranslateAttribute(a)); bool newUser = (userId > MaxUserID); bool newItem = (itemId > MaxItemID); float userAttrsTerm = 0, itemAttrsTerm = 0; foreach (var feat in featurs) { // if feat_index is greater than MaxFeatureId it means that the feature is new in test set so its factors has not been learnt if (feat.Item1 < NumTrainFeaturs) { float x_z = feat.Item2; int g_z = FeatureGroups[feat.Item1]; float alpha_z = weights[g_z]; userAttrsTerm += newUser ? 0 : alpha_z *x_z *MatrixExtensions.RowScalarProduct(feature_factors, feat.Item1, user_factors, userId); itemAttrsTerm += newItem ? 0 : alpha_z *x_z *MatrixExtensions.RowScalarProduct(feature_factors, feat.Item1, item_factors, itemId); } } int u = 0; int i = 1; float alpha_u = weights[u]; float alpha_i = weights[i]; float itemBias = newItem ? 0 : item_bias[itemId]; float userItemTerm = (newUser || newItem) ? 0 : alpha_u *alpha_i *MatrixExtensions.RowScalarProduct(user_factors, userId, item_factors, itemId); return(itemBias + userItemTerm + alpha_u * userAttrsTerm + alpha_i * itemAttrsTerm); }
protected void _Iterate(IList <int> rating_indices, bool update_user, bool update_item) { foreach (int index in rating_indices) { int u = ratings.Users[index]; int i = ratings.Items[index]; int g_u = 0; //FeatureGroups[user_id]; int g_i = 1; //FeatureGroups[item_id]; float alpha_u = weights[g_u]; float alpha_i = weights[g_i]; // used by WrapRec-based logic string userIdOrg = UsersMap.ToOriginalID(u); string itemIdOrg = ItemsMap.ToOriginalID(i); List <Tuple <int, float> > features = new List <Tuple <int, float> >(); if (Split.SetupParameters.ContainsKey("feedbackAttributes")) { features = Split.Container.FeedbacksDic[userIdOrg, itemIdOrg].GetAllAttributes().Select(a => a.Translation) .NormalizeSumToOne(Normalize).ToList(); } var p = Predict(u, i); float err = (p - ratings[index]) * 2; float sum_u = 0, sum_i = 0; foreach (var feature in features) { int j = feature.Item1; float x_j = feature.Item2; int g_z = 2; // FeatureGroups[feature.Item1]; float alpha_z = weights[g_z]; sum_u += x_j * alpha_z * MatrixExtensions.RowScalarProduct(user_factors, u, feature_factors, j); sum_i += x_j * alpha_z * MatrixExtensions.RowScalarProduct(item_factors, i, feature_factors, j); } float ui = MatrixExtensions.RowScalarProduct(item_factors, i, user_factors, u); sum_u += alpha_i * ui; sum_i += alpha_u * ui; float sum_z = 0; float sum_z_bias = 0; for (int z = 0; z < features.Count; z++) { int z_ix = features[z].Item1; float x_z = features[z].Item2; float sum_j = 0; int g_z = 2; // FeatureGroups[z_ix]; float alpha_z = weights[g_z]; for (int j = z + 1; j < features.Count; j++) { int j_ix = features[j].Item1; float x_j = features[j].Item2; sum_j += x_j * MatrixExtensions.RowScalarProduct(feature_factors, z_ix, feature_factors, j_ix); } sum_z += 2 * alpha_z * x_z * sum_j; sum_z += x_z * alpha_u * MatrixExtensions.RowScalarProduct(feature_factors, z_ix, user_factors, u); sum_z += x_z * alpha_i * MatrixExtensions.RowScalarProduct(feature_factors, z_ix, item_factors, i); sum_z_bias += x_z * feature_biases[z_ix]; } float[] sum = new float[NumFactors]; foreach (var feature in features) { int j = feature.Item1; float x_j = feature.Item2; int g_z = 2; //FeatureGroups[feature.Item1]; float alpha_z = weights[g_z]; for (int f = 0; f < NumFactors; f++) { sum[f] += feature_factors[j, f] * x_j * alpha_z; } } for (int f = 0; f < NumFactors; f++) { sum[f] += user_factors[u, f] * alpha_u + item_factors[i, f] * alpha_i; } // adjust biases global_bias -= current_learnrate * (err + RegB * global_bias); if (update_user) { user_bias[u] -= current_learnrate * (err * alpha_u + RegU * user_bias[u]); } if (update_item) { item_bias[i] -= current_learnrate * (err * alpha_i + RegI * item_bias[i]); } foreach (var feature in features) { int j = feature.Item1; float x_j = feature.Item2; float w_j = feature_biases[j]; int g_z = 2; // FeatureGroups[feature.Item1]; float alpha_z = weights[g_z]; feature_biases[j] -= current_learnrate * (x_j * alpha_z * err + RegC * w_j); } // adjust latent factors for (int f = 0; f < NumFactors; f++) { double v_uf = user_factors[u, f]; double v_if = item_factors[i, f]; if (update_user) { double delta_u = alpha_u * (sum[f] - v_uf * alpha_u) * err + RegU * v_uf; user_factors.Inc(u, f, -current_learnrate * delta_u); } if (update_item) { double delta_i = alpha_i * (sum[f] - v_if * alpha_i) * err + RegI * v_if; item_factors.Inc(i, f, -current_learnrate * delta_i); } foreach (var feature in features) { int j = feature.Item1; float x_j = feature.Item2; float v_jf = feature_factors[j, f]; int g_z = 2; // FeatureGroups[feature.Item1]; float alpha_z = weights[g_z]; double delta_j = x_j * alpha_z * (sum[f] - v_jf * x_j * alpha_z) * err + RegC * v_jf; feature_factors.Inc(j, f, -current_learnrate * delta_j); } } // update alphas float update_alpha_u = (user_bias[u] + sum_u) * err + reg_w * weights[g_u]; weights[g_u] -= current_learnrate * update_alpha_u; float update_alpha_i = (item_bias[i] + sum_i) * err + reg_w * weights[g_i]; weights[g_i] -= current_learnrate * update_alpha_i; for (int g = 0; g < NumGroups - 2; g++) { float alpha_z_g = weights[g + 2]; float update_alpha_z = (sum_z + sum_z_bias) * err + reg_w * alpha_z_g; weights[g + 2] -= current_learnrate * update_alpha_z; } NormalizeWeights(); } Console.WriteLine($"alpha_u: {weights[0]}, alpha_i: {weights[1]}" + (weights.Length > 2 ? $", alpha_z: {weights[2]}" : "")); //_alphaWriter.WriteLine(++_iter + "," + weights[0] + "," + weights[1] + (weights.Length > 2 ? "," + weights[2] : "")); }
/// void Iterate(IList <int> rating_indices, bool update_user, bool update_item) { //SetupLoss(); foreach (int index in rating_indices) { int u = ratings.Users[index]; int i = ratings.Items[index]; int correct_label = value_to_label_id[ratings[index]]; float user_reg_weight = FrequencyRegularization ? (float)(RegU / Math.Sqrt(ratings.CountByUser[u])) : RegU; float item_reg_weight = FrequencyRegularization ? (float)(RegI / Math.Sqrt(ratings.CountByItem[i])) : RegI; for (int l = 0; l < label_id_to_value.Count - 1; l++) { double dot_product = user_biases[l, u] + item_biases[l, i] + MatrixExtensions.RowScalarProduct(user_factors[l], u, item_factors[l], i); double label_percentage = 1 / (1 + Math.Exp(-dot_product)); float gradient_common = (float)-label_percentage; if (l == correct_label) { gradient_common += 1; } // adjust biases if (update_user) { user_biases.Inc(l, u, BiasLearnRate * LearnRate * (gradient_common - BiasReg * user_reg_weight * user_biases[l, u])); } if (update_item) { item_biases.Inc(l, i, BiasLearnRate * LearnRate * (gradient_common - BiasReg * item_reg_weight * item_biases[l, i])); } // adjust latent factors for (int f = 0; f < NumFactors; f++) { double u_f = user_factors[l][u, f]; double i_f = item_factors[l][i, f]; if (update_user) { double delta_u = gradient_common * i_f - user_reg_weight * u_f; user_factors[l].Inc(u, f, LearnRate * delta_u); } if (update_item) { double delta_i = gradient_common * u_f - item_reg_weight * i_f; item_factors[l].Inc(i, f, LearnRate * delta_i); } } } } }