-
Notifications
You must be signed in to change notification settings - Fork 0
/
ranking.py
106 lines (84 loc) · 3.53 KB
/
ranking.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pandas as pd
from distancia import jaccard_sim, simpson_corr, hamming_dist
def __split_data(poderes, features, hero_name):
""" Filtra do dataset poderes as features que será usada para calcular a similaridade.
Atributos
---------
poderes: pandas Dataframe
dataset contendo o nome dos herois e seus poderes
features: lista
features do dataset que usaremos como parametros para calcular a similaridade
hero_name: string
heroi que buscaremos o mais similar no dataset
Retornos
--------
hero_features: pandas Series
features do heroi que queremos encontrar o mais similar
poder_features: pandas Dataframe
features dos personagens que queremos comparar com o heroi
hero_names: pandas Series
nome de todos os herois exceto pelo hero_name
"""
features.append('hero_names')
poderes_features = poderes[features]
hero = poderes_features.loc[poderes_features['hero_names'] == hero_name]
if hero.shape[0] != 0:
hero_index = hero.index
hero_names = poderes_features.drop(hero_index)['hero_names']
poderes_features = poderes_features.drop('hero_names', axis=1)
hero_features = poderes_features.iloc[hero_index[0]]
poder_features = poderes_features.drop(hero_index).reset_index(drop=True)
else:
raise ValueError("heroi não existe no dataset")
return hero_features, poder_features, hero_names
def __similarity_method(metodo):
"""Retorna metodo que implementa a similaridade passada por parametro e o tipo de similaridade."""
if metodo == 'jaccard':
sim = jaccard_sim
rank = 'similaridade'
elif metodo == 'simpson':
sim = simpson_corr
rank = 'similaridade'
elif metodo == 'hamming':
sim = hamming_dist
rank = 'distancia'
else:
raise ValueError("Metodo não definido")
return sim, rank
def __sorting(hero_names, similaridades, rank):
"""Cria dataframe e ordena do mais similar para o menos."""
result = pd.DataFrame({"hero_names":hero_names, "similaridade": similaridades})
if rank == 'similaridade':
result.sort_values(by=['similaridade'], ascending=False, inplace=True)
else:
result.sort_values(by=['similaridade'], ascending=True, inplace=True)
return result
def ranking(poderes, features, hero_name, metodo='jaccard'):
''' Retorna os herois mais similares ao hero_name.
Atributos
---------
poderes: pandas Dataframe
dataset contendo o nome dos herois e seus poderes
features: lista
features do dataset que usaremos como parametros para calcular a similaridade
hero_name: string
heroi que buscaremos o mais similar no dataset
metodo: string
metodo de similaridade
Retornos
--------
result: pandas Dataframe
nome do heroi e sua respectiva similaridade em ordem do mais similar ao menos similar
'''
hero_features, poder_features, hero_names = __split_data(poderes, features, hero_name)
sim, rank = __similarity_method(metodo)
# calcula a similaridade de todos os personagens em relação ao hero_name
# cria uma lista com o resultado da similaridade
linhas = poder_features.shape[0]
similaridades = []
for i in range(linhas):
similaridades.append(sim(hero_features, poder_features.iloc[i]))
result = __sorting(hero_names, similaridades, rank)
return result