示例#1
0
    def ratePartition(self):
        """ 
        Metoda do oceny podziału sieci. Porównuje podział wykonany z wzrocowym i wyznacza procentową skuteczność podziału.
        
        @return:  
        """
        result = 0
        maximal_result = 0
        
        
        for index, node in enumerate(self.graph.nodes()):
            for groupNo in self.partition:
                if node in groupNo:
                    nodeComputedGroup = self.partition.index(groupNo)
            for groupNo in handPartition:
                if node in groupNo:
                    nodeOriginalGroup = handPartition.index(groupNo)
                    
            for secondNode in self.graph.nodes()[index+1:]:
                for groupNo in self.partition:
                    if secondNode in groupNo:
                        secondNodeComputedGroup = self.partition.index(groupNo)
                for groupNo in handPartition:
                    if secondNode in groupNo:
                        secondNodeOriginalGroup = handPartition.index(groupNo)
                
                if nodeOriginalGroup == secondNodeOriginalGroup:
                    maximal_result += 1
                if (nodeOriginalGroup == secondNodeOriginalGroup) and (nodeComputedGroup == secondNodeComputedGroup):
                    result += 1

        ret = float(result)/maximal_result * 100.0
        logger.info("# Jakość grupowania FB: " + str(ret) + "%")  
        return ret
示例#2
0
def karateClub():
    """
    Funkcja uruchamia różne algorytmy grupowania na sieci klubu karate
    
    @return: W systemie plików zapisywane są obrazy PNG z wynikami grupowań
    """
    
    karateG = karate_graph.karate_graph()
    cq = sna.Cliquer(karateG)
    
    logger.info("# Karate Graph... ")
    partition = cq.blondelAlgorithm()
    cq.prettyPlotter(l=partition, filename="karate_blondel.png")
    
    partition = cq.newmanAlgorithm()
    cq.prettyPlotter(l=partition, filename="karate_newman.png")
    
    
    partition = cq.causetNewmanAlgorithm()
    cq.prettyPlotter(l=partition, filename="karate_causet_newman.png")
    
    partition = cq.MCLAlgorithm(2.0)
    cq.prettyPlotter(l=partition, filename="karate_MCL.png")
    
    logger.info("# Karate Graph wykonano")
示例#3
0
    def rateQuality(self, hardGroupsNo = 0):
        '''
        Wyznacza wskaźniki jakości działania metody autorskiej

        @type hardGroupsNo: number
        @param hardGroupsNo: liczba kolejnych (od najmniej licznej) grup, których członkowie będą uznani za podjerzanych
        
        @rtype: tuple
        @return: Krotka matchRate i popRate
        '''
        if hardGroupsNo:
            self.selectGroups = [hardGroupsNo]
        for i in self.selectGroups: # pobierz pierwszych i grup
            matchCount = 0
            # suspects = self.cq.smartGetFristNGroups(self.result, i)
            suspects = self.cq.getSuspectedGroups(self.result, i)
            
            logger.debug("# Podejrzani: ")
            logger.debug("# " + str(suspects))
            
            for v in self.rings:
                if int(v) in suspects:
                    matchCount += 1
            
            matchRate = matchCount/len(self.rings) * 100.0
            popRate = len(suspects)/self.vertexNo * 100.0
            suspectsRate = matchCount/len(suspects) * 100.0
            
            logger.info("%d ; %f ; %f" % (i, matchRate, popRate)) # liczba grup, procent wykrytych, procent podejrzewanje populacji
        
        return (matchRate, popRate, suspectsRate)
示例#4
0
 def nativeCliquer(self):
     """
     Wykorzystuje metodę znajdowania klik z biblioteki NetworkX. 
     
     Metoda ta nie wykorzystuje algorytmów grupowania, wyznacza jedynie k-kliki. Nie jest to właściwe podejście do problemu.
     """
     cliques = list(nx.find_cliques(self.graph))
     logger.info("Kliki wyznaczone:")
     import pprint
     pprint.pprint(cliques)
示例#5
0
 def __init__(self, testingDataPath = "/tmp/testing-ring.txt"):
     """
     Konstruktor
     @param testingDataPath: ścieżka do pliku z testowymi danymi o głosowaniu
     @type testingDataPath: text
     """
     logger.info("################### WYZNACZANIE KLIK ZLOSLIWYCH GLOSUJACYCH ######################")
     self.testingDataPath = testingDataPath
     self.dm = sna.DataMaker(self.testingDataPath)
     self.gm = sna.GraphMaker(self.testingDataPath)
