# Path: algo/const.py
# NUM_SETS = 5
# 
# RANK_SIZE = 5
# 
# REP = 3
# 
# Path: perf/metrics.py
# def calculate_rmse(result, truth):
#   """ Calculates RMSE (Root Mean Squared Error) of a prediction task.
# 
#       Args:
#         result: a list of predicted values assigned to the instances.
#         truth: a list with the corrected values.
# 
#       Returns:
#         A real value representing the RMSE.
#   """
#   errors = calculate_squared_errors(result, truth)
#   rmse = sqrt(float(sum(errors)) / len(errors))
#   return rmse
# 
# def calculate_avg_ndcg(votes, reviews, pred, truth, k):
#   """ Calculates the average nDCG by grouping votes in (user, product) pairs in
#       order to compose rankings.
# 
#       Args:
#         votes: set of votes to evaluate through grouping and ranking.
#         reviews: dictionary of reviews.
#         pred: list of floats with predicted relevances for each vote in votes.
#         truth: list of floats (or integers) with true relevances for each vote
#       in votes.
#         k: an integer with the limit position of the ranking to calculate the
#       score.
# 
#       Returns:
#         A float in range [0, 1] with nDCG@K score.
#   """
#   pred_group = {}
#   truth_group = {}
#   for i, vote in enumerate(votes):
#     voter = vote['voter']
#     product = reviews[vote['review']]['product']
#     key = (voter, product)
#     if key not in pred_group:
#       pred_group[key] = []
#       truth_group[key] =[]
#     pred_group[key].append(pred[i])
#     truth_group[key].append(truth[i])
#   score_sum = 0.0
#   for key in pred_group:
#     ndcg = calculate_ndcg(pred_group[key], truth_group[key], k)
#     score_sum += ndcg
#   score = score_sum / len(pred_group)
#   return score


from math import sqrt
from sys import argv, exit
from time import time
from random import shuffle
from numpy import nan, isnan, copy
from numpy.random import uniform, seed
from pickle import load
from algo.const import NUM_SETS, RANK_SIZE, REP 
from perf.metrics import calculate_rmse, calculate_avg_ndcg

def main():
  """ Predicts helpfulness votes using MF.

      Args:
        None.

      Returns:
        None. Results are printed to files.
  """
  load_args()
  
  for i in xrange(NUM_SETS):
    print 'Reading pickles'
    train = load(open('%s/train-%d.pkl' % (_PKL_DIR, i), 'r'))
    val = load(open('%s/validation-%d.pkl' % (_PKL_DIR, i), 'r'))
    test = load(open('%s/test-%d.pkl' % (_PKL_DIR, i), 'r'))
    reviews = load(open('%s/reviews-%d.pkl' % (_PKL_DIR, i), 'r'))
    truth = [v['vote'] for v in train]
    
    for j in xrange(REP):
      print 'Fitting Model'
      model = MF_Model()
      model.fit(train)

      print 'Calculating Predictions'
      pred = model.predict(train)
      print 'TRAINING ERROR'
      print '-- RMSE: %f' % calculate_rmse(pred, truth)
      print '-- nDCG@%d: %f' % (RANK_SIZE, calculate_avg_ndcg(train, reviews,

# Path: algo/const.py
# NUM_SETS = 5
# 
# RANK_SIZE = 5
# 
# REP = 3
# 
# Path: perf/metrics.py
# def calculate_rmse(result, truth):
#   """ Calculates RMSE (Root Mean Squared Error) of a prediction task.
# 
#       Args:
#         result: a list of predicted values assigned to the instances.
#         truth: a list with the corrected values.
# 
#       Returns:
#         A real value representing the RMSE.
#   """
#   errors = calculate_squared_errors(result, truth)
#   rmse = sqrt(float(sum(errors)) / len(errors))
#   return rmse
# 
# def calculate_avg_ndcg(votes, reviews, pred, truth, k):
#   """ Calculates the average nDCG by grouping votes in (user, product) pairs in
#       order to compose rankings.
# 
#       Args:
#         votes: set of votes to evaluate through grouping and ranking.
#         reviews: dictionary of reviews.
#         pred: list of floats with predicted relevances for each vote in votes.
#         truth: list of floats (or integers) with true relevances for each vote
#       in votes.
#         k: an integer with the limit position of the ranking to calculate the
#       score.
# 
#       Returns:
#         A float in range [0, 1] with nDCG@K score.
#   """
#   pred_group = {}
#   truth_group = {}
#   for i, vote in enumerate(votes):
#     voter = vote['voter']
#     product = reviews[vote['review']]['product']
#     key = (voter, product)
#     if key not in pred_group:
#       pred_group[key] = []
#       truth_group[key] =[]
#     pred_group[key].append(pred[i])
#     truth_group[key].append(truth[i])
#   score_sum = 0.0
#   for key in pred_group:
#     ndcg = calculate_ndcg(pred_group[key], truth_group[key], k)
#     score_sum += ndcg
#   score = score_sum / len(pred_group)
#   return score


# Path: algo/recsys/mf.py
from math import sqrt
from sys import argv, exit
from time import time
from random import shuffle
from numpy import nan, isnan, copy
from numpy.random import uniform, seed
from pickle import load
from algo.const import NUM_SETS, RANK_SIZE, REP 
from perf.metrics import calculate_rmse, calculate_avg_ndcg


def main():
  """ Predicts helpfulness votes using MF.

      Args:
        None.

      Returns:
        None. Results are printed to files.
  """
  load_args()
  
  for i in xrange(NUM_SETS):
    print 'Reading pickles'
    train = load(open('%s/train-%d.pkl' % (_PKL_DIR, i), 'r'))
    val = load(open('%s/validation-%d.pkl' % (_PKL_DIR, i), 'r'))
    test = load(open('%s/test-%d.pkl' % (_PKL_DIR, i), 'r'))
    reviews = load(open('%s/reviews-%d.pkl' % (_PKL_DIR, i), 'r'))
    truth = [v['vote'] for v in train]
    
    for j in xrange(REP):
      print 'Fitting Model'
      model = MF_Model()
      model.fit(train)

      print 'Calculating Predictions'
      pred = model.predict(train)
      print 'TRAINING ERROR'
      print '-- RMSE: %f' % calculate_rmse(pred, truth)
      print '-- nDCG@%d: %f' % (RANK_SIZE, calculate_avg_ndcg(train, reviews,

          pred, truth, RANK_SIZE))