diff --git a/src/libs/recommendation/CMakeLists.txt b/src/libs/recommendation/CMakeLists.txt index cdcf20bd..b2161dc2 100644 --- a/src/libs/recommendation/CMakeLists.txt +++ b/src/libs/recommendation/CMakeLists.txt @@ -1,7 +1,7 @@ add_library(lmsrecommendation SHARED impl/Engine.cpp - impl/ProviderCreator.cpp + impl/ClassifierCreator.cpp ) target_include_directories(lmsrecommendation INTERFACE diff --git a/src/libs/recommendation/impl/ProviderCreator.cpp b/src/libs/recommendation/impl/ClassifierCreator.cpp similarity index 70% rename from src/libs/recommendation/impl/ProviderCreator.cpp rename to src/libs/recommendation/impl/ClassifierCreator.cpp index 00d0b0e9..865dd1c9 100644 --- a/src/libs/recommendation/impl/ProviderCreator.cpp +++ b/src/libs/recommendation/impl/ClassifierCreator.cpp @@ -17,19 +17,19 @@ * along with LMS. If not, see . */ -#include "recommendation/ClustersRecommendationProviderCreator.hpp" -#include "recommendation/FeaturesRecommendationProviderCreator.hpp" -#include "recommendation/Provider.hpp" +#include "recommendation/ClustersClassifierCreator.hpp" +#include "recommendation/FeaturesClassifierCreator.hpp" +#include "recommendation/Classifier.hpp" namespace Recommendation { - std::unique_ptr createClustersRecommendationProvider() + std::unique_ptr createClustersClassifier() { return {}; } - std::unique_ptr createFeaturesRecommendationProvider(Scanner::IMediaScanner&) + std::unique_ptr createFeaturesClassifier() { return {}; } diff --git a/src/libs/recommendation/impl/Engine.cpp b/src/libs/recommendation/impl/Engine.cpp index a2c61a61..384f6862 100644 --- a/src/libs/recommendation/impl/Engine.cpp +++ b/src/libs/recommendation/impl/Engine.cpp @@ -34,15 +34,15 @@ createEngine() } void -Engine::clearProviders() +Engine::clearClassifiers() { - _providers.clear(); + _classifiers.clear(); } void -Engine::addProvider(std::unique_ptr provider, unsigned priority) +Engine::addClassifier(std::unique_ptr classifier, unsigned priority) { - _providers.emplace(priority, std::move(provider)); + _classifiers.emplace(priority, std::move(classifier)); } std::vector diff --git a/src/libs/recommendation/impl/Engine.hpp b/src/libs/recommendation/impl/Engine.hpp index 92dacc08..cbf66a2b 100644 --- a/src/libs/recommendation/impl/Engine.hpp +++ b/src/libs/recommendation/impl/Engine.hpp @@ -22,7 +22,7 @@ #include #include "recommendation/IEngine.hpp" -#include "recommendation/Provider.hpp" +#include "recommendation/Classifier.hpp" namespace Database { @@ -34,9 +34,6 @@ namespace Recommendation class Engine : public IEngine { public: - void clearProviders() override; - void addProvider(std::unique_ptr provider, unsigned priority) override; - // Closest results first std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount) override; std::vector getSimilarTracks(Database::Session& session, const std::unordered_set& tracksId, std::size_t maxCount) override; @@ -44,8 +41,10 @@ namespace Recommendation std::vector getSimilarArtists(Database::Session& session, Database::IdType artistId, std::size_t maxCount) override; private: + void clearClassifiers(); + void addClassifier(std::unique_ptr classifier, unsigned priority); - std::map> _providers; + std::map> _classifiers; }; } // ns Recommendation diff --git a/src/libs/recommendation/include/recommendation/Provider.hpp b/src/libs/recommendation/include/recommendation/Classifier.hpp similarity index 95% rename from src/libs/recommendation/include/recommendation/Provider.hpp rename to src/libs/recommendation/include/recommendation/Classifier.hpp index d40f686e..3c7c7e63 100644 --- a/src/libs/recommendation/include/recommendation/Provider.hpp +++ b/src/libs/recommendation/include/recommendation/Classifier.hpp @@ -32,10 +32,12 @@ namespace Database namespace Recommendation { - class Provider + class Classifier { public: - virtual ~Provider() = default; + virtual ~Classifier() = default; + + virtual void classify() = 0; virtual bool isTrackClassified(Database::IdType trackId) const = 0; virtual bool isReleaseClassified(Database::IdType releaseId) const = 0; diff --git a/src/libs/recommendation/include/recommendation/ClustersRecommendationProviderCreator.hpp b/src/libs/recommendation/include/recommendation/ClustersClassifierCreator.hpp similarity index 90% rename from src/libs/recommendation/include/recommendation/ClustersRecommendationProviderCreator.hpp rename to src/libs/recommendation/include/recommendation/ClustersClassifierCreator.hpp index 99b11666..71e92ddc 100644 --- a/src/libs/recommendation/include/recommendation/ClustersRecommendationProviderCreator.hpp +++ b/src/libs/recommendation/include/recommendation/ClustersClassifierCreator.hpp @@ -28,8 +28,8 @@ namespace Database namespace Recommendation { - class Provider; + class Classifier; - std::unique_ptr createClustersRecommendationProvider(); + std::unique_ptr createClustersClassifier(); } diff --git a/src/libs/recommendation/include/recommendation/FeaturesRecommendationProviderCreator.hpp b/src/libs/recommendation/include/recommendation/FeaturesClassifierCreator.hpp similarity index 83% rename from src/libs/recommendation/include/recommendation/FeaturesRecommendationProviderCreator.hpp rename to src/libs/recommendation/include/recommendation/FeaturesClassifierCreator.hpp index 756bf605..ce4e3a74 100644 --- a/src/libs/recommendation/include/recommendation/FeaturesRecommendationProviderCreator.hpp +++ b/src/libs/recommendation/include/recommendation/FeaturesClassifierCreator.hpp @@ -26,15 +26,10 @@ namespace Database class Session; } -namespace Scanner -{ - class IMediaScanner; -} - namespace Recommendation { - class Provider; + class Classifier; - std::unique_ptr createFeaturesRecommendationProvider(Scanner::IMediaScanner& scanner); + std::unique_ptr createFeaturesClassifier(); } diff --git a/src/libs/recommendation/include/recommendation/IEngine.hpp b/src/libs/recommendation/include/recommendation/IEngine.hpp index bc420aff..a28adfaf 100644 --- a/src/libs/recommendation/include/recommendation/IEngine.hpp +++ b/src/libs/recommendation/include/recommendation/IEngine.hpp @@ -23,7 +23,7 @@ #include #include "database/Types.hpp" -#include "Provider.hpp" +#include "Classifier.hpp" namespace Database { @@ -32,15 +32,12 @@ namespace Database namespace Recommendation { - class Provider; + class Classifier; class IEngine { public: virtual ~IEngine() = default; - virtual void clearProviders() = 0; - virtual void addProvider(std::unique_ptr provider, unsigned priority) = 0; - // Closest results first virtual std::vector getSimilarTracksFromTrackList(Database::Session& session, Database::IdType tracklistId, std::size_t maxCount) = 0; virtual std::vector getSimilarTracks(Database::Session& session, const std::unordered_set& tracksId, std::size_t maxCount) = 0; diff --git a/src/lms/main.cpp b/src/lms/main.cpp index 126c7402..7cf6af96 100644 --- a/src/lms/main.cpp +++ b/src/lms/main.cpp @@ -29,9 +29,7 @@ #include "cover/ICoverArtGrabber.hpp" #include "database/Db.hpp" #include "scanner/IMediaScanner.hpp" -#include "recommendation/FeaturesRecommendationProviderCreator.hpp" #include "recommendation/IEngine.hpp" -#include "recommendation/ClustersRecommendationProviderCreator.hpp" #include "subsonic/SubsonicResource.hpp" #include "ui/LmsApplication.hpp" #include "utils/IConfig.hpp" @@ -145,9 +143,7 @@ int main(int argc, char* argv[]) ServiceProvider::assign(Auth::createPasswordService(ServiceProvider::get()->getULong("login-throttler-max-entriees", 10000))); Scanner::IMediaScanner& mediaScanner {ServiceProvider::assign(Scanner::createMediaScanner(database))}; - Recommendation::IEngine& recommendationEngine {ServiceProvider::assign(Recommendation::createEngine())}; - recommendationEngine.addProvider(Recommendation::createFeaturesRecommendationProvider(mediaScanner), 0); - recommendationEngine.addProvider(Recommendation::createClustersRecommendationProvider(), 1); + ServiceProvider::assign(Recommendation::createEngine()); CoverArt::IGrabber& coverArtGrabber {ServiceProvider::assign(CoverArt::createGrabber(argv[0]))}; coverArtGrabber.setDefaultCover(server.appRoot() + "/images/unknown-cover.jpg"); diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index f66ea24a..4fcdba31 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(metadata) +add_subdirectory(recommendation-features) diff --git a/src/tools/recommendation-features/CMakeLists.txt b/src/tools/recommendation-features/CMakeLists.txt new file mode 100644 index 00000000..25508174 --- /dev/null +++ b/src/tools/recommendation-features/CMakeLists.txt @@ -0,0 +1,10 @@ + +add_executable(lms-recommendation-features + LmsRecommendationFeatures.cpp + ) + +target_link_libraries(lms-recommendation-features PRIVATE + lmsdatabase + lmsrecommendation + ) + diff --git a/src/tools/similarity/LmsSimilarity.cpp b/src/tools/recommendation-features/LmsRecommendationFeatures.cpp similarity index 85% rename from src/tools/similarity/LmsSimilarity.cpp rename to src/tools/recommendation-features/LmsRecommendationFeatures.cpp index 522b6558..6426dff5 100644 --- a/src/tools/similarity/LmsSimilarity.cpp +++ b/src/tools/recommendation-features/LmsRecommendationFeatures.cpp @@ -28,17 +28,16 @@ #include "database/Release.hpp" #include "database/Session.hpp" #include "database/Track.hpp" -#include "utils/Config.hpp" +#include "utils/IConfig.hpp" #include "utils/Service.hpp" #include "utils/StreamLogger.hpp" -#include "similarity/features/SimilarityFeaturesSearcher.hpp" +#include "recommendation/IEngine.hpp" +#include "recommendation/FeaturesClassifierCreator.hpp" int main(int argc, char *argv[]) { try { - using namespace Similarity; - // log to stdout ServiceProvider::create(std::cout); @@ -46,16 +45,16 @@ int main(int argc, char *argv[]) if (argc >= 2) configFilePath = std::string(argv[1], 0, 256); - ServiceProvider::create(configFilePath); + ServiceProvider::assign(createConfig(configFilePath)); - Database::Db db {ServiceProvider::get()->getPath("working-dir") / "lms.db"}; + Database::Db db {ServiceProvider::get()->getPath("working-dir") / "lms.db"}; Database::Session session {db}; + auto classifier {Recommendation::createFeaturesClassifier()}; + std::cout << "Classifying tracks..." << std::endl; // may be long... - struct FeaturesSearcher::TrainSettings trainSettings; - trainSettings.featureSettingsMap = FeaturesSearcher::getDefaultTrainFeatureSettings(); - FeaturesSearcher searcher {session, trainSettings}; + classifier->classify(); std::cout << "Classifying tracks DONE" << std::endl; const std::vector trackIds = std::invoke([&]() @@ -85,7 +84,7 @@ int main(int argc, char *argv[]) }; std::cout << "Processing track '" << trackToString(trackId) << std::endl; - for (Database::IdType similarTrackId : searcher.getSimilarTracks({trackId}, 3)) + for (Database::IdType similarTrackId : classifier->getSimilarTracks(session, {trackId}, 3)) std::cout << "\t- Similar track '" << trackToString(similarTrackId) << std::endl; } @@ -107,7 +106,7 @@ int main(int argc, char *argv[]) }; std::cout << "Processing release '" << releaseToString(releaseId) << "'" << std::endl; - for (Database::IdType similarReleaseId : searcher.getSimilarReleases({releaseId}, 3)) + for (Database::IdType similarReleaseId : classifier->getSimilarReleases({releaseId}, 3)) std::cout << "\t- Similar release '" << releaseToString(similarReleaseId) << "'" << std::endl; } @@ -129,7 +128,7 @@ int main(int argc, char *argv[]) }; std::cout << "Processing artist '" << artistToString(artistId) << "'" << std::endl; - for (Database::IdType similarArtistId : searcher.getSimilarArtists({artistId}, 3)) + for (Database::IdType similarArtistId : classifier->getSimilarArtists({artistId}, 3)) std::cout << "\t- Similar artist '" << artistToString(similarArtistId) << "'" << std::endl; } diff --git a/src/tools/similarity-parameters/Makefile.am b/src/tools/similarity-parameters/Makefile.am deleted file mode 100644 index 0f7cb8f8..00000000 --- a/src/tools/similarity-parameters/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -noinst_PROGRAMS = lms-similarity-parameters - -lms_similarity_parameters_SOURCES = \ - $(srcdir)/LmsSimilarityParameters.cpp \ - $(top_srcdir)/src/database/Artist.cpp \ - $(top_srcdir)/src/database/Cluster.cpp \ - $(top_srcdir)/src/database/Db.cpp \ - $(top_srcdir)/src/database/TrackFeatures.cpp \ - $(top_srcdir)/src/database/TrackList.cpp \ - $(top_srcdir)/src/database/Release.cpp \ - $(top_srcdir)/src/database/ScanSettings.cpp \ - $(top_srcdir)/src/database/Session.cpp \ - $(top_srcdir)/src/database/SessionPool.cpp \ - $(top_srcdir)/src/database/SqlQuery.cpp \ - $(top_srcdir)/src/database/Track.cpp \ - $(top_srcdir)/src/database/User.cpp \ - $(top_srcdir)/src/similarity/features/som/DataNormalizer.cpp \ - $(top_srcdir)/src/similarity/features/som/Network.cpp \ - $(top_srcdir)/src/similarity/features/SimilarityFeaturesCache.cpp \ - $(top_srcdir)/src/similarity/features/SimilarityFeaturesSearcher.cpp \ - $(top_srcdir)/src/similarity/features/SimilarityFeaturesDefs.cpp \ - $(top_srcdir)/src/utils/Config.cpp \ - $(top_srcdir)/src/utils/Logger.cpp \ - $(top_srcdir)/src/utils/Random.cpp \ - $(top_srcdir)/src/utils/StreamLogger.cpp \ - $(top_srcdir)/src/utils/String.cpp - -lms_similarity_parameters_CXXFLAGS=-std=c++17 -I$(top_srcdir)/src -D_REENTRANT - diff --git a/src/tools/similarity/Makefile.am b/src/tools/similarity/Makefile.am deleted file mode 100644 index 0473f464..00000000 --- a/src/tools/similarity/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -noinst_PROGRAMS = lms-similarity - -lms_similarity_SOURCES = \ - $(srcdir)/LmsSimilarity.cpp \ - $(top_srcdir)/src/database/Artist.cpp \ - $(top_srcdir)/src/database/Cluster.cpp \ - $(top_srcdir)/src/database/Db.cpp \ - $(top_srcdir)/src/database/TrackFeatures.cpp \ - $(top_srcdir)/src/database/TrackList.cpp \ - $(top_srcdir)/src/database/Release.cpp \ - $(top_srcdir)/src/database/ScanSettings.cpp \ - $(top_srcdir)/src/database/Session.cpp \ - $(top_srcdir)/src/database/SqlQuery.cpp \ - $(top_srcdir)/src/database/Track.cpp \ - $(top_srcdir)/src/database/User.cpp \ - $(top_srcdir)/src/similarity/features/som/DataNormalizer.cpp \ - $(top_srcdir)/src/similarity/features/som/Network.cpp \ - $(top_srcdir)/src/similarity/features/SimilarityFeaturesCache.cpp \ - $(top_srcdir)/src/similarity/features/SimilarityFeaturesSearcher.cpp \ - $(top_srcdir)/src/similarity/features/SimilarityFeaturesDefs.cpp \ - $(top_srcdir)/src/utils/Config.cpp \ - $(top_srcdir)/src/utils/Logger.cpp \ - $(top_srcdir)/src/utils/StreamLogger.cpp \ - $(top_srcdir)/src/utils/String.cpp - -lms_similarity_CXXFLAGS=-std=c++17 -I$(top_srcdir)/src -D_REENTRANT -