def main(in_file, out_file, go_file, model_file, terms_file, annotations_file, chunk_size, diamond_file, threshold, batch_size, alpha): # Load GO and read list of all terms go = Ontology(go_file, with_rels=True) terms_df = pd.read_pickle(terms_file) terms = terms_df['terms'].values.flatten() # Read known experimental annotations annotations = {} df = pd.read_pickle(annotations_file) for row in df.itertuples(): annotations[row.proteins] = set(row.prop_annotations) go.calculate_ic(annotations.values()) diamond_preds = {} mapping = {} with gzip.open(diamond_file, 'rt') as f: for line in f: it = line.strip().split() if it[0] not in mapping: mapping[it[0]] = {} mapping[it[0]][it[1]] = float(it[2]) for prot_id, sim_prots in mapping.items(): annots = {} allgos = set() total_score = 0.0 for p_id, score in sim_prots.items(): allgos |= annotations[p_id] total_score += score allgos = list(sorted(allgos)) sim = np.zeros(len(allgos), dtype=np.float32) for j, go_id in enumerate(allgos): s = 0.0 for p_id, score in sim_prots.items(): if go_id in annotations[p_id]: s += score sim[j] = s / total_score for go_id, score in zip(allgos, sim): annots[go_id] = score diamond_preds[prot_id] = annots # Load CNN model model = load_model(model_file) # Alphas for the latest model alphas = {NAMESPACES['mf']: 0.55, NAMESPACES['bp']: 0.59, NAMESPACES['cc']: 0.46} # Alphas for the cafa2 model # alphas = {NAMESPACES['mf']: 0.63, NAMESPACES['bp']: 0.68, NAMESPACES['cc']: 0.48} start_time = time.time() total_seq = 0 w = gzip.open(out_file, 'wt') for prot_ids, sequences in read_fasta(in_file, chunk_size): total_seq += len(prot_ids) deep_preds = {} ids, data = get_data(sequences) preds = model.predict(data, batch_size=batch_size) assert preds.shape[1] == len(terms) for i, j in enumerate(ids): prot_id = prot_ids[j] if prot_id not in deep_preds: deep_preds[prot_id] = {} for l in range(len(terms)): if preds[i, l] >= 0.01: # Filter out very low scores if terms[l] not in deep_preds[prot_id]: deep_preds[prot_id][terms[l]] = preds[i, l] else: deep_preds[prot_id][terms[l]] = max( deep_preds[prot_id][terms[l]], preds[i, l]) # Combine diamond preds and deepgo for prot_id in prot_ids: annots = {} if prot_id in diamond_preds: for go_id, score in diamond_preds[prot_id].items(): annots[go_id] = score * alphas[go.get_namespace(go_id)] for go_id, score in deep_preds[prot_id].items(): if go_id in annots: annots[go_id] += (1 - alphas[go.get_namespace(go_id)]) * score else: annots[go_id] = (1 - alphas[go.get_namespace(go_id)]) * score # Propagate scores with ontology structure gos = list(annots.keys()) for go_id in gos: for g_id in go.get_anchestors(go_id): if g_id in annots: annots[g_id] = max(annots[g_id], annots[go_id]) else: annots[g_id] = annots[go_id] sannots = sorted(annots.items(), key=lambda x: x[1], reverse=True) for go_id, score in sannots: if score >= threshold: w.write(prot_id + '\t' + go_id + '\t' + go.get_term(go_id)['name'] + '\t%.2f' % go.get_ic(go_id) + '\t%.3f\n' % score) w.write('\n') w.close() total_time = time.time() - start_time print('Total prediction time for %d sequences is %d' % (total_seq, total_time))
def main(train_data_file, test_data_file, terms_file, diamond_scores_file, ont, alpha): alpha /= 100.0 go_rels = Ontology('data-cafa/go.obo', with_rels=True) terms_df = pd.read_pickle(terms_file) terms = terms_df['terms'].values.flatten() terms_dict = {v: i for i, v in enumerate(terms)} train_df = pd.read_pickle(train_data_file) test_df = pd.read_pickle(test_data_file) annotations = train_df['annotations'].values annotations = list(map(lambda x: set(x), annotations)) test_annotations = test_df['annotations'].values test_annotations = list(map(lambda x: set(x), test_annotations)) go_rels.calculate_ic(annotations + test_annotations) # Print IC values of terms ics = {} for term in terms: ics[term] = go_rels.get_ic(term) prot_index = {} for i, row in enumerate(train_df.itertuples()): prot_index[row.proteins] = i # BLAST Similarity (Diamond) diamond_scores = {} with open(diamond_scores_file) as f: for line in f: it = line.strip().split() if it[0] not in diamond_scores: diamond_scores[it[0]] = {} diamond_scores[it[0]][it[1]] = float(it[2]) blast_preds = [] for i, row in enumerate(test_df.itertuples()): annots = {} prot_id = row.proteins # BlastKNN if prot_id in diamond_scores: sim_prots = diamond_scores[prot_id] allgos = set() total_score = 0.0 for p_id, score in sim_prots.items(): allgos |= annotations[prot_index[p_id]] total_score += score allgos = list(sorted(allgos)) sim = np.zeros(len(allgos), dtype=np.float32) for j, go_id in enumerate(allgos): s = 0.0 for p_id, score in sim_prots.items(): if go_id in annotations[prot_index[p_id]]: s += score sim[j] = s / total_score ind = np.argsort(-sim) for go_id, score in zip(allgos, sim): annots[go_id] = score blast_preds.append(annots) # DeepGOPlus go_set = go_rels.get_namespace_terms(NAMESPACES[ont]) go_set.remove(FUNC_DICT[ont]) labels = test_df['annotations'].values labels = list(map(lambda x: set(filter(lambda y: y in go_set, x)), labels)) # print(len(go_set)) deep_preds = [] alphas = { NAMESPACES['mf']: 0.55, NAMESPACES['bp']: 0.59, NAMESPACES['cc']: 0.46 } for i, row in enumerate(test_df.itertuples()): annots_dict = blast_preds[i].copy() for go_id in annots_dict: annots_dict[go_id] *= alphas[go_rels.get_namespace(go_id)] for j, score in enumerate(row.preds): go_id = terms[j] score *= 1 - alphas[go_rels.get_namespace(go_id)] if go_id in annots_dict: annots_dict[go_id] += score else: annots_dict[go_id] = score deep_preds.append(annots_dict) print('AUTHOR DeepGOPlus') print('MODEL 1') print('KEYWORDS sequence alignment.') for i, row in enumerate(test_df.itertuples()): prot_id = row.proteins for go_id, score in deep_preds[i].items(): print(f'{prot_id}\t{go_id}\t{score:.2f}') print('END') return # Propagate scores # deepgo_preds = [] # for annots_dict in deep_preds: # annots = {} # for go_id, score in annots_dict.items(): # for a_id in go_rels.get_anchestors(go_id): # if a_id in annots: # annots[a_id] = max(annots[a_id], score) # else: # annots[a_id] = score # deepgo_preds.append(annots) fmax = 0.0 tmax = 0.0 precisions = [] recalls = [] smin = 1000000.0 rus = [] mis = [] for t in range(0, 101): threshold = t / 100.0 preds = [] for i, row in enumerate(test_df.itertuples()): annots = set() for go_id, score in deep_preds[i].items(): if score >= threshold: annots.add(go_id) new_annots = set() for go_id in annots: new_annots |= go_rels.get_anchestors(go_id) preds.append(new_annots) # Filter classes preds = list( map(lambda x: set(filter(lambda y: y in go_set, x)), preds)) fscore, prec, rec, s, ru, mi, fps, fns = evaluate_annotations( go_rels, labels, preds) avg_fp = sum(map(lambda x: len(x), fps)) / len(fps) avg_ic = sum( map(lambda x: sum(map(lambda go_id: go_rels.get_ic(go_id), x)), fps)) / len(fps) print(f'{avg_fp} {avg_ic}') precisions.append(prec) recalls.append(rec) print( f'Fscore: {fscore}, Precision: {prec}, Recall: {rec} S: {s}, RU: {ru}, MI: {mi} threshold: {threshold}' ) if fmax < fscore: fmax = fscore tmax = threshold if smin > s: smin = s print(f'Fmax: {fmax:0.3f}, Smin: {smin:0.3f}, threshold: {tmax}') precisions = np.array(precisions) recalls = np.array(recalls) sorted_index = np.argsort(recalls) recalls = recalls[sorted_index] precisions = precisions[sorted_index] aupr = np.trapz(precisions, recalls) print(f'AUPR: {aupr:0.3f}') plt.figure() lw = 2 plt.plot(recalls, precisions, color='darkorange', lw=lw, label=f'AUPR curve (area = {aupr:0.2f})') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('Recall') plt.ylabel('Precision') plt.title('Area Under the Precision-Recall curve') plt.legend(loc="lower right") plt.savefig(f'aupr_{ont}_{alpha:0.2f}.pdf') df = pd.DataFrame({'precisions': precisions, 'recalls': recalls}) df.to_pickle(f'PR_{ont}_{alpha:0.2f}.pkl')