Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Up to line 135 the code works as it should, I get RMSE = 0 through the part with cout. But when I add the

Up to line 135 the code works as it should, I get RMSE = 0 through the part with cout. But when I add the part after line 135 to my code, I cannot run the program. Have I added this part in the wrong place? Normally the program needs to write the predicted ratings to a new .csv file, but this does not happen because the code is not working properly. Please help me with this. By the way, is there anything extra I need to do so that the code can read test.csv and train.csv? Other than that, I'm free to change the inside of the function with int main() to lower the RMSE value even more, right?

#include #include #include #include #include #include #include #include

// A struct to represent a rating given by a user to an item struct Rating { int user_id; int item_id; float rating; };

// A struct to represent a predicted rating for an item struct PredictedRating { int id; int user_id; int item_id; float rating; };

// Reads the ratings from a .csv file and returns them as a vector std::vector read_ratings(const std::string& filename) { std::vector ratings;

std::ifstream file(filename); if (file.is_open()) { std::string line; // Skip the first line (header) std::getline(file, line); while (std::getline(file, line)) { Rating rating; std::sscanf(line.c_str(), "%d,%d,%f", &rating.user_id, &rating.item_id, &rating.rating); ratings.push_back(rating); } file.close(); }

return ratings; }

// Reads the test cases from a .csv file and returns them as a vector std::vector read_test_cases(const std::string& filename) { std::vector test_cases;

std::ifstream file(filename); if (file.is_open()) { std::string line; // Skip the first line (header) std::getline(file, line); while (std::getline(file, line)) { PredictedRating test_case; std::sscanf(line.c_str(), "%d,%d,%d", &test_case.id, &test_case.user_id, &test_case.item_id); test_cases.push_back(test_case); } file.close(); }

return test_cases; }

// Calculates the root mean squared error between the predicted ratings and the actual ratings float calculate_rmse(const std::vector& predicted_ratings, const std::vector& actual_ratings) { float sum_squared_error = 0.0f; for (const auto& predicted_rating : predicted_ratings) { auto actual_rating_iter = std::find_if(actual_ratings.begin(), actual_ratings.end(), [&](const Rating& r) { return r.user_id == predicted_rating.user_id && r.item_id == predicted_rating.item_id; }); if (actual_rating_iter != actual_ratings.end()) { sum_squared_error += std::pow(predicted_rating.rating - actual_rating_iter->rating, 2); } } return std::sqrt(sum_squared_error / predicted_ratings.size()); }

float predict_rating_mean_user(int user_id, int item_id, const std::unordered_map>& user_ratings) { if (user_ratings.count(user_id) == 0) { // If the user has not rated any items, return the mean rating of all users float sum_ratings = 0.0f; int num_ratings = 0; for (const auto& [_, ratings] : user_ratings) { for (const auto& rating : ratings) { sum_ratings += rating.rating; num_ratings++; } } return sum_ratings / num_ratings; } else { // If the user has rated items, return the mean rating of the user float sum_ratings = 0.0f; int num_ratings = 0; for (const auto& rating : user_ratings.at(user_id)) { sum_ratings += rating.rating; num_ratings++; } return sum_ratings / num_ratings; } }

int main() { // Read in the training and test sets std::vector training_set = read_ratings("training.csv"); std::vector test_set = read_test_cases("test.csv");

// Initialize a map to store the ratings given by each user std::unordered_map> user_ratings; for (const auto& rating : training_set) { user_ratings[rating.user_id].push_back(rating); }

// Initialize a map to store the ratings received by each item std::unordered_map> item_ratings; for (const auto& rating : training_set) { item_ratings[rating.item_id].push_back(rating); }

// Predict the ratings for the test set using the mean rating of the user for (auto& predicted_rating : test_set) { predicted_rating.rating = predict_rating_mean_user(predicted_rating.user_id, predicted_rating.item_id, user_ratings); }

// Calculate the RMSE between the predicted ratings and the actual ratings float rmse = calculate_rmse(test_set, training_set); std::cout << "RMSE: " << rmse << std::endl;

return 0; }

// Calculates the predicted rating for an item using user-based collaborative filtering (UBCF) float calculate_predicted_rating_using_ubcf(int user_id, int item_id, const std::unordered_map>& user_ratings, const std::vector& all_ratings) { // Get the ratings given by the user to other items std::vector user_item_ratings = user_ratings.at(user_id);

// Initialize variables to store the numerator and denominator of the prediction formula float numerator = 0.0f; float denominator = 0.0f;

// Calculate the numerator and denominator for each item rated by the user for (const auto& rating : user_item_ratings) { // Calculate the similarity between the current item and the item being rated float similarity = calculate_similarity(item_id, rating.item_id, all_ratings); numerator += similarity * rating.rating; denominator += similarity; }

// Return the predicted rating return numerator / denominator; }

// Calculates the predicted rating for an item using item-based collaborative filtering (IBCF) float calculate_predicted_rating_using_ibcf(int user_id, int item_id, const std::unordered_map>& item_ratings, const std::vector& all_ratings) { // Get the ratings received by the item from other users std::vector item_user_ratings = item_ratings.at(item_id);

// Initialize variables to store the numerator and denominator of the prediction formula float numerator = 0.0f; float denominator = 0.0f;

// Calculate the numerator and denominator for each user who rated the item for (const auto& rating : item_user_ratings) { // Calculate the similarity between the current user and the user who rated the item

float similarity = calculate_similarity(user_id, rating.user_id, all_ratings); numerator += similarity * rating.rating; denominator += similarity; }

// Return the predicted rating return numerator / denominator; }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions