source: orange/Orange/OrangeWidgets/Unsupervised/OWPubmedView.py @ 10720:9bea02180ee9

Revision 10720:9bea02180ee9, 10.7 KB checked in by mstajdohar, 2 years ago (diff)

Moved to Unsupervised.

Line 
1"""
2<name>Pubmed Network View</name>
3<description></description>
4<icon>icons/Network.png</icon>
5<contact></contact> 
6<priority>6450</priority>
7"""
8
9import Orange
10import OWGUI
11
12from OWWidget import *
13
14class PubmedNetworkView(Orange.network.NxView):
15    """Network Inside View
16   
17    """
18   
19    def __init__(self, parent):
20        Orange.network.NxView.__init__(self)
21       
22        self._nhops = 2
23        self._edge_threshold = 0.5
24        self._algorithm = 0 # 0 without clustering, 1 with clustering
25        self._n_max_neighbors = 10
26        self._center_nodes = []
27        self.parent = parent
28        self._hidden_nodes = []
29        self._k_algorithm = 0.3
30        self._delta_score = {}
31       
32    def init_network(self, graph):
33        self._network = graph
34       
35        if hasattr(self.parent, 'init_network'):
36            self.parent.init_network()
37
38        if graph is None:
39            return None
40                     
41        return graph
42       
43   
44    def update_network(self):   
45        if self._center_nodes == []:
46            return
47       
48        subnet = Orange.network.Graph()
49        central_nodes, to_add = self._center_nodes[:], self._center_nodes[:]
50        for l in range(self._nhops):
51            for i in central_nodes:
52                neig = sorted([x for x in self._network.neighbors(i) if self._network.edge[i][x]['weight'] > self._edge_threshold], reverse=True)
53                if len(neig) > self._n_max_neighbors:
54                    neig = neig[:self._n_max_neighbors]
55                to_add.extend(neig)
56            central_nodes = neig
57        to_add = list(set(to_add))
58        subnet.add_nodes_from([(x, self._network.node[x]) for x in to_add])
59        nodes = subnet.nodes()
60        while nodes:
61            i = nodes.pop()
62            subnet.node[i] = self._network.node[i]
63            neig = [x for x in self._network.neighbors(i) if x in nodes] 
64            subnet.add_weighted_edges_from([(i,x,w) for x,w in zip(neig, [self._network.edge[i][y]['weight'] for y in neig])])
65       
66        subnet.remove_nodes_from(self._hidden_nodes)
67        subnet = self._propagate(subnet)
68       
69        if self._nx_explorer is not None:
70            self._nx_explorer.change_graph(subnet)       
71       
72    def set_nhops(self, nhops):
73        self._nhops = nhops 
74       
75    def set_edge_threshold(self, edge_threshold):
76        self._edge_threshold = edge_threshold
77
78    def set_algorithm(self, algorithm):
79        self._algorithm = algorithm
80       
81    def set_n_max_neighbors(self, n_max_neighbors):
82        self._n_max_neighbors = n_max_neighbors
83       
84    def set_center_nodes(self, c_nodes):
85        self._center_nodes = c_nodes
86       
87    def set_k(self, k):
88        self._k_algorithm = k
89   
90    def node_selection_changed(self):
91        pass
92   
93    def set_user_node_score(self, node_index, new_score):
94        self._delta_score[node_index] = new_score - self._network.node[node_index]['score']
95        self._network.node[node_index]['score'] = new_score
96        self._network.node[node_index]['user_score'] = 1
97   
98    def update_center_nodes(self, new_node):
99        self._center_nodes.append(new_node) 
100       
101    def _get_neighbors(self):
102    #TO DELETE?
103        nodes = set([self._center_node])
104        for n in range(self._nhops):
105            neighbors = set()
106            for node in nodes:
107                neighbors.update(self._network.neighbors(node))
108            nodes.update(neighbors)
109        return nodes
110       
111    def _propagate(self, net):
112        central_nodes = [i for i in net.nodes() if net.node[i]['user_score'] == 1]
113        central_delta_score = [self._delta_score[id] for id in central_nodes]
114        cluster_centers = [net.node[x]['cluster'] for x in central_nodes if net.node[x]['cluster'] != '']
115        updated = central_nodes[:]
116        L = 0
117        while True:
118            to_update = []
119            for i in central_nodes:
120                to_update.extend(net.neighbors(i))
121            to_update = set(to_update) - set(updated)
122            if to_update:
123                for i in to_update:
124                    if not net.node[i]['user_score']:
125                        predec = [j for j in net.neighbors(i) if j in central_nodes]
126                        predec_delta_score = [central_delta_score[central_nodes.index(x)] for x in predec]
127                        self._k_algortihm = self.compute_k(i, cluster_centers, net)
128                        if self._k_algortihm: #else the node is isolated and the score doesn't change
129                            net.node[i]['score'] = _prop(predec, predec_delta_score, i, L, net)
130                        net.node[i]['level'] = L
131                updated.extend(to_update)
132                central_nodes = list(to_update)
133                central_delta_score = []
134                for id in central_nodes:
135                    if self._delta_score.get(id, []):
136                        central_delta_score.append(self._delta_score[id])
137                    else:
138                        central_delta_score.append(net.node[id]['score'] - 0.5)
139                L += 1
140            else:
141                return net
142               
143    def compute_k(self, id, centers, net):
144        import networkx as nx #VEDERE SE C'E' IN ORANGENET
145        if self._algorithm == 0: #no clustering
146            return self._algorithm
147        else:   #clustering
148            paths = []
149            for c in centers:
150                try:
151                    paths.append(nx.algorithms.shortest_paths.generic.shortest_path_length(net, id, c))
152                except nx.exception.NetworkXNoPath:
153                    return None #isolated node
154                   
155            return float(min(paths))/10
156           
157               
158    def _prop(self, predec, predec_delta_score, node, L, net): 
159        edges_weight = [net[i][node]['weight'] for i in predecessors]
160        x = [(delta * w + 0.5)/(1 + level*self._k_algorithm) for delta, w in zip(predec_delta_score, edges_weight)]   
161        return max(x)   
162       
163       
164class OWPubmedView(OWWidget):
165   
166    settingsList = ['_nhops']
167   
168    def __init__(self, parent=None, signalManager=None):
169        OWWidget.__init__(self, parent, signalManager, 'Pubmed Network View', wantMainArea=0)
170       
171        self.inputs = []
172        self.outputs = [("Nx View", Orange.network.NxView)]
173       
174        self._nhops = 2
175        self._edge_threshold = 0.5
176        self._n_max_neighbors = 20
177        self.selected_titles = []
178        self.titles = []
179        self.filter = ''
180        self.ids = []
181        self._selected_nodes = []
182        self._algorithm = 0
183        self._k_algorithm = 0.3
184       
185        self.loadSettings()
186       
187        box = OWGUI.widgetBox(self.controlArea, "Paper Selection", orientation="vertical")
188        OWGUI.lineEdit(box, self, "filter", callback=self.filter_list, callbackOnType=True)
189        self.list_titles = OWGUI.listBox(box, self, "selected_titles", "titles", selectionMode=QListWidget.MultiSelection, callback=self.update_view)
190        OWGUI.separator(self.controlArea)
191        box_pref = OWGUI.widgetBox(self.controlArea, "Preferences", orientation="vertical")
192        OWGUI.spin(box_pref, self, "_nhops", 1, 6, 1, label="Number of hops: ", callback=self.update_view)
193        OWGUI.spin(box_pref, self, "_n_max_neighbors", 1, 100, 1, label="Max number of neighbors: ", callback=self.update_view)
194        OWGUI.doubleSpin(box_pref, self, "_edge_threshold", 0, 1, step=0.01, label="Edge threshold: ", callback=self.update_view)
195        OWGUI.separator(self.controlArea)
196        box_alg = OWGUI.widgetBox(self.controlArea, "Interest Propagation Algorithm", orientation="vertical")
197        radio_box = OWGUI.radioButtonsInBox(box_alg, self, "_algorithm", [], callback=self.update_view)
198        OWGUI.appendRadioButton(radio_box, self, "_algorithm", "Without Clustering", callback=self.update_view)
199        OWGUI.doubleSpin(OWGUI.indentedBox(radio_box), self, "_k_algorithm", 0, 1, step=0.01, label="Parameter k: ", callback=self.update_view)
200        OWGUI.appendRadioButton(radio_box, self, "_algorithm", "With Clustering", callback=self.update_view)
201       
202        self.inside_view = PubmedNetworkView(self)
203        self.send("Nx View", self.inside_view)
204 
205       
206    def init_network(self):
207        if self.inside_view._network is None:
208            return
209       
210        self.titles = [self.inside_view._network.node[node]['title'] for node in self.inside_view._network.nodes()]
211        self.ids = self.inside_view._network.nodes()
212       
213        QObject.connect(self.inside_view._nx_explorer.networkCanvas, SIGNAL('point_rightclicked(Point*)'), self.node_menu_show)
214       
215       
216    def update_view(self):
217        self.inside_view.set_nhops(self._nhops)
218        self.inside_view.set_edge_threshold(self._edge_threshold)
219        self.inside_view.set_n_max_neighbors(self._n_max_neighbors)
220        self.inside_view.set_algorithm(self._algorithm)
221        self.inside_view.set_k(self._k_algorithm)
222        self._selected_nodes = [self.ids[row] for row in self.selected_titles]
223        self.inside_view.set_center_nodes(self._selected_nodes)
224        self.inside_view.update_network()
225       
226       
227    def filter_list(self):
228        """Given a query for similar titles sets titles and ids"""
229       
230        str_input = self.filter
231        str_input = str_input.strip(' .').lower().split(' ')
232        titles2 = [(n, str.lower(self.inside_view._network.node[n]['title'].encode('utf-8').strip(' .')).split(' ')) for n in self.inside_view._network.nodes()] # [(id,title)]
233        titles2 = sorted(titles2, key = lambda x: sum(i in str_input for i in x[1]), reverse=True)
234        self.titles = [self.inside_view._network.node[x[0]]['title'] for x in titles2]
235        self.ids = [x[0] for x in titles2]
236       
237    def node_menu_show(self, node):
238        menu = QMenu(self)
239        menu.addAction('Expand Node')
240        menu.addAction('Hide Node')
241        qstr = QString('Set Score')
242        submenu = menu.addMenu(qstr)
243        submenu.addAction('0')
244        submenu.addAction('0.2')
245        submenu.addAction('0.5')
246        submenu.addAction('0.7')
247        submenu.addAction('1')
248        self.connect(menu, SIGNAL("triggered(QAction*)"), lambda action, node=node: self.node_menu_triggered(action, node))
249        menu.popup(QCursor.pos())
250 
251    def node_menu_triggered(self, action, node):       
252        # delete_node_and_neig --> ????       
253        if action.text() == 'Expand Node':
254            self.inside_view.update_center_nodes(node.index())
255           
256        elif action.text() == 'Hide Node':
257            self.inside_view._hidden_nodes.append(node.index())
258       
259        else:     
260            self.inside_view.set_user_node_score(node.index(), float(action.text()))
261       
262        self.inside_view.update_network()  #chiama propagate
263       
264           
265
266   
267     
Note: See TracBrowser for help on using the repository browser.