Skip to content

Commit

Permalink
dodalem metode k-srednich
Browse files Browse the repository at this point in the history
  • Loading branch information
Krzysztof Nowak committed May 20, 2012
1 parent e5969d7 commit 8353cb3
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 9 deletions.
112 changes: 106 additions & 6 deletions SWD.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from math import *

Expand All @@ -6,16 +7,19 @@

class Zbior:
def __init__(self):
self.lista = []
self.kolumny = []
self.typy = []
self.lista = [] # wektory wartosci
self.kolumny = [] # nazwy kolumn
self.typy = [] # typy zmiennych
pass
def dodaj_liste(self,lista):
self.lista += list(lista)
def dodaj_typy(self,typy):
self.typy += list(typy)
def dodaj_kolumny(self,kolumny):
self.kolumny += list(kolumny)
def rzutuj_dane(self):
for i in range(len(self.typy)):
self.rzutuj(self.typy[i],i)
def __repr__(self):
s = "Liczba zmiennych: "+str(len(self.lista[0]))+"\n"
s += "Liczba obserwacji: "+str(len(self.lista))+"\n"
Expand Down Expand Up @@ -297,6 +301,97 @@ def ocenaKlasyfikacji(self, k, metryka, klasa_decyzyjna, indeksy):

return [ile,len(self.lista)]

def _srednia(self, obiekty):
sr = [0]*len(obiekty[0])
for zm in range(len(obiekty[0])):
suma = 0
for i in obiekty:
suma += i[zm]
sr[zm] = float(suma)/len(obiekty)
return sr


def licz_k_srednich(self, k, metryka, klasa_decyzyjna, indeksy, N=None, dopasuj=True):
"""
Funkcja klasyfikujaca metoda k-srednich
metryka - metryka odleglosci
k - k klas
klasa_decyzyjna - indeks kolumny klasy decyzyjnej
indeksy - indeksy kolumn wartosci
N - ile razy iterowac jesli podane N,
jesli nie podane, iterowac az nie ma zmian pomiedzy klasami (max 500 iteracji)
"""
wartosci = []
klasy_prawdziwe = []
for wektor in self.lista:
wartosci.append([wektor[i] for i in indeksy])
klasy_prawdziwe.append(wektor[klasa_decyzyjna])
from random import sample
srednie = sample(wartosci,k)
klasy_tmp = [-1]*len(wartosci)

def iteruj(klasy_tmp, srednie):
for w in range(len(wartosci)):
min = [0,metryka(wartosci[w],srednie[0])]
for s_idx in range(len(srednie)):
dystans = metryka(srednie[s_idx],wartosci[w])
if dystans < min[1]:
min = [s_idx, dystans]
klasy_tmp[w] = min[0]
for i in range(k):
obiekty = [wartosci[w] for w in range(len(wartosci)) if klasy_tmp[w]==i]
srednie[i] = self._srednia(obiekty)

return [klasy_tmp, srednie]

if N:
for i in range(N):
klasy_tmp, srednie = iteruj(list(klasy_tmp), list(srednie))
else:
for i in range(500):
klasy_tmp_prev, srednie_prev = list(klasy_tmp), list(srednie)
klasy_tmp, srednie = iteruj(list(klasy_tmp), list(srednie))

if klasy_tmp == klasy_tmp_prev:
break

def poprawnie_sklasyfikowanych(mapping):
correct = 0.
for i in range(len(klasy_prawdziwe)):
if klasy_tmp[i] == mapping[klasy_prawdziwe[i]]:
correct+=1
return correct/len(klasy_prawdziwe)

if not dopasuj: #jesli nie dopasowujemy klas poczatkowych, zwracamy jedynie wynik i srednie
return [klasy_tmp, srednie]
else:
from itertools import permutations
klasy_prawdziwe_typy = list(set(klasy_prawdziwe))
if k == len(klasy_prawdziwe_typy):
best_klas = [-1.,range(k)]
for perm in permutations(range(k)):
mapping = dict((klasy_prawdziwe_typy[i], perm[i]) for i in range(k))
popr_val = poprawnie_sklasyfikowanych(mapping)
if popr_val > best_klas[0]:
best_klas = [popr_val, perm]