示例#6
0
 def loadGraph(self, filename = 'fb.gpickle'):
     """
     Ładuje sieć do pamięci z pliku typu python pickle.
     @param filename: nazwa pliku  
     """
     self.graph = nx.read_gpickle(filename)
     # anonimizacja grafu, każdemu węzłowi przypisywany jest numer
     i = 1
     for node in self.graph:
         self.labels[node] = i
         i += 1 
     logger.info("########################## FACEBOOK EXPERIMENT ########################")
     logger.debug("Sieć załadowana, krawędzi: %d, węzłów: %d" % (self.graph.number_of_edges(), self.graph.number_of_nodes()))
示例#7
0
    def partitionGraph(self, filename = "fb_partition.png", method = 'blondelAlgorithm'):
        from thesis.sna import Cliquer
        
        cq = Cliquer(self.graph)
        function = getattr(cq, method)
        self.partition = function()
        
        # write down partition
        
        for cluster in self.partition:
            members = ""
            for member in cluster:
                members += str(self.labels[member]) + " "
            logger.info(str(self.partition.index(cluster)) + ", " + members)
        
        # partition done, making colors
        # making graph
        
        nodeList = self.partition
        colorList = [0] * self.graph.number_of_nodes()

        for nbunch in nodeList:
            for n in nbunch:
                colorList[self.graph.nodes().index(n)] = nodeList.index(nbunch)

        import matplotlib.pyplot as plt
        
        # stupid hack becouse of pygraphviz utf-8 malfunction
        graph_copy = nx.Graph();
        graph_copy.add_nodes_from(self.graph.nodes())
        graph_copy.add_edges_from(self.graph.edges())
        # end stupid hack
        
        
        pos=nx.pygraphviz_layout(graph_copy,prog='neato')
        for i in pos:
            pos[i] = (pos[i][0]*3, pos[i][1]*3)
        
        
        plt.figure(figsize=(20,20))
        plt.axis('off')
        nx.draw_networkx_edges(self.graph,pos,alpha=0.2)
        nx.draw_networkx_nodes(self.graph, pos, size = 4, node_color=colorList, with_labels=False)
        nx.draw_networkx_labels(self.graph, pos, font_size = 10, labels = self.labels)
        
        import config
        filename = config.PLOT_OUT_DIR+filename
        plt.savefig(filename)
示例#8
0
    def plotTuple(self, tuple, caption = "This is experiment", xlabel = "This is x label", ylabel = "This is y label", file_title = "chart", xaxis = [], step = 1):
        """
        Metoda rysuje wykres ilustrujący eksperyment
        
        @param tuple: krotka z wynikami
        @param caption: tytuł wykresu
        @param xlabel: tytuł osi poziomej
        @param ylabel: tytuł osi pionowej
        @param file_title: nazwa pliku
        
        @return: W systemie plików pojawia się plik w formacie eps będący zadanym wykresem
        """
        if not xaxis:
            from numpy import arange
            xaxis = arange(0,len(tuple[0]),1)

        logger.info("############# Rysowanie wykresu ################")
        logger.info("# " + str(tuple))
        
        import Gnuplot
        g = Gnuplot.Gnuplot()
        suspects = Gnuplot.Data(xaxis, tuple[0], title ='procent wykrytych zlosliwych glosujacych', with_="points lt 1 lw 6 lc 1")
        population = Gnuplot.Data(xaxis, tuple[1], title='podejrzany procent populacji', with_="points lt 4 lw 6 lc 3")
        suspectsR = Gnuplot.Data(xaxis, tuple[2], title='procent zlosliwych glosujacych wsrod podejrzanych', with_="points lt 2 lw 6 lc 4")
        near100 = Gnuplot.Data(xaxis, tuple[3], title='procent wykryc powyzej 90%', with_="points lt 3 lw 6 lc 6")
        
        
        g.title(caption)
        g.xlabel(xlabel)
        g.ylabel(ylabel)
        g('set xtics ' + repr(step))
        g('set grid')
        g('set size 1.3,1.3')
        
        maxs = []
        maxs.append(max(tuple[0]))
        maxs.append(max(tuple[1]))
        maxs.append(max(tuple[2]))
        maxs.append(max(tuple[3]))
        max_y = max(maxs)
        
        g('set yrange [ 0 : ' + repr(max_y+10) + ' ]')
        g.plot(suspects, population, suspectsR, near100)
        #g.plot(suspects, population, suspectsR)
        import config
        file_title = config.PLOT_OUT_DIR+file_title
        g.hardcopy(file_title + '.eps', eps=True)
示例#9
0
def fbExperiment():
    """
    Uruchomienie eksperymentów na danych z platformy facebook. Zakłada, że sieć znajduje się w pliku fb.gpickle. 
    """
    fb = Facebooker()
    fb.loadGraph()
    fb.partitionGraph()
    fb.ratePartition()
    fb.computeMeasures()
    fb.loadMeasures()
    fb.graphMeasure('clustering', True)
    fb.graphMeasure('betweeness', True)
    fb.graphMeasure('degree', True)
    fb.graphMeasure('closeness', True)
    fb.graphMeasure('eigenvector', True)
    from thesis import logger   
    logger.info("# Średni wsp. gronowania: " + str(fb.centrality['avg_clustering'])) 
    logger.info("# Średnia najkrótsza ścieżka: " + str(fb.centrality['avg_shortest_path'] ))
示例#10
0
 def iterateParam(self, minValue = 10, maxValue = 25, step = 5, param = "target_size", hardGroupsNo = 2, runsNo = 100):
     '''
     Służy do przeprowadzania eksperytmentu polegającego na ocenie jakości działania metody przy zmieniającym się jednym parametrze generatora. 
     
     Podawana jest nazwa parametru, wartości minimalna i maksymalna oraz krok, z jakim zmieniania jest wartość. 
     
     @param minValue: wartość startowa parametru
     @param maxValue: wartośc końcowa
     @param step: krok
     @param param: nazwa parametru
     @param hardGroupsNo: liczba grup
     @param runsNo: liczba uruchomień
     
     @rtype: tuple
     @return Krotka zwierające krotkę z wynikami oraz listę argumentów, w celu rysowania wykresów
     '''
     
     oldDictValue = self.paramsDict[param]
     self.paramsDict[param] = minValue
     
     matchRates = []
     popRates = []
     suspectRates = []
     near100Rates = []
     xaxis = []
     
     
     while self.paramsDict[param] <= maxValue:
         logger.info("# Będzie zmieniany parametr %s : teraz wynosi %d:" % (param, self.paramsDict[param]))
         tuple = self.compute(hardGroupsNo = hardGroupsNo, runsNo = runsNo)
         xaxis.append(self.paramsDict[param]) 
         self.paramsDict[param] += step
         
         if hardGroupsNo:
             matchRates.append(tuple[0])
             popRates.append(tuple[1])
             suspectRates.append(tuple[2])
             near100Rates.append(tuple[3])
         
     
     self.paramsDict[param] = oldDictValue
     
     if hardGroupsNo:
         return ((matchRates, popRates, suspectRates, near100Rates), xaxis)
示例#11
0
 def makeGraph(self):
     """
     Tworzy sieć według autorskiej metody wczytując dane o głosowaniu z pliku.
     
     @rtype: networkx.Graph
     @return: Wczytana sieć.
     """
     if self.file_type == FileType.VOTING_RING:
         i = 0
         voters = []
         with open(self.path) as file:
             for line in file:
                 if not i % 2 == 0: # voters line
                     voters = [int(v) for v in line.split()]
                     # voting for same item increases edge weight between all of voters by 1
                     self.graph.add_nodes_from(voters)
                     self.addEdges(voters)
                 
                 i += 1
         
         logger.info("# Sieć załadowana, węzłów: "  + repr(self.graph.number_of_nodes()) + ", krawędzi: " + repr(self.graph.number_of_edges()))
         return self.graph
示例#12
0
    def graphMeasure(self, measure = 'degree', anonymized_log = True):
        """
        Metoda twrzy rysunek grafu reprezentującego sieć kolorując węzły odpowiednio do charakteryzującej je miary centralnośći. 
        
        @param measure: nazwa miary centralności, której wartość bęðzie wykorzystana przy kolorowaniu węzłów
        @type anonymized_log: boolean
        @param anonymized_log: włączenie anonimizacji danych zapisywanch w pliku dziennika (numery zamiast pełnego imienia i nazwiska)
        """
        measureValues = self.centrality[measure]
        
        
        filename = measure + ".png"
        
        # print sorted node list on INFO
        nodesDict = dict()
        for node, data in self.graph.nodes_iter(data=True):
            nodesDict[node] = measureValues[node]
        sortedNodes = sorted(nodesDict, key=nodesDict.get, reverse = True)
        
        logger.info("******########*******" + measure + "******########*******")
        for node in sortedNodes:
            if not anonymized_log:
                logger.info(self.graph.node[node]['name'] +" (" + str(self.labels[node]) + "): " + str(nodesDict[node])) # z nazwiskami osob
            else:
                logger.info(str(self.labels[node]) + ": " + str(nodesDict[node])) # same numery
            # set my value to 0 for better colors
            if self.graph.node[node]['name'] == 'Marcin Mincer':
                measureValues[node] = 0
        
        

        # stupid hack becouse of pygraphviz utf-8 malfunction
        graph_copy = nx.Graph();
        graph_copy.add_nodes_from(self.graph.nodes())
        graph_copy.add_edges_from(self.graph.edges())
        # end stupid hack
        
        pos=nx.pygraphviz_layout(graph_copy,prog='neato')
        for i in pos:
            pos[i] = (pos[i][0]*3, pos[i][1]*3)
        
        import matplotlib.pyplot as plt
        

        
        plt.figure(figsize=(20,20))
        plt.axis('off')
        nx.draw_networkx_edges(self.graph,pos,alpha=0.2)
        nx.draw_networkx_nodes(self.graph, pos, size = 4, with_labels=False, node_color=measureValues.values(), cmap=plt.cm.get_cmap('Spectral'))
        nx.draw_networkx_labels(self.graph, pos, font_size = 10, labels = self.labels)
        plt.colorbar(orientation="horizontal", fraction = 0.04, pad = 0.01, aspect = 16)
        import config
        filename = config.PLOT_OUT_DIR+filename
        plt.savefig(filename)
示例#13
0
def sixtyOne(sliceLevels = [3]):
    """
    Funkcja uruchamia autorską metodą na danych ze strony thesixtyone.com
    @param sliceLevels: lista poziomów odcięcia, z jakimi ma być uruchomiony algorytm
    @return: Obraz PNG w systemie plików, lista podejrzanych w pliku dziennika
    """
    import config
    gm = sna.GraphMaker(config.SIXTYONE_SOURCE_FILE)
    gm.makeGraph()
    
    
    for sliceLevel in sliceLevels:
        cq = sna.Cliquer(gm.graph)
        nodesNo = cq.graph.number_of_nodes()
        cq.sliceGraph(sliceLevel)
        
        partition = cq.blondelAlgorithm()
        suspects = cq.smartGetFristNGroups(partition, 2)
        suspects_no = len(suspects)
        
        logger.info("############### EKSPERYMENT THESIXTYONE  ##################")
        logger.info("# O przynależność do kliki jest podejrzanch %d użytkowników, co stanowi  %f procent całej populacji." % (suspects_no, (suspects_no / nodesNo ) * 100.0) )
        logger.info("# Identyfikatory podjerzanych użytkowników: ")
        logger.info(suspects)
示例#14
0
    def compute(self, hardGroupsNo = 0, runsNo = 1):
        '''
        Metoda wykonuje określoną w L{runsNo} liczbę uruchomień algorytmu, zwaraca średnią arytmetyczną wskaźników jakości. 

        @type hardGroupsNo: number
        @param hardGroupsNo: liczba grup (począwszy od najmniej licznej), których członkowie są uważania za podjerzanych
        @rtype: tuple
        @return: Zwraca krotkę (matchRate, popRate, suspectsRate, near100rate), która zwiera średnią arytmetyczną z wartości wyznaczonych przez metodę L{rateQuality}.  
        '''
        
        
        logger.info("# Parametry generatora")
        logger.info("# " + str(self.paramsDict))
        logger.info("# Liczba prób: %d" % runsNo )
        

        
        logger.info("# Poziom odcięcia: %d" % self.paramsDict['slice_level'])
        matchRate = 0.0
        matchRateList = []
        popRate = 0.0
        suspectsRate = 0.0
        
        
        near100Rate = 0.0 
  
        for run in xrange(runsNo):
            self.dm.generate(**self.paramsDict)
            self.graph = self.gm.makeGraph()
            self.rings = sum(self.dm.voting_rings, []) # H-H-HHACKISH spłaszczenie listy list
            self.vertexNo = len(self.graph)

            self.cq = sna.Cliquer(self.graph)
            self.cq.sliceGraph(self.paramsDict['slice_level'])
            self.result = self.cq.blondelAlgorithm()
            
            tuple = self.rateQuality(hardGroupsNo)
            
            matchRate += tuple[0]
            matchRateList.append(tuple[0])
            popRate += tuple[1]
            suspectsRate += tuple[2] 
             
            # czwarty wskaźnik jakości
            if tuple[0] > 90:
                near100Rate += 1
            logger.debug(near100Rate)

        matchRateAvg = float(matchRate/float(runsNo))
        
        # obliczenie wariancji matchRate
        matchRateList = map(lambda rate: (rate - matchRateAvg)**2, matchRateList)
        matchRateVariance = 1.0/runsNo * sum(matchRateList) 
                    
        
        # wyznaczanie średnich arytmetycznych
        tuple = (float(matchRate/float(runsNo)), float(popRate / float(runsNo)), float(suspectsRate / float(runsNo)), float(near100Rate / float(runsNo))*100.0)
        logger.info("# Po  %d uruchomieniach (procent wykrytych; procent populacji podjerzewany; procent faktycznych wśród podejrzewanych; procent podejść, gdzie wykryto powyżej 90 procent" % runsNo)
        logger.info(tuple)
        logger.info("# Dla parametrów generatora: ")
        logger.info(self.paramsDict)
        logger.info("# Wariancja porcentu wykrytych")
        logger.info(matchRateVariance)
        logger.info("# ------------------- KONIEC --------------------")
    
        return tuple