NUM_SETS = 5 RANK_SIZE = 5 REP = 3 REVIEW_FEATS = {
  'www': ['num_tokens', 'num_sents', 'uni_ratio', 'avg_sent',
    'cap_sent', 'noun_ratio', 'adj_ratio', 'comp_ratio', 'verb_ratio',
    'adv_ratio', 'fw_ratio', 'sym_ratio', 'num_ratio', 'punct_ratio', 'kl',
    'pos_ratio', 'neg_ratio'],
  'sel': ['num_tokens', 'uni_ratio', 'noun_ratio', 'sym_ratio', 'fw_ratio',
    'kl', 'avg_sent', 'punct_ratio'],
  'cap': ['num_tokens', 'num_sents', 'uni_ratio', 'avg_sent',
    'cap_sent', 'noun_ratio', 'adj_ratio', 'comp_ratio', 'verb_ratio',
    'adv_ratio', 'fw_ratio', 'sym_ratio', 'num_ratio', 'punct_ratio', 'kl',
    'pos_ratio', 'neg_ratio'],
  'all': ['num_tokens', 'num_sents', 'uni_ratio', 'avg_sent',
    'cap_sent', 'noun_ratio', 'adj_ratio', 'comp_ratio', 'verb_ratio',
    'adv_ratio', 'fw_ratio', 'sym_ratio', 'num_ratio', 'punct_ratio', 'kl',
    'pos_ratio', 'neg_ratio'],
  'svr_top10': ['noun_ratio', 'uni_ratio', 'sym_ratio', 'punct_ratio',
    'verb_ratio', 'comp_ratio', 'kl'],
  'spear_top10': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top10m': ['num_tokens', 'uni_ratio'],
  'spear_top10': ['num_tokens', 'uni_ratio'],
  'new_sel': ['num_tokens', 'uni_ratio'],
  'ig_top5': ['num_tokens', 'num_sents', 'uni_ratio'],
  'ig_top10': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top1': ['num_tokens'],
  'spear_top2': ['num_tokens', 'num_sents'],
  'spear_top3': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top4': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top5': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top5m': ['num_tokens', 'uni_ratio'],
  'spear_top6': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top7': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top8': ['num_tokens', 'num_sents', 'uni_ratio'],
  'spear_top9': ['num_tokens', 'num_sents', 'uni_ratio']
} AUTHOR_FEATS = {
  'www': ['num_reviews', 'avg_rating', 'num_trustors', 'num_trustees',
    'pagerank'],
  'sel': ['num_trustors'],
  'cap': ['num_reviews', 'avg_rating', 'num_trustors', 'num_trustees',
    'pagerank'],
  'all': ['num_reviews', 'avg_rating', 'num_trustors', 'num_trustees',
    'pagerank', 'num_votes_rec', 'num_votes_giv', 'sd_rating', 'sd_help_rec',
    'sd_help_giv', 'avg_rel_rating', 'avg_help_rec', 'avg_help_giv',
    'avg_rel_help_giv', 'avg_rating_sim', 'avg_help_giv_sim',
    'avg_rating_dir_net', 'avg_help_giv_tru_net'],
  'svr_top10': [],
  'spear_top10': ['num_trustees', 'num_trustors', 'num_reviews'],
  'spear_top10m': ['num_trustees', 'num_trustors', 'num_reviews'],
  'new_sel': ['num_trustees', 'num_trustors', 'num_reviews'],
  'ig_top5': ['pagerank', 'num_trustees'],
  'ig_top10': ['pagerank', 'num_trustees'],
  'spear_top1': [],
  'spear_top2': [],
  'spear_top3': [],
  'spear_top4': [],
  'spear_top5': ['num_trustees'],
  'spear_top5m': ['num_trustees'],
  'spear_top6': ['num_trustees', 'num_trustors'],
  'spear_top7': ['num_trustees', 'num_trustors'],
  'spear_top8': ['num_trustees', 'num_trustors'],
  'spear_top9': ['num_trustees', 'num_trustors']
} VOTER_FEATS = {
  'www': [],
  'sel': ['avg_help_giv', 'avg_help_giv_tru_net'],
  'cap': ['num_trustors', 'num_trustees', 'pagerank', 'avg_rating',
    'avg_rating_dir_net', 'avg_rating_sim', 'avg_help_giv', 'avg_help_giv_sim', 
    'avg_help_giv_tru_net'],
  'all': ['num_reviews', 'avg_rating', 'num_trustors', 'num_trustees',
    'pagerank', 'num_votes_rec', 'num_votes_giv', 'sd_rating', 'sd_help_rec',
    'sd_help_giv', 'avg_rel_rating', 'avg_help_rec', 'avg_help_giv',
    'avg_rel_help_giv', 'avg_rating_sim', 'avg_help_giv_sim',
    'avg_rating_dir_net', 'avg_help_giv_tru_net'],
  'svr_top10': ['avg_help_giv'],
  'spear_top10': ['avg_help_giv'],
  'spear_top10m': ['avg_help_giv'],
  'new_sel': ['avg_help_giv'],
  'ig_top5': [],
  'ig_top10': ['avg_help_giv', 'pagerank', 'avg_rating_dir_net',
    'avg_rating_sim', 'avg_help_giv_sim'],
  'spear_top1': [],
  'spear_top2': [],
  'spear_top3': [],
  'spear_top4': ['avg_help_giv'],
  'spear_top5': ['avg_help_giv'],
  'spear_top5m': ['avg_help_giv'],
  'spear_top6': ['avg_help_giv'],
  'spear_top7': ['avg_help_giv'],
  'spear_top8': ['avg_help_giv'],
  'spear_top9': ['avg_help_giv']
} SIM_FEATS = {
  'www': [],
  'sel': ['jacc_rated', 'common_rated'],
  'cap': ['common_rated', 'jacc_rated', 'cos_ratings', 'pear_ratings',
    'diff_avg_ratings', 'diff_max_ratings', 'diff_min_ratings'],
  'all': ['common_rated', 'jacc_rated', 'cos_ratings', 'pear_ratings',
    'diff_avg_ratings', 'diff_max_ratings', 'diff_min_ratings'],
  'svr_top10': [],
  'svr_top10m': [],
  'new_sel': ['diff_trustors', 'diff_reviews', 'diff_pagerank', 'diff_close',
    'diff_eigen'],
  'spear_top10': [],
  'ig_top5': [],
  'ig_top10': [],
  'spear_top1': [],
  'spear_top2': [],
  'spear_top3': [],
  'spear_top4': [],
  'spear_top5': [],
  'spear_top5m': [],
  'spear_top6': [],
  'spear_top7': [],
  'spear_top8': [],
  'spear_top9': []
} CONN_FEATS = {
  'www': [],
  'cap': ['jacc_trustees', 'jacc_trustors', 'adamic_adar_trustees',
    'adamic_adar_trustors', 'katz'],
  'sel': ['jacc_trustees', 'adamic_adar_trustees', 'adamic_adar_trustors'], 
  'all': ['jacc_trustees', 'jacc_trustors', 'adamic_adar_trustees',
    'adamic_adar_trustors', 'katz'],
  'svr_top10': ['jacc_trustors', 'adamic_adar_trustors'],
  'spear_top10': ['jacc_trustees', 'adamic_adar_trustees',
    'adamic_adar_trustors'],
  'spear_top10m': ['jacc_trustees', 'adamic_adar_trustees',
    'adamic_adar_trustors'],
  'new_sel': ['jacc_trustees', 'adamic_adar_trustees', 'adamic_adar_trustors', 
    'voter_trust',  'author_trust', 'inv_from_vot_path', 'inv_from_aut_path'],
  'ig_top5': [],
  'ig_top10': [],
  'spear_top1': [],
  'spear_top2': [],
  'spear_top3': [],
  'spear_top4': [],
  'spear_top5': [],
  'spear_top5m': [],
  'spear_top6': ['jacc_trustees'],
  'spear_top7': ['jacc_trustees'],
  'spear_top8': ['jacc_trustees', 'adamic_adar_trustees'],
  'spear_top9': ['jacc_trustees', 'adamic_adar_trustees',
      'adamic_adar_trustors']
} 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 def compute_avg_user(users):
  """ Creates an average user model for mean imputation.

      Args:
        users: the modeled dictionary of users.

      Returns:
        A dictionary representing a user with average feature values.
  """
  avg_user = {}
  for feature in users.itervalues().next():
    avg_user[feature] = 0.0
  missing = []
  for feature in avg_user:
    if feature in ['id', 'ratings', '_id', 'similars', 'trustees', 'trustors']:
      continue
    avg_user[feature] = 0.0
    count = 0
    for user in users.itervalues():
      if not isnan(user[feature]):
        try:
          avg_user[feature] += user[feature]
        except:
          print feature
          print avg_user
          print user
        count += 1
    if count == 0:
      missing.append(feature)
    else:
      avg_user[feature] /= float(count)
  for feature in missing:
    if feature == 'avg_help_giv_sim' or feature == 'avg_help_giv_tru_net':
      avg_user[feature] = avg_user['avg_help_giv']
    elif feature == 'avg_rating_sim' or feature == 'avg_rating_fir_net':
      avg_user[feature] = avg_user['avg_rating']
  avg_user['id'] = avg_user['_id'] = None
  avg_user['ratings'] = {}
  avg_user['similars'] = []
  avg_max = []
  avg_min = []
  for user in users.itervalues():
    if user['ratings']:
      avg_max.append(max(user['ratings'].values()))
      avg_min.append(min(user['ratings'].values()))
  avg_user['avg_max'] = mean(avg_max)
  avg_user['avg_min'] = mean(avg_min)
  return avg_user def compute_avg_model(model):
  """ Creates an average user model for mean imputation.

      Args:
        users: the modeled dictionary of users.

      Returns:
        A dictionary representing a user with average feature values.
  """
  avg_entity = {}
  for feature in model.itervalues().next():
    avg_entity[feature] = 0.0
  for feature in avg_entity:
    count = 0.0
    for user in model.itervalues():
      if not isnan(user[feature]):
        avg_entity[feature] += user[feature]
        count += 1.0
    avg_entity[feature] /= count
  return avg_entity class BiasModel(object):
  """ Class implementing a Bias Baseline Model. """

  def __init__(self):
    """ Discriminates existing attributes, initilizing all to None.

        Args:
          None.

        Returns:
          None.
    """
    self.product_bias = None
    self.author_bias = None
    self.voter_bias = None
    self.overall_mean = None

  def _initialize(self, votes, reviews):
    """ Initializes bias values for each entity and calculates overall average.

        Observation:
        - Instead of using random values, static estimation is used by averaging
          deviation from mean (or mean + previous bias).

        Args:
          votes: list of votes (training set).
          reviews: dictionary of reviews, to obtain product.
        
        Returns:
          None. Instance fields are updated.
    """
    self.voter_bias = {}
    voter_count = {}
    self.author_bias = {}
    author_count = {}
    self.product_bias = {}
    product_count = {}
    self.overall_mean = 0
    count = 0
    for vote in votes:
      self.overall_mean += vote['vote']
      count += 1
    self.overall_mean /= float(count)
    for vote in votes:
      voter = vote['voter']
      if voter not in self.voter_bias:
        self.voter_bias[voter] = 0
        voter_count[voter] = 0
      self.voter_bias[voter] += (vote['vote'] - self.overall_mean)
      voter_count[voter] += 1
    for voter in self.voter_bias:
      self.voter_bias[voter] /= float(voter_count[voter])
    for vote in votes:
      voter = vote['voter']
      author = vote['author']
      if author not in self.author_bias:
        self.author_bias[author] = 0
        author_count[author] = 0
      self.author_bias[author] += (vote['vote'] - self.overall_mean -
          self.voter_bias[voter]) 
      author_count[author] += 1
    for author in self.author_bias:
      self.author_bias[author] /= float(author_count[author])
    for vote in votes:
      voter = vote['voter']
      author = vote['author']
      product = reviews[vote['review']]['product']
      if product not in self.product_bias:
        self.product_bias[product] = 0
        product_count[product] = 0
      self.product_bias[product] += (vote['vote'] - self.overall_mean -
          self.voter_bias[voter] - self.author_bias[author]) 
      product_count[product] += 1
    for product in self.product_bias:
      self.product_bias[product] /= float(product_count[product])
    
  def fit(self, votes, reviews):
    """ Fits a Bias Baseline model given training set (votes).

        Args:
          vote: list of votes, represented as dictionaries (training set).
          reviews: dictionary of reviews.
        
        Returns:
          None. Instance fields are updated.
    """
    self._initialize(votes, reviews)
    previous = float('inf')
    for _ in xrange(_ITER):
      for vote in votes:
        voter = vote['voter']
        author = vote['author']
        product = reviews[vote['review']]['product']
        pred = self.overall_mean + self.voter_bias[voter] + \
            self.author_bias[author] + self.product_bias[product]
        error = pred - float(vote['vote']) 
        # one does not depend on the other: no need for temporary variables
        self.voter_bias[voter] -= _ALPHA * 2 * (error + _BETA *
            self.voter_bias[voter])
        self.author_bias[author] -= _ALPHA * 2 * (error + _BETA * \
            self.author_bias[author])
        self.product_bias[product] -= _ALPHA * 2 * (error + _BETA * \
            self.product_bias[product])
      value = 0.0
      for vote in votes:
        voter = vote['voter']
        author = vote['author']
        product = reviews[vote['review']]['product']
        pred = self.overall_mean + self.voter_bias[voter] + \
            self.author_bias[author] + self.product_bias[product]
        value += (vote['vote'] - pred) ** 2
      for voter in self.voter_bias:
        value += self.voter_bias[voter] ** 2
      for author in self.author_bias:
        value += self.author_bias[author] ** 2
      for product in self.product_bias:
        value += self.product_bias[product] ** 2
      if abs(previous - value) < _TOL:
        print 'Convergence'
        break
      previous = value

  def fit_transform(self, votes, reviews):
    """ Fits Bias Model on data and adjust vote values to contain only unbiased
        value.

        Args:
          votes: list of votes to learn model and transform values.
          reviews: dictionary of reviews.

        Returns:
          None. Changes are made in place.
    """
    self.fit(votes, reviews)
    return self.transform(votes, reviews)

  def predict(self, votes, reviews):
    """ Predicts a set of vote examples using previous fitted model.

        Args:
          votes: list of dictionaries, representing votes, to predict
        helpfulness vote value.
          reviews: dictionary of reviews.

        Returns:
          A list of floats with predicted vote values.
    """
    pred = []
    for vote in votes:
      voter = vote['voter']
      author = vote['author']
      product = reviews[vote['review']]['product'] 
      value = self.overall_mean
      if voter in self.voter_bias: # if no bias, we assume 0
        dot += self.voter_bias[voter]
      if author in self.author_bias:
        dot += self.author_bias[author]
      if product in self.product_bias:
        dot += self.product_bias[product]
      pred.append(value)
    return pred

  def transform(self, votes, reviews):
    """ Removes bias values and overall mean from votes.

        Args:
          votes: list of votes to remove bias; it should be the same list
        fitted, because all entities have to have a bias associated.
          reviews: dictionary of reviews.

        Returns:
          A new list of votes with unbiased values. 
    """
    new_votes = []
    for vote in votes:
      new_vote = vote.copy()
      voter = vote['voter']
      author = vote['author']
      product = reviews[vote['review']]['product']
      new_vote['vote'] -= self.overall_mean + self.voter_bias[voter] + \
          self.author_bias[author] + self.product_bias[product]
      new_votes.append(new_vote) 
    return new_votes

  def add_bias(self, votes, reviews, pred):
    """ Removes bias values and overall mean from votes.

        Args:
          votes: votes whose values are being predicted.
          reviews: dictionary of reviews.
          pred: unbiased estimates of votes.

        Returns:
          None. The pred list is changed in place.
    """
    for index, vote in enumerate(votes):
      voter = vote['voter']
      author = vote['author']
      product = reviews[vote['review']]['product']
      if isnan(pred[index]):
        continue
      pred[index] += self.overall_mean
      if voter in self.voter_bias:
        pred[index] += self.voter_bias[voter]
      if author in self.author_bias:
        pred[index] += self.author_bias[author]
      if product in self.product_bias:
        pred[index] += self.product_bias[product] def fit_scaler(scale_type, data):
  """ Fits a scaler to a data.

      Args:
        scale_type: indicates the type of scale to adopt. It can be 'standard' to 
          scale with zero mean and unit standard deviation, or 'minmax' for range
          between 0 and 1.
        data: list of arrays with instances to be scaled.

      Returns:
        A scaler that fits the data.
  """
  if scale_type == 'standard':
    return StandardScaler(copy=False).fit(data)
  if scale_type == 'minmax':
    return MinMaxScaler(copy=False).fit(data) def fit_scaler_by_query(scale_type, data, qid, qid_dep_size):
  """ Fits a scaler to data.

      Args:
        scale_type: indicates the type of scale to adopt. It can be 'standard' to 
          scale with zero mean and unit standard deviation, or 'minmax' for range
          between 0 and 1.
        data: list of arrays with instances to be scaled.
        qid: list of query ids associated to each instance.
        qid_dep_size: number of features query-dependent, which are in the end
          of the instance array of features.

      Returns:
        A scaler that fits the data.
  """
  data = array(data)
  dim = data.shape[1]
  q_undep, q_dep = hsplit(data, [dim-qid_dep_size])
  if scale_type == 'standard':
    overall_scaler = StandardScaler(copy=False).fit(q_undep)
  if scale_type == 'minmax':
    overall_scaler = MinMaxScaler(copy=False).fit(q_undep)
  return overall_scaler def scale_features(scaler, data, qid=None, qid_dep_size=None, 
    scale_type='minmax'):
  """ Scales features from data given a fitted scaler. 

      Args:
        scaler: a scaler object with transform function.
        data: list of instances to scale. 
        qid: list of query ids associated to each instance.
        qid_dep_size: number of features query-dependent, which are in the end
          of the instance array of features.
        scale_type: indicates the type of scale to adopt. It can be 'standard' to 
          scale with zero mean and unit standard deviation, or 'minmax' for range
          between 0 and 1.

      Returns:
        A pair with scaled train and test sets. 
  """
  data = array(data)
  if qid is None:
    data = scaler.transform(data)
  else:
    dim = data.shape[1]
    overall_scaler = scaler 
    q_undep, q_dep = hsplit(data, [dim-qid_dep_size])
    q_undep = overall_scaler.transform(q_undep)
    qid_grouped = group_by_qid(q_dep, qid)
    q_scalers = {}
    for q in qid_grouped: 
      if scale_type == 'minmax':
        q_scalers[q] = MinMaxScaler(copy=False).fit(qid_grouped[q])
      if scale_type == 'standard':
        q_scalers[q] = StandardScaler(copy=False).fit(qid_grouped[q])
    for i in xrange(q_dep.shape[0]):
      q_dep[i] = q_scalers[qid[i]].transform([q_dep[i]])
    data = hstack((q_undep, q_dep))
  return data 
from pickle import load
from sys import argv, exit
from time import time
from numpy import nan, isnan, mean
from numpy.random import binomial
from sklearn.svm import SVR
from algo.const import NUM_SETS, RANK_SIZE, REP, REVIEW_FEATS, AUTHOR_FEATS, \
    VOTER_FEATS, SIM_FEATS, CONN_FEATS
from perf.metrics import calculate_rmse, calculate_avg_ndcg
from util.avg_model import compute_avg_user, compute_avg_model 
from util.bias import BiasModel
from util.scaling import fit_scaler, fit_scaler_by_query, scale_features

      Args:
        None.

      Returns:
        None. Global values of this module are updated. 
  """
  i = 1
  while i < len(argv): 
    if argv[i] == '-c':
      global _C
      _C = float(argv[i+1])
    elif argv[i] == '-k' and argv[i+1] in ['linear', 'rbf', 'poly', 'rbf',
        'sigmoid']:
      global _KERNEL 
      _KERNEL = argv[i+1]
    elif argv[i] == '-e':
      global _EPS
      _EPS = float(argv[i+1])
    elif argv[i] == '-f' and argv[i+1] in REVIEW_FEATS:
      global _FEAT_TYPE
      _FEAT_TYPE = argv[i+1]
    elif argv[i] == '-b' and argv[i+1] in ['y', 'n']:
      global _BIAS
      _BIAS = True if argv[i+1] == 'y' else False
    else:
      print ('Usage: $ python -m algo.reg.svr [-c <penalty>] [-k <kernel>] '
          '[-e <epsilon>] [-f <feature_set>] [-b <bias>]')
      exit()
    i = i + 2


def generate_input(reviews, users, sim, conn, votes, avg_user, avg_sim, avg_conn):
  """ Generates input for the regression problem by turning all features
      associated to each entity into a vector. 

      Args:
        reviews: dictionary of reviews.
        users: dictionary of users.
        sim: dictionary of author-voter similary, indexed by the pair.
        conn: dictionary of author-voter connection strength, indexed by the
          pair.
        votes: list of votes to extract features from.
        avg_user: dictionary of an average user for mean imputation.
        avg_sim: dictionary of an average similarity relation.
        avg_conn: dictionary of an average connection strength relation.

      Returns:
        A triple with an list of features' lists, a list of true votes and a
      list with query ids. 
  """
  X = []
  y = []
  qid = []
  for vote in votes:
    example = []
    review = reviews[vote['review']]
    for feature in REVIEW_FEATS[_FEAT_TYPE]:
      example.append(review[feature])
    author = users[vote['author']] if vote['author'] in users else avg_user
    for feature in AUTHOR_FEATS[_FEAT_TYPE]:
      if isnan(author[feature]):
        example.append(avg_user[feature]) 
      else:
        example.append(author[feature])
    voter = users[vote['voter']] if vote['voter'] in users else avg_user
    for feature in VOTER_FEATS[_FEAT_TYPE]:
      if isnan(voter[feature]):
        example.append(avg_user[feature]) 
      else:
        example.append(voter[feature]) 
    av = (author['id'], voter['id'])
    u_sim = sim[av] if av in sim else avg_sim
    for feature in SIM_FEATS[_FEAT_TYPE]:
      if isnan(u_sim[feature]):
        example.append(avg_sim[feature]) 
      else:
        example.append(u_sim[feature]) 
    u_conn = conn[av] if av in conn else avg_conn
    for feature in CONN_FEATS[_FEAT_TYPE]:
      if isnan(u_conn[feature]):
        example.append(avg_conn[feature]) 
      else:
        example.append(u_conn[feature]) 
    X.append(example)
    y.append(vote['vote'])
    qid.append(vote['voter'])
  return X, y, qid


def predict():
  """ Predicts votes by applying a SVR regressor technique.

      Args:
        None.

      Returns:
        None.
  """
  load_args()
  
  for i in xrange(NUM_SETS):
    t = time()

    print 'Reading data'
    reviews = load(open('%s/new-reviews-%d.pkl' % (_PKL_DIR, i), 'r'))
    users = load(open('%s/users-%d.pkl' % (_PKL_DIR, i), 'r'))
    train = load(open('%s/train-%d.pkl' % (_PKL_DIR, i), 'r'))
    test = load(open('%s/test-%d.pkl' % (_PKL_DIR, i), 'r'))
    val = load(open('%s/validation-%d.pkl' % (_PKL_DIR, i), 'r'))
    sim = load(open('%s/new-sim-%d.pkl' % (_PKL_DIR, i), 'r'))
    conn = load(open('%s/new-conn-%d.pkl' % (_PKL_DIR, i), 'r'))
    train_truth = [v['vote'] for v in train] 

    if _BIAS:
      bias = BiasModel()
      train = bias.fit_transform(train, reviews)

    avg_user = compute_avg_user(users)
    avg_sim = compute_avg_model(sim)

    avg_conn = compute_avg_model(conn)