Beispiel #1
0
        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);
        }
Beispiel #2
0
        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));
        }
Beispiel #5
0
        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);
        }
Beispiel #8
0
        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);
                        }
                    }
                }
            }
        }