diff --git a/src/Recommendation.jl b/src/Recommendation.jl index 9308d41..e41e51d 100644 --- a/src/Recommendation.jl +++ b/src/Recommendation.jl @@ -22,7 +22,7 @@ include("model/tf_idf.jl") include("model/user_knn.jl") include("model/item_knn.jl") include("model/svd.jl") -include("model/mf.jl") +include("model/matrix_factorization.jl") include("metric/base.jl") include("metric/accuracy.jl") diff --git a/src/model/mf.jl b/src/model/matrix_factorization.jl similarity index 92% rename from src/model/mf.jl rename to src/model/matrix_factorization.jl index e585b25..8e9886f 100644 --- a/src/model/mf.jl +++ b/src/model/matrix_factorization.jl @@ -1,7 +1,7 @@ -export MF +export MatrixFactorization, MF """ - MF( + MatrixFactorization( data::DataAccessor, k::Int ) @@ -16,13 +16,13 @@ MF solves the following minimization problem for a set of observed user-item int where ``\\mathbf{p}_u, \\mathbf{q}_i \\in \\mathbb{R}^k`` are respectively a factorized user and item vector, and ``\\lambda`` is a regularization parameter to avoid overfitting. An optimal solution will be found by stochastic gradient descent (SGD). Ultimately, we can predict missing values in ``R`` by just computing ``PQ^{\\mathrm{T}}``, and the prediction directly leads recommendation. """ -struct MF <: Recommender +struct MatrixFactorization <: Recommender data::DataAccessor k::Int P::AbstractMatrix Q::AbstractMatrix - function MF(data::DataAccessor, k::Int) + function MatrixFactorization(data::DataAccessor, k::Int) n_user, n_item = size(data.R) P = matrix(n_user, k) Q = matrix(n_item, k) @@ -31,6 +31,8 @@ struct MF <: Recommender end end +const MF = MatrixFactorization + MF(data::DataAccessor) = MF(data, 20) isbuilt(recommender::MF) = isfilled(recommender.P) diff --git a/test/model/test_mf.jl b/test/model/test_matrix_factorization.jl similarity index 54% rename from test/model/test_mf.jl rename to test/model/test_matrix_factorization.jl index 17255b1..4cd8dea 100644 --- a/test/model/test_mf.jl +++ b/test/model/test_matrix_factorization.jl @@ -1,12 +1,10 @@ -function test_mf() - println("-- Testing MF-based recommender") - +function run(recommender::Type{T}) where {T<:Recommender} m = [NaN 3 NaN 1 2 1 NaN 4 1 2 NaN NaN 3 2 NaN 3 NaN 2 3 3 NaN 5 NaN 1] data = DataAccessor(m) - recommender = MF(data, 2) + recommender = recommender(data, 2) build!(recommender, learning_rate=15e-4, max_iter=100) # top-4 recommantion list should be same as CF/SVD-based recommender @@ -14,4 +12,15 @@ function test_mf() @test Set([first(r) for r in rec]) == Set([2, 5, 6, 8]) end +function test_mf() + println("-- Testing MF-based (aliased) recommender") + run(MF) +end + +function test_matrix_factorization() + println("-- Testing Matrix Factorization-based recommender") + run(MatrixFactorization) +end + test_mf() +test_matrix_factorization() diff --git a/test/runtests.jl b/test/runtests.jl index c77e6e5..5d01394 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -15,7 +15,7 @@ include("model/test_tf_idf.jl") include("model/test_user_knn.jl") include("model/test_item_knn.jl") include("model/test_svd.jl") -include("model/test_mf.jl") +include("model/test_matrix_factorization.jl") include("metric/test_accuracy.jl") include("metric/test_ranking.jl")