Esempio n. 1
0
		/// <summary>Compute the overlap between the vectors in a binary matrix</summary>
		/// <returns>a sparse matrix with the overlaps</returns>
		/// <param name='entity_data'>the binary matrix</param>
		public static Tuple<IMatrix<float>, IList<float>> ComputeWeighted(IBooleanMatrix entity_data)
		{
			var transpose = (IBooleanMatrix) entity_data.Transpose();

			var other_entity_weights = new float[transpose.NumberOfRows];
			for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
			{
				int freq = transpose.GetEntriesByRow(row_id).Count;
				other_entity_weights[row_id] = 1f / (float) Math.Log(3 + freq, 2); // TODO make configurable
			}

			IMatrix<float> weighted_overlap = new SymmetricMatrix<float>(entity_data.NumberOfRows);
			IList<float> entity_weights = new float[entity_data.NumberOfRows];

			// go over all (other) entities
			for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
			{
				var row = transpose.GetEntriesByRow(row_id);
				for (int i = 0; i < row.Count; i++)
				{
					int x = row[i];
					entity_weights[x] += other_entity_weights[row_id];
					for (int j = i + 1; j < row.Count; j++)
					{
						int y = row[j];
						weighted_overlap[x, y] += other_entity_weights[row_id] * other_entity_weights[row_id];
					}
				}
			}

			return Tuple.Create(weighted_overlap, entity_weights);
		}
        /// <summary>Compute the overlap between the vectors in a binary matrix</summary>
        /// <returns>a sparse matrix with the overlaps</returns>
        /// <param name='entity_data'>the binary matrix</param>
        public static Tuple <IMatrix <float>, IList <float> > ComputeWeighted(IBooleanMatrix entity_data)
        {
            var transpose = (IBooleanMatrix)entity_data.Transpose();

            var other_entity_weights = new float[transpose.NumberOfRows];

            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                int freq = transpose.GetEntriesByRow(row_id).Count;
                other_entity_weights[row_id] = 1f / (float)Math.Log(3 + freq, 2);                  // TODO make configurable
            }

            IMatrix <float> weighted_overlap = new SymmetricMatrix <float>(entity_data.NumberOfRows);
            IList <float>   entity_weights   = new float[entity_data.NumberOfRows];

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = transpose.GetEntriesByRow(row_id);
                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];
                    entity_weights[x] += other_entity_weights[row_id];
                    for (int j = i + 1; j < row.Count; j++)
                    {
                        int y = row[j];
                        weighted_overlap[x, y] += other_entity_weights[row_id] * other_entity_weights[row_id];
                    }
                }
            }

            return(Tuple.Create(weighted_overlap, entity_weights));
        }
Esempio n. 3
0
        ///
        public override void ComputeCorrelations(IBooleanMatrix entity_data)
        {
            var transpose = entity_data.Transpose();

            var overlap = new SparseMatrix <int>(entity_data.NumberOfRows, entity_data.NumberOfRows);

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = ((IBooleanMatrix)transpose).GetEntriesByRow(row_id);

                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];

                    for (int j = i + 1; j < row.Count; j++)
                    {
                        int y = row[j];

                        if (x < y)
                        {
                            overlap[x, y]++;
                        }
                        else
                        {
                            overlap[y, x]++;
                        }
                    }
                }
            }

            // the diagonal of the correlation matrix
            for (int i = 0; i < num_entities; i++)
            {
                this[i, i] = 1;
            }

            // compute cosine
            foreach (var index_pair in overlap.NonEmptyEntryIDs)
            {
                int x = index_pair.First;
                int y = index_pair.Second;

                this[x, y] = (float)(overlap[x, y] / Math.Sqrt(entity_data.NumEntriesByRow(x) * entity_data.NumEntriesByRow(y)));
            }
        }
Esempio n. 4
0
		/// <summary>Compute the overlap between the vectors in a binary matrix</summary>
		/// <returns>a sparse matrix with the overlaps</returns>
		/// <param name='entity_data'>the binary matrix</param>
		public static IMatrix<uint> ComputeUInt(IBooleanMatrix entity_data)
		{
			var transpose = entity_data.Transpose() as IBooleanMatrix;

			var overlap = new SymmetricSparseMatrix<uint>(entity_data.NumberOfRows);

			// go over all (other) entities
			for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
			{
				var row = transpose.GetEntriesByRow(row_id);
				for (int i = 0; i < row.Count; i++)
				{
					int x = row[i];
					for (int j = i + 1; j < row.Count; j++)
						overlap[x, row[j]]++;
				}
			}
			return overlap;
		}
        /// <summary>Computes the overlap between the vectors in a binary matrix</summary>
        /// <returns>a sparse matrix with the overlaps</returns>
        /// <param name='entity_data'>the binary matrix</param>
        public static IMatrix <ushort> ComputeUShort(IBooleanMatrix entity_data)
        {
            var transpose = entity_data.Transpose() as IBooleanMatrix;

            var overlap = new SymmetricSparseMatrix <ushort>(entity_data.NumberOfRows);

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = transpose.GetEntriesByRow(row_id);
                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];
                    for (int j = i + 1; j < row.Count; j++)
                    {
                        overlap[x, row[j]]++;
                    }
                }
            }
            return(overlap);
        }