mapping = dict((klasy_prawdziwe_typy[i], best_klas[1][i]) for i in range(k))
mapping2 = dict((v,k) for k,v in mapping.items())
for w in range(len(self.lista)):
self.lista[w].append(mapping2[klasy_tmp[w]])
self.kolumny.append('Metoda %d-srednich'%(k))
self.typy.append(str)
return {'result':'OK', 'val':best_klas[0], 'perm': best_klas[1]}
else:
for w in range(len(self.lista)):
self.lista[w].append(klasy_tmp[w])
self.kolumny.append('Metoda %d-srednich'%(k))
self.typy.append(int)
return {'result':'NIE'}



def main():
z = Zbior()
z.wczytaj('dane2.txt', '\t', 0, 1,1)
Expand Down Expand Up @@ -341,8 +436,13 @@ def DBG_Mahalanobis():
print linalg.det(C)
#return sqrt( (X-Y)*C.I*(X-Y).T )

def DBG():
pass
def DBG_k_srednich():
z = Zbior()
z.wczytaj('dane/irisdat2.txt', '\t', 0, 1,1)
z.rzutuj_dane()
output = z.licz_k_srednich(3,z.metrykaEuklidesowa,4,[0,1,2,3], None)
if output['result'] == 'OK':
print output['val']
if(__name__ == "__main__"):
DBG()
DBG_k_srednich()

34 changes: 34 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,38 @@ def SklasyfikujObiekt(self, metryka):
self.zb.lista[item_index][int(klasa)] = wynik
self.populate_from_set()

def Metoda_K_Srednich(self):
N = None
k, ok = QtGui.QInputDialog.getText(self, 'K klas', 'Podaj k:')
if not ok:
return

klasa, ok = QtGui.QInputDialog.getText(self, 'Klasa decyzyjna', 'Podaj indeks klasy decyzyjnej:')
if not ok:
return

indeksy, ok = QtGui.QInputDialog.getText(self, 'Indeksy Zmiennych', 'Podaj indeksy kolumn oddzielone ",":')
if not ok:
return

indeksy = [int(i) for i in indeksy.split(',')]

N, ok = QtGui.QInputDialog.getText(self, 'Ilosc iteracji', 'Podaj ilosc iteracji, lub -1 jesli chcesz iterowac az nie bedzie zmian:')
if not ok:
return

N = int(N)

wynik = self.zb.licz_k_srednich(int(k), self.zb.metrykaEuklidesowa, int(klasa), indeksy, (N if N>0 else None))

if wynik['result'] == 'OK':
self.PopupMessage("Podsumowanie klasyfikacji", "Sklasyfikowano %.2f%% osobnikow poprawnie" %(wynik['val']*100))
else:
self.PopupMessage("Nie mozna podsumowac klasyfikacji", "Nie mozna bylo podsumowac klasyfikacji, k <> faktycznej ilosci klas")
self.populate_from_set()

def Metoda_K_Srednich_search(self):
pass #TODO
def __init__(self):
QtGui.QMainWindow.__init__(self)

Expand Down Expand Up @@ -403,6 +435,8 @@ def __init__(self):
self.ui.actionMetryk_Euklidesow_2.triggered.connect(self.KlasyfikujEuklidesowa)
self.ui.actionMetryk_Miejsk_2.triggered.connect(self.KlasyfikujMiejska)
self.ui.actionMetryk_Mahalanobisa_2.triggered.connect(self.KlasyfikujMahalanobisa)
self.ui.actionMetoda_K_Srednich.triggered.connect(self.Metoda_K_Srednich)
self.ui.actionMetoda_K_Srednich_optymalne_K.triggered.connect(self.Metoda_K_Srednich_search)

self.TypToS = TypToS
self.SToTyp = SToTyp
Expand Down
12 changes: 10 additions & 2 deletions window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Form implementation generated from reading ui file 'window.ui'
#
# Created: Wed Apr 11 12:45:51 2012
# Created: Mon May 21 00:27:51 2012
# by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!
Expand Down Expand Up @@ -80,7 +80,7 @@ def setupUi(self, MainWindow):
self.verticalLayout.addWidget(self.treeWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 765, 22))
self.menubar.setGeometry(QtCore.QRect(0, 0, 765, 25))
self.menubar.setObjectName(_fromUtf8("menubar"))
self.menuFile = QtGui.QMenu(self.menubar)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
Expand Down Expand Up @@ -154,6 +154,10 @@ def setupUi(self, MainWindow):
self.actionMetryk_Mahalanobisa_2.setObjectName(_fromUtf8("actionMetryk_Mahalanobisa_2"))
self.actionAAA = QtGui.QAction(MainWindow)
self.actionAAA.setObjectName(_fromUtf8("actionAAA"))
self.actionMetoda_K_Srednich = QtGui.QAction(MainWindow)
self.actionMetoda_K_Srednich.setObjectName(_fromUtf8("actionMetoda_K_Srednich"))
self.actionMetoda_K_Srednich_optymalne_K = QtGui.QAction(MainWindow)
self.actionMetoda_K_Srednich_optymalne_K.setObjectName(_fromUtf8("actionMetoda_K_Srednich_optymalne_K"))
self.menuFile.addAction(self.actionLoad)
self.menuFile.addAction(self.actionSave)
self.menuData.addAction(self.actionAdd_Row)
Expand All @@ -179,6 +183,8 @@ def setupUi(self, MainWindow):
self.menuSprawd_ocene_klasyfikacji.addAction(self.actionMetryk_Mahalanobisa)
self.menuKlasyfikacja.addAction(self.menuSklasyfikuj_obiekt.menuAction())
self.menuKlasyfikacja.addAction(self.menuSprawd_ocene_klasyfikacji.menuAction())
self.menuKlasyfikacja.addAction(self.actionMetoda_K_Srednich)
self.menuKlasyfikacja.addAction(self.actionMetoda_K_Srednich_optymalne_K)
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuData.menuAction())
self.menubar.addAction(self.menuStat.menuAction())
Expand Down Expand Up @@ -226,4 +232,6 @@ def retranslateUi(self, MainWindow):
self.actionMetryk_Miejsk_2.setText(QtGui.QApplication.translate("MainWindow", "Metryką Miejską", None, QtGui.QApplication.UnicodeUTF8))
self.actionMetryk_Mahalanobisa_2.setText(QtGui.QApplication.translate("MainWindow", "Metryką Mahalanobisa", None, QtGui.QApplication.UnicodeUTF8))
self.actionAAA.setText(QtGui.QApplication.translate("MainWindow", "AAA", None, QtGui.QApplication.UnicodeUTF8))
self.actionMetoda_K_Srednich.setText(QtGui.QApplication.translate("MainWindow", "Metoda K-Srednich", None, QtGui.QApplication.UnicodeUTF8))
self.actionMetoda_K_Srednich_optymalne_K.setText(QtGui.QApplication.translate("MainWindow", "Metoda K-Srednich - optymalne K", None, QtGui.QApplication.UnicodeUTF8))

14 changes: 13 additions & 1 deletion window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
<x>0</x>
<y>0</y>
<width>765</width>
<height>22</height>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
Expand Down Expand Up @@ -222,6 +222,8 @@
</widget>
<addaction name="menuSklasyfikuj_obiekt"/>
<addaction name="menuSprawd_ocene_klasyfikacji"/>
<addaction name="actionMetoda_K_Srednich"/>
<addaction name="actionMetoda_K_Srednich_optymalne_K"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuData"/>
Expand Down Expand Up @@ -355,6 +357,16 @@
<string>AAA</string>
</property>
</action>
<action name="actionMetoda_K_Srednich">
<property name="text">
<string>Metoda K-Srednich</string>
</property>
</action>
<action name="actionMetoda_K_Srednich_optymalne_K">
<property name="text">
<string>Metoda K-Srednich - optymalne K</string>
</property>
</action>
</widget>
<resources/>
<connections/>
Expand Down

0 comments on commit 8353cb3

Please sign in to comment.