- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There's potentially a bug in ALS implementation, or I'm doing something wrong. Please, take a look at the code below.
Input data, in CSR format:
[root@c010-n002 DAAL-CF-RS]# cat test.csr 1,2,3,4 1,1,3 1,1,1
Code (from code examples):
#include "daal.h" #include "service.h" using namespace std; using namespace daal; using namespace daal::data_management; using namespace daal::algorithms::implicit_als; string trainDatasetFileName = "./test.csv"; typedef double algorithmFPType; /* Algorithm floating-point type */ typedef double dataFPType; /* Input data floating-point type */ const size_t nFactors = 2; services::SharedPtr<NumericTable> dataTable; services::SharedPtr<Model> initialModel; services::SharedPtr<training::Result> trainingResult; void initializeModel(); void trainModel(); void testModel(); int main(int argc, char *argv[]) { checkArguments(argc, argv, 1, &trainDatasetFileName); initializeModel(); trainModel(); testModel(); return 0; } void initializeModel() { dataTable = services::SharedPtr<NumericTable>(createSparseTable<dataFPType>(trainDatasetFileName)); training::init::Batch<algorithmFPType, training::init::fastCSR> initAlgorithm; initAlgorithm.parameter.nFactors = nFactors; initAlgorithm.input.set(training::init::data, dataTable); initAlgorithm.compute(); initialModel = initAlgorithm.getResult()->get(training::init::model); printNumericTable(dataTable, "Initial ratings:"); } void trainModel() { training::Batch<algorithmFPType, training::fastCSR> algorithm; algorithm.input.set(training::data, dataTable); algorithm.input.set(training::inputModel, initialModel); algorithm.parameter.nFactors = nFactors; algorithm.compute(); trainingResult = algorithm.getResult(); } void testModel() { prediction::ratings::Batch<> algorithm; algorithm.parameter.nFactors = nFactors; algorithm.input.set(prediction::ratings::model, trainingResult->get(training::model)); algorithm.compute(); services::SharedPtr<NumericTable> predictedRatings = algorithm.getResult()->get(prediction::ratings::prediction); printNumericTable(predictedRatings, "Predicted ratings:"); }
Compilation process:
[root@c010-n002 DAAL-CF-RS]# icpc -daal -O3 implicit_als_csr_batch.cpp [root@c010-n002 DAAL-CF-RS]# icpc -v icpc version 16.0.1 (gcc version 4.8.3 compatibility) [root@c010-n002 DAAL-CF-RS]# ./a.out test.csr Initial ratings: 1.000 0.000 0.000 1.000 0.000 0.000 0.000 0.000 1.000 Predicted ratings: 1.000 1.000 -0.009 0.000 0.000 0.000 -0.002 -0.002 1.000
I've tried batch code with CSV files - same result. Looks like the result is transposed... Bug or feature?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Vadim,
Your observation is correct, the results of ALS prediction are transposed in memory.
This will be fixed in the upcoming release.
Best regards,
Victoriya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Victoriya.
How would you recommend to transpose the result back? Is this functionality already exists in DAAL, or should I do it manually?
And last quick question: https://software.intel.com/en-us/node/599569 - online DAAL documentation, ALS example. It is a little bit different from the same example in archived documentation from here: https://software.intel.com/en-us/daal-user-and-reference-guides-zip
I'm interested in following code snippet from ZIP archive located at file:///......../daal_ur_guides/daal_cpp_api/implicit_als_dense_batch_8cpp-example.htm#DAAL-EXAMPLE-CPP-IMPLICIT_ALS_DENSE_BATCH
Looks like namespaces were changed, and this file is outdated.
/* file: implicit_als_dense_batch.cpp */ /******************************************************************************* ! Copyright(C) 2014-2015 Intel Corporation. All Rights Reserved. ! ! The source code, information and material ("Material") contained herein is ! owned by Intel Corporation or its suppliers or licensors, and title to such ! Material remains with Intel Corporation or its suppliers or licensors. The ! Material contains proprietary information of Intel or its suppliers and ! licensors. The Material is protected by worldwide copyright laws and treaty ! provisions. No part of the Material may be used, copied, reproduced, ! modified, published, uploaded, posted, transmitted, distributed or disclosed ! in any way without Intel's prior express written permission. No license ! under any patent, copyright or other intellectual property rights in the ! Material is granted to or conferred upon you, either expressly, by ! implication, inducement, estoppel or otherwise. Any license under such ! intellectual property rights must be express and approved by Intel in ! writing. ! ! *Third Party trademarks are the property of their respective owners. ! ! Unless otherwise agreed by Intel in writing, you may not remove or alter ! this notice or any other notice embedded in Materials by Intel or Intel's ! suppliers or licensors in any way. ! !******************************************************************************* ! Content: ! C++ example of the implicit alternating least squares (ALS) algorithm in ! the batch processing mode. ! ! The program trains the implicit ALS model on a dense training data set. !******************************************************************************/ #include "daal.h" #include "service.h" using namespace std; using namespace daal; using namespace daal::algorithms::implicit_als; /* Input data set parameters */ string trainDatasetFileName = "../data/batch/implicit_als.csv"; typedef double algorithmFPType; /* Algorithm floating-point type */ /* Algorithm parameters */ const size_t nUsers = 46; const size_t nFactors = 2; const size_t nIndices = 5; const size_t nRecommendations = 3; services::SharedPtr<NumericTable> dataTable; services::SharedPtr<Model> initialModel; services::SharedPtr<training::Result> trainingResult; void initializeModel(); void trainModel(); void testModel(); void predictRatings(); int main(int argc, char *argv[]) { checkArguments(argc, argv, 1, &trainDatasetFileName); initializeModel(); trainModel(); predictRatings(); testModel(); return 0; } void initializeModel() { /* Read trainDatasetFileName from a file and create a numeric table to store the input data */ FileDataSource<CSVFeatureManager> dataSource(trainDatasetFileName, DataSource::doAllocateNumericTable, DataSource::doDictionaryFromContext); /* Retrieve the input data */ dataSource.loadDataBlock(nUsers); dataTable = dataSource.getNumericTable(); /* Create an algorithm object to initialize the implicit ALS model with the default method */ training::init::Batch<algorithmFPType, training::init::defaultDense> initAlgorithm; initAlgorithm.parameter.nFactors = nFactors; /* Pass a training data set and dependent values to the algorithm */ initAlgorithm.input.set(training::init::data, dataTable); /* Initialize the implicit ALS model */ initAlgorithm.compute(); initialModel = initAlgorithm.getResult()->get(training::model); } void trainModel() { /* Create an algorithm object to train the implicit ALS model with the default method */ training::Batch<algorithmFPType, training::defaultDense> algorithm; /* Pass a training data set and dependent values to the algorithm */ algorithm.input.set(training::data, dataTable); algorithm.input.set(training::inputModel, initialModel); algorithm.parameter.nFactors = nFactors; /* Build the implicit ALS model */ algorithm.compute(); /* Retrieve the algorithm results */ trainingResult = algorithm.getResult(); } void predictRatings() { /* Create an algorithm object to prediction recommendations of the implicit ALS model */ prediction::Batch<algorithmFPType, prediction::predictRatingsDense> algorithm; algorithm.parameter.nFactors = nFactors; algorithm.input.set(prediction::data, dataTable); algorithm.input.set(prediction::model, trainingResult->get(training::model)); algorithm.compute(); services::SharedPtr<NumericTable> predictedRatings = algorithm.getResult()->get(prediction::ratings); printNumericTable(predictedRatings, "Predicted ratings:"); } void testModel() { /* Create an algorithm object to prediction recommendations of the implicit ALS model */ prediction::Batch<> algorithm; int indices[nIndices] = { 0, 1, 2, 3, 4 }; services::SharedPtr<NumericTable> indicesTable(new HomogenNumericTable<int>(indices, 1, nIndices)); algorithm.parameter.nFactors = nFactors; algorithm.parameter.nRecommendations = nRecommendations; algorithm.input.set(prediction::indices, indicesTable); algorithm.input.set(prediction::model, trainingResult->get(training::model)); /* Predict recommendations of the implicit ALS model */ algorithm.compute(); services::SharedPtr<prediction::Result> predictionResult = algorithm.getResult(); printNumericTable(predictionResult->get(prediction::itemsIds), "Recommended items IDs:"); printNumericTable(predictionResult->get(prediction::ratings ), "Recommended items ratings:"); }
Compilation process:
> icpc -daal test.cpp test.cpp(76): error: argument of type "daal::algorithms::implicit_als::training::ResultId" is incompatible with parameter of type "daal::algorithms::implicit_als::training::init::ResultId" initialModel = initAlgorithm.getResult()->get(training::model); ^ test.cpp(94): error: namespace "daal::algorithms::implicit_als::prediction" has no member "Batch" prediction::Batch<algorithmFPType, prediction::predictRatingsDense> algorithm; ^ test.cpp(94): error: type name is not allowed prediction::Batch<algorithmFPType, prediction::predictRatingsDense> algorithm; ^ test.cpp(94): error: namespace "daal::algorithms::implicit_als::prediction" has no member "predictRatingsDense" prediction::Batch<algorithmFPType, prediction::predictRatingsDense> algorithm; ^ test.cpp(94): error: identifier "algorithm" is undefined prediction::Batch<algorithmFPType, prediction::predictRatingsDense> algorithm; ^ test.cpp(96): error: namespace "daal::algorithms::implicit_als::prediction" has no member "data" algorithm.input.set(prediction::data, dataTable); ^ test.cpp(97): error: namespace "daal::algorithms::implicit_als::prediction" has no member "model" algorithm.input.set(prediction::model, trainingResult->get(training::model)); ^ test.cpp(99): error: a namespace name is not allowed services::SharedPtr<NumericTable> predictedRatings = algorithm.getResult()->get(prediction::ratings); ^ test.cpp(105): error: namespace "daal::algorithms::implicit_als::prediction" has no member "Batch" prediction::Batch<> algorithm; ^ test.cpp(105): error: expected an expression prediction::Batch<> algorithm; ^ test.cpp(108): error: identifier "algorithm" is undefined algorithm.parameter.nFactors = nFactors; ^ test.cpp(110): error: namespace "daal::algorithms::implicit_als::prediction" has no member "indices" algorithm.input.set(prediction::indices, indicesTable); ^ test.cpp(111): error: namespace "daal::algorithms::implicit_als::prediction" has no member "model" algorithm.input.set(prediction::model, trainingResult->get(training::model)); ^ test.cpp(114): error: namespace "daal::algorithms::implicit_als::prediction" has no member "Result" services::SharedPtr<prediction::Result> predictionResult = algorithm.getResult(); ^ test.cpp(115): error: namespace "daal::algorithms::implicit_als::prediction" has no member "itemsIds" printNumericTable(predictionResult->get(prediction::itemsIds), "Recommended items IDs:"); ^ test.cpp(116): error: a namespace name is not allowed printNumericTable(predictionResult->get(prediction::ratings ), "Recommended items ratings:"); ^ compilation aborted for test.cpp (code 2)
Can you please show me working example of testModel() function, if it's not too much to ask. Thank you in advance.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Vadim,
The latest release of Intel® DAAL doesn't contain transpose functionality. To transpose back the results of ALS prediction you could use following code:
void printTransposedNumericTable(services::SharedPtr<NumericTable> dataTable, const char *message) { size_t nRows = dataTable->getNumberOfRows(); size_t nCols = dataTable->getNumberOfColumns(); BlockDescriptor<double> block; dataTable->getBlockOfRows(0, nRows, readOnly, block); double *data = block.getBlockPtr(); double *transposedData = new double[nRows * nCols]; std::cout << std::endl << message << std::endl; for (size_t i = 0; i < nRows; i++) { for (size_t j = 0; j < nCols; j++) { transposedData[i * nCols + j] = data[j * nRows + i]; std::cout << std::setw(10) << std::setiosflags(std::ios::fixed) << std::setprecision(3); std::cout << transposedData[i * nCols + j]; } std::cout << std::endl; } dataTable->releaseBlockOfRows(block); delete [] transposedData; }
This function reads the data from input numeric table dataTable, transposes the data and prints the transposed results. transposedData array contains the data in the correct layout.
Regarding the code snippet from ZIP archive. That ZIP archive contains outdated version of the examples. Please refer to Intel® DAAL Programming Guide for the correct version of the examples: https://software.intel.com/en-us/daal-programming-guide
We will remove the outdated version of the codes from the web.
Best regards,
Victoriya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Victoriya! Your answers are very informative and helpful.
If I may, I would like to ask the last question. For ALS algorithm, is there DAAL's way to get "most recommended" ItemID. Or do I have to check manually all the predicted ratings for particular User to find the corresponding ItemID with the highest rating (or several of them, for instance)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ALS algorithms has one prediction method that computes the ratings for all users and all items based on the trained model. Please refer to the following topic of Intel® DAAL Programming Guide for the description of ALS prediction:
https://software.intel.com/en-us/node/599535
To find the "most recommended" itemID for the user you need to find maximal rating among the ratings computed for this user. The itemID that corresponds to the maximal rating is the "most recommended" itemID.
Best regards,
Victoriya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page