Esempio n. 6
0
        ///
        public override void ComputeCorrelations(IBooleanMatrix entity_data)
        {
            var transpose = (IBooleanMatrix) entity_data.Transpose();

            var other_entity_weights = new float[transpose.NumberOfRows];
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                int freq = transpose.GetEntriesByRow(row_id).Count;
                other_entity_weights[row_id] = 1f / (float) Math.Log(3 + freq, 2); // TODO make configurable
            }

            var weighted_overlap = new SymmetricMatrix<float>(entity_data.NumberOfRows);
            var entity_weights = new float[entity_data.NumberOfRows];

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = transpose.GetEntriesByRow(row_id);
                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];
                    entity_weights[x] += other_entity_weights[row_id];
                    for (int j = i + 1; j < row.Count; j++)
                    {
                        int y = row[j];
                        weighted_overlap[x, y] += other_entity_weights[row_id] * other_entity_weights[row_id];
                    }
                }
            }

            // the diagonal of the correlation matrix
            for (int i = 0; i < num_entities; i++)
                this[i, i] = 1;

            // compute cosine
            for (int x = 0; x < num_entities; x++)
                for (int y = 0; y < x; y++)
                    this[x, y] = (float) (weighted_overlap[x, y] / Math.Sqrt(entity_weights[x] * entity_weights[y] ));
        }
Esempio n. 7
0
        private void IterateBatch(IList <int> rating_indices, bool update_user, bool update_item)
        {
            SetupLoss();
            SparseBooleanMatrix user_reverse_connections = (SparseBooleanMatrix)user_connections.Transpose();

            // I. compute gradients
            var user_factors_gradient = new Matrix <float>(user_factors.dim1, user_factors.dim2);
            var item_factors_gradient = new Matrix <float>(item_factors.dim1, item_factors.dim2);
            var user_bias_gradient    = new float[user_factors.dim1];
            var item_bias_gradient    = new float[item_factors.dim1];

            // I.1 prediction error
            foreach (int index in rating_indices)
            {
                int user_id = ratings.Users[index];
                int item_id = ratings.Items[index];

                // prediction
                float score = global_bias + user_bias[user_id] + item_bias[item_id];
                score += DataType.MatrixExtensions.RowScalarProduct(user_factors, user_id, item_factors, item_id);
                double sig_score = 1 / (1 + Math.Exp(-score));

                float prediction = (float)(MinRating + sig_score * rating_range_size);
                float error      = prediction - ratings[index];

                float gradient_common = compute_gradient_common(sig_score, error);

                user_bias_gradient[user_id] += gradient_common;
                item_bias_gradient[item_id] += gradient_common;

                for (int f = 0; f < NumFactors; f++)
                {
                    float u_f = user_factors[user_id, f];
                    float i_f = item_factors[item_id, f];

                    user_factors_gradient.Inc(user_id, f, gradient_common * i_f);
                    item_factors_gradient.Inc(item_id, f, gradient_common * u_f);
                }
            }

            // I.2 L2 regularization
            //        biases
            for (int u = 0; u < user_bias_gradient.Length; u++)
            {
                user_bias_gradient[u] += user_bias[u] * RegU * BiasReg;
            }
            for (int i = 0; i < item_bias_gradient.Length; i++)
            {
                item_bias_gradient[i] += item_bias[i] * RegI * BiasReg;
            }
            //        latent factors
            for (int u = 0; u < user_factors_gradient.dim1; u++)
            {
                for (int f = 0; f < user_factors_gradient.dim2; f++)
                {
                    user_factors_gradient.Inc(u, f, user_factors[u, f] * RegU);
                }
            }

            for (int i = 0; i < item_factors_gradient.dim1; i++)
            {
                for (int f = 0; f < item_factors_gradient.dim2; f++)
                {
                    item_factors_gradient.Inc(i, f, item_factors[i, f] * RegI);
                }
            }

            // I.3 social network regularization -- see eq. (13) in the paper
            if (SocialRegularization != 0)
            {
                for (int u = 0; u < user_factors_gradient.dim1; u++)
                {
                    var   sum_connections      = new float[NumFactors];
                    float bias_sum_connections = 0;
                    int   num_connections      = user_connections[u].Count;
                    foreach (int v in user_connections[u])
                    {
                        bias_sum_connections += user_bias[v];
                        for (int f = 0; f < sum_connections.Length; f++)
                        {
                            sum_connections[f] += user_factors[v, f];
                        }
                    }
                    if (num_connections != 0)
                    {
                        user_bias_gradient[u] += social_regularization * (user_bias[u] - bias_sum_connections / num_connections);
                        for (int f = 0; f < user_factors_gradient.dim2; f++)
                        {
                            user_factors_gradient.Inc(u, f, social_regularization * (user_factors[u, f] - sum_connections[f] / num_connections));
                        }
                    }

                    foreach (int v in user_reverse_connections[u])
                    {
                        float trust_v             = (float)1 / user_connections[v].Count;
                        float neg_trust_times_reg = -social_regularization * trust_v;

                        float bias_diff    = 0;
                        var   factor_diffs = new float[NumFactors];
                        foreach (int w in user_connections[v])
                        {
                            bias_diff -= user_bias[w];
                            for (int f = 0; f < factor_diffs.Length; f++)
                            {
                                factor_diffs[f] -= user_factors[w, f];
                            }
                        }

                        bias_diff             *= trust_v;             // normalize
                        bias_diff             += user_bias[v];
                        user_bias_gradient[u] += neg_trust_times_reg * bias_diff;

                        for (int f = 0; f < factor_diffs.Length; f++)
                        {
                            factor_diffs[f] *= trust_v;                             // normalize
                            factor_diffs[f] += user_factors[v, f];
                            user_factors_gradient.Inc(u, f, neg_trust_times_reg * factor_diffs[f]);
                        }
                    }
                }
            }

            // II. apply gradient descent step
            if (update_user)
            {
                for (int user_id = 0; user_id < user_factors_gradient.dim1; user_id++)
                {
                    user_bias[user_id] -= user_bias_gradient[user_id] * LearnRate * BiasLearnRate;
                }
                user_factors_gradient.Multiply(-LearnRate);
                user_factors.Inc(user_factors_gradient);
            }
            if (update_item)
            {
                for (int item_id = 0; item_id < item_factors_gradient.dim1; item_id++)
                {
                    item_bias[item_id] -= item_bias_gradient[item_id] * LearnRate * BiasLearnRate;
                }
                item_factors_gradient.Multiply(-LearnRate);
                item_factors.Inc(item_factors_gradient);
            }
        }
Esempio n. 8
0
        void ComputeCorrelationsUShortOverlap(IBooleanMatrix entity_data)
        {
            var transpose = entity_data.Transpose() as IBooleanMatrix;

            var overlap = new SymmetricMatrix<ushort>(entity_data.NumberOfRows);

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = transpose.GetEntriesByRow(row_id);
                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];
                    for (int j = i + 1; j < row.Count; j++)
                        overlap[x, row[j]]++;
                }
            }

            // the diagonal of the correlation matrix
            for (int i = 0; i < num_entities; i++)
                this[i, i] = 1;

            // compute cosine
            for (int x = 0; x < num_entities; x++)
                for (int y = 0; y < x; y++)
                {
                    long size_product = entity_data.NumEntriesByRow(x) * entity_data.NumEntriesByRow(y);
                    if (size_product > 0)
                        this[x, y] = (float) (overlap[x, y] / Math.Sqrt(size_product));
                }
        }
Esempio n. 9
0
        ///
        public override void ComputeCorrelations(IBooleanMatrix entity_data)
        {
            var transpose = entity_data.Transpose();

            var overlap = new SparseMatrix<int>(entity_data.NumberOfRows, entity_data.NumberOfRows);

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = ((IBooleanMatrix) transpose).GetEntriesByRow(row_id);

                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];

                    for (int j = i + 1; j < row.Count; j++)
                    {
                        int y = row[j];

                        if (x < y)
                            overlap[x, y]++;
                        else
                            overlap[y, x]++;
                    }
                }
            }

            // the diagonal of the correlation matrix
            for (int i = 0; i < num_entities; i++)
                this[i, i] = 1;

            // compute cosine
            foreach (var index_pair in overlap.NonEmptyEntryIDs)
            {
                int x = index_pair.First;
                int y = index_pair.Second;

                this[x, y] = (float) (overlap[x, y] / Math.Sqrt(entity_data.NumEntriesByRow(x) * entity_data.NumEntriesByRow(y) ));
            }
        }
Esempio n. 10
0
        ///
        public override void ComputeCorrelations(IBooleanMatrix entity_data)
        {
            var transpose = entity_data.Transpose() as IBooleanMatrix;

            var overlap = new SymmetricMatrix<int>(entity_data.NumberOfRows);

            // go over all (other) entities
            for (int row_id = 0; row_id < transpose.NumberOfRows; row_id++)
            {
                var row = transpose.GetEntriesByRow(row_id);
                for (int i = 0; i < row.Count; i++)
                {
                    int x = row[i];
                    for (int j = i + 1; j < row.Count; j++)
                    {
                        int y = row[j];
                        overlap[x, y]++;
                    }
                }
            }

            // the diagonal of the correlation matrix
            for (int i = 0; i < num_entities; i++)
                this[i, i] = 1;

            // compute Jaccard index
            for (int x = 0; x < num_entities; x++)
                for (int y = 0; y < x; y++)
                    this[x, y] = (float) (overlap[x, y] / (entity_data.NumEntriesByRow(x) + entity_data.NumEntriesByRow(y) - overlap[x, y]));
        }