Sveučilište u Zagrebu
Fakultet elektrotehnike i računarstva
(c) 2015-2016 Domagoj Alagić
Verzija: 0.1
Zadnji put ažurirano: 7. listopada 2016.
import numpy as np
import scipy as sp
from scipy import stats
import matplotlib.pyplot as plt
from sklearn import datasets
%pylab inline
Populating the interactive namespace from numpy and matplotlib
(a) Kreirajte dvije liste: $a = [2, 4, 5, 6, 8, 13]$ i $b = [1, 3, 10, 13, 15]$.
a = [2, 4, 5, 6, 8, 13]
b = [1, 3, 10, 13, 15]
print a, b
[2, 4, 5, 6, 8, 13] [1, 3, 10, 13, 15]
(b) Napišite kôd koji konkatenira liste $a$ i $b$ u listu $c$:
c = a + b
print c
[2, 4, 5, 6, 8, 13, 1, 3, 10, 13, 15]
(c) Sortirajte listu $c$:
c = sorted(c)
print c
[1, 2, 3, 4, 5, 6, 8, 10, 13, 13, 15]
(d) Izbacite duplikate iz liste c:
c = list(set(c))
print c
[1, 2, 3, 4, 5, 6, 8, 10, 13, 15]
(e) Dohvatite i ispišite (pazite na indeksiranje od 0):
print c[2]
print c[-2:]
print c[2:5]
3 [13, 15] [3, 4, 5]
(f) Generirajte interval brojeva ran
s elementima iz $[2, 20]$.
ran = range(2, 21)
print ran
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
(g) Ispišite sve generirane brojeve iz intervala skupa s njihovim indeksima u listi:
for ind, val in enumerate(ran):
print ind, val
0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 11 10 12 11 13 12 14 13 15 14 16 15 17 16 18 17 19 18 20
(h) Korištenjem sažetog zapisa liste (engl. list comprehension) transformirajte listu ran
tako da sve elemente zamijenite njihovim prirodnim logaritmom.
ran_ln = [np.log(elem) for elem in ran]
print ran_ln
[0.69314718055994529, 1.0986122886681098, 1.3862943611198906, 1.6094379124341003, 1.791759469228055, 1.9459101490553132, 2.0794415416798357, 2.1972245773362196, 2.3025850929940459, 2.3978952727983707, 2.4849066497880004, 2.5649493574615367, 2.6390573296152584, 2.7080502011022101, 2.7725887222397811, 2.8332133440562162, 2.8903717578961645, 2.9444389791664403, 2.9957322735539909]
(a) Napišite funkciju make_3sg_form(word)
koja vraća glagol u trećem licu jednine za dani glagol u infinitivu, npr. try -> tries. Slijedite sljedeća pravila:
NB: Znakovni niz je zapravo polje znakova tako da vrijede "trikovi" za indeksiranje polja.
(b) Isprobajte implementiranu funkciju za fix, brush, cry, play i echo. Primjetite da je ovo složen problem i da tri jednostavna pravila neće uspjeti pokriti sve slučajeve.
def make_3sg_form(word):
ret_word = word
if ret_word.endswith("y"):
ret_word = ret_word[0:-1] + "ies"
elif ret_word.endswith("o") or ret_word.endswith("x") or ret_word.endswith("s") or \
ret_word.endswith("ch") or ret_word.endswith("sh"):
ret_word += "es"
else:
ret_word += "s"
return ret_word
print "fix", "->", make_3sg_form("fix")
print "brush", "->", make_3sg_form("brush")
print "jump", "->", make_3sg_form("jump")
print "cry", "->", make_3sg_form("cry")
print "echo", "->", make_3sg_form("echo")
fix -> fixes brush -> brushes jump -> jumps cry -> cries echo -> echoes
Napišite funkciju filterShortWords (word_list, min_length)
koja prima listu riječi i minimalnu dopuštenu duljinu riječi te vraća novu listu riječi koja sadrži samo one riječi čija je duljina veća od minimalne dopuštene. Obavezno provjerite da je dana duljina riječi pozitivan broj veći od 1. Ako nije, bacite iznimku. U slučaju da korisnik nije zadao duljinu, funkcija radi jednako kao da je korisnik zadao duljinu od dva znaka (koristite podrazumijevane argumente, engl. default arguments).
Zadatak riješite na dva načina:
for
petlji,filter
u kombinaciji s lambda-izrazom.(d) Pokažite na primjeru da su izlazi implementiranih funkcija jednaki.
NB: Podrazumijevani elementi (ili grupa istih) uvijek dolaze na kraju liste argumenata u definiciji funkcije.
def filterShortWordsLoop(word_list, min_length=2):
if min_length < 1:
raise ValueError("Length must be >= 1.")
filtered_list = []
for word in word_list:
if len(word) >= min_length:
filtered_list.append(word)
return filtered_list
def filterShortWordsLambda(word_list, min_length=2):
if min_length < 1:
raise ValueError("Length must be >= 1.")
return filter(lambda elem: len(elem) >= min_length, word_list)
def filterShortWordsCompr(word_list, min_length=2):
if min_length < 1:
raise ValueError("Length must be >= 1.")
return [elem for elem in word_list if len(elem) >= min_length]
word_list = ["Ja", "sam", "mali", "Mate", "od", "mame", "i", "tate"]
print filterShortWordsLoop(word_list, min_length=3)
print filterShortWordsLambda(word_list, min_length=3)
print filterShortWordsCompr(word_list, min_length=3)
['sam', 'mali', 'Mate', 'mame', 'tate'] ['sam', 'mali', 'Mate', 'mame', 'tate'] ['sam', 'mali', 'Mate', 'mame', 'tate']
Dana vam je mapa koja za ključeve sadrži nazive programskih jezika, a za vrijednosti liste programskih paradigmi koje određeni jezik pokriva.
langs_paradigms = {
"Java" : ["object-oriented", "imperative"],
"Haskell" : ["functional"],
"Lisp" : ["functional", "procedural"]
}
Napišite razred ProgLanguageRepository
uzimajući u obzir sljedeće stvari:
data
.count
koja vraća broj programskih jezika dostupnih u repozitoriju.get_langs_paradigms (lang)
koja za dano ime programskog jezika vraća listu njegovih paradigmi ili vraća None
ako taj jezik ne postoji u repozitoriju.add_lang_paradigm (lang, paradigm)
koja danom programskom jeziku dodaje paradigmu (ako je već nema).remove_lang_paradigm (lang, paradigm)
koja danom programskom jeziku miče danu paradigmu (ako je ima).data
.Pokažite na par primjera da vaša implementacija radi.
class ProgLanguageRepository:
# Konstruktor
def __init__(self, data):
self.data = data
def count(self):
return len(self.data.keys()) # len(self.data)
def get_langs_paradigms(self, lang):
if lang in self.data:
return self.data[lang]
else:
return None
def add_lang_paradigm(self, lang, paradigm):
if paradigm not in self.data[lang]:
self.data[lang].append(paradigm)
def remove_lang_paradigm(self, lang, paradigm):
if paradigm in self.data[lang]:
self.data[lang].remove(paradigm)
def __str__(self):
return self.data.__str__()
prog_repo = ProgLanguageRepository(langs_paradigms)
print prog_repo
{'Lisp': ['functional', 'procedural'], 'Haskell': ['functional'], 'Java': ['object-oriented', 'imperative']}
print prog_repo.get_langs_paradigms("Lisp")
print prog_repo.get_langs_paradigms("d")
['functional', 'procedural'] None
prog_repo.add_lang_paradigm("Haskell", "object-oriented")
prog_repo.add_lang_paradigm("Haskell", "object-oriented")
print prog_repo
{'Lisp': ['functional', 'procedural'], 'Haskell': ['functional', 'object-oriented'], 'Java': ['object-oriented', 'imperative']}
prog_repo.remove_lang_paradigm("Haskell", "object-oriented")
prog_repo.remove_lang_paradigm("Haskell", "object-oriented")
print prog_repo
{'Lisp': ['functional', 'procedural'], 'Haskell': ['functional'], 'Java': ['object-oriented', 'imperative']}
(a) Napišite kôd koji stvara sljedeća tri vektor-stupca, jedan vektor-redak i kvadratnu matricu ranga 2 (koristite numpy
za cijeli zadatak):
$ x_{1} = \begin{pmatrix} 1\\ 2\\ \end{pmatrix}$, $ x_{2} = \begin{pmatrix} 3\\ 5\\ \end{pmatrix}$, $ x_{3} = \begin{pmatrix} -3\\ 4\\ \end{pmatrix}$, $ x_{4} = \begin{pmatrix} 4\\ 0\\ \end{pmatrix}^T$, $ A = \begin{pmatrix} 5 & 3 \\ 10 & 6 \\ \end{pmatrix} $
(b) Zatim napišite naredbe koje stvaraju dvije nove matrice: matricu $C$ dimenzija $2\times3$ koja se dobije tako da se vektor-stupci poredaju horizontalno jedan kraj drugog te matricu $D$ dimenzija $3\times2$ koja se dobije tako da se matrica $A$ postavi ispod danog vektor-retka.
# stvaranje svih danih vektora i matrica
x_1 = np.array([[1], [2]])
x_2 = np.array([[3], [5]])
x_3 = np.array([[-3], [4]])
x_4 = np.array([4, 0])
A = np.array([[5, 3], [10, 6]])
print x_1
print x_2
print x_3
print x_4
print A
[[1] [2]] [[3] [5]] [[-3] [ 4]] [4 0] [[ 5 3] [10 6]]
# stvaranje matrice C
C = np.hstack([x_1, x_2, x_3])
print C
[[ 1 3 -3] [ 2 5 4]]
# stvaranje matrice D
D = np.vstack([x_4, A])
print D
[[ 4 0] [ 5 3] [10 6]]
(c) Izračunajte umnožak matrica $C$ i $D$ te ga pohranite u matricu $U$.
U = C.dot(D)
print U
[[-11 -9] [ 73 39]]
(d) Nadalje, napišite kôd koji izračunava inverz matrice $U$ (spremiti u matricu $I$) kojeg zatim transponira (i sprema u matricu $R$).
I = np.linalg.inv(U)
print I
R = np.transpose(I)
print R
[[ 0.17105263 0.03947368] [-0.32017544 -0.04824561]] [[ 0.17105263 -0.32017544] [ 0.03947368 -0.04824561]]
(e) Izračunajte sumu svih elemenata u matrici $D$ (spremite u varijablu D_total
), ali i sume po zasebnim dimenzijama (D_x
, D_y
).
D_total = np.sum(D[:])
print D_total
D_x = np.sum(D, axis=0) # po x osi
print D_x
D_y = np.sum(D, axis=1) # po y osi
print D_y
28 [19 9] [ 4 8 16]
(f) Ispišite determinantu matrice $R$.
print np.linalg.det(R)
0.00438596491228
(g) Isprobajte vrijedi li $R\cdot R^{-1} = I$.
RI = np.dot(R, np.linalg.inv(R))
print RI
[[ 1. 0.] [ 0. 1.]]
(h) Stvorite vektor-stupac $n$ dimenzija $4\times 1$ čiji su svi elementi 0 (bez ručnog pisanja svih elemenata).
n = np.zeros([4, 1])
print n
[[ 0.] [ 0.] [ 0.] [ 0.]]
(a) Napišite kôd koji iscrtava sljedeće funkcije:
$f_{1}(x) = \sqrt{(1-(|x|-1)^2)}$ i $f_{2}(x) = -3 \cdot \sqrt{(1-\sqrt{\frac{|x|}{2}})}$
pritom definirajući domenu funkcija kao $x \in [-2, 2]$ (u 1000 točaka). Graf funkcije $f_{1}(x)$ prikažite plavom bojom, a graf funkcije $f_{2}(x)$ crvenom. Iscrtajte oba grafa na istoj slici tako da su vidljive točke iz intervala $x \in [-3, 3]$ i $y \in [-3, 1.5]$.
(b) Ostavite oznake osi jednostavno kao $x$ i $y$. Iscrtajte legendu u donjem desnom kutu tako da je naziv funkcije $f_{1}(x)$ bolja polovica, a naziv funkcije $f_{2}(x)$ dobra polovica.
# funkcije
def f_1(x):
return np.sqrt((1 - (np.abs(x) - 1)**2))
def f_2(x):
return -3 * np.sqrt(1 - np.sqrt((np.abs(x)/2)))
# domena u 1000 točaka
x = np.linspace(-2, 2, 1000)
# iscrtavanje prvog grafa plavom linijom
plt.plot(x, f_1(x), 'b-', label="bolja polovica")
# iscrtavanje drugog grafa crvenom linijom
plt.plot(x, f_2(x), 'r-', label="dobra polovica")
# postavljanje ograničenja prikaza
plt.xlim([-3, 3])
plt.ylim([-3, 1.5])
# postavljanje oznaka osi
plt.xlabel("x")
plt.ylabel("y")
# iscrtavanje legende
plt.legend(loc="lower right")
plt.show()
(a) Učitajte skup podataka Iris. Ovaj skup podataka sadrži 150 instanci, 50 za svaku od tri klase (Iris setosa, Iris virginica i Iris versicolor). Svaka instanca, to jest vektor, sadrži četiri značajke: širinu i dužinu latice te širinu i dužinu čašićnog listića. U polju iris.data nalaze se instance, dok se u iris.target nalaze oznake instanci (njihove stvarne klase). Ispišite dimenzije polja instanci te polja njihovih stvarnih oznaka.
# učitavanje dataseta
iris = datasets.load_iris()
print iris.data.shape
print iris.target.shape
(150L, 4L) (150L,)
(b) Budući da ne možemo vizualizirati 4-dimenzijske podatke, iz svake instance izdvojite samo prve dvije značajke. Koristite indeksiranje poljem brojeva. Ispišite dimenzije dobivenog polja instanci.
data_2dim = iris.data[:, 0:2]
print data_2dim.shape
(150L, 2L)
(c) Logičkim indeksiranjem razdvojite primjere za svaku od tri klase. Ispišite dimenzije dobivenih polja.
class_1_samples = iris.data[iris.target == 0]
class_2_samples = iris.data[iris.target == 1]
class_3_samples = iris.data[iris.target == 2]
print class_1_samples.shape
print class_2_samples.shape
print class_3_samples.shape
(50L, 4L) (50L, 4L) (50L, 4L)
(d) Napišite kôd koji iscrtava četiri zasebna grafa (četiri podgrafa u 2x2 mreži), pri čemu tri grafa prikazuju instance određene klase (točke u 2-dimenzijskom prostoru), a četvrti ih prikazuje sve (u različitim bojama). Osigurajte da svi grafovi prikazuju isto područje grafa (npr. $x \in [4,9]$ i $y \in [1.5, 5]$).
Proučite kako se postavlja veličina glavnog okvira (u koji se smještaju podgrafovi) te ju postavite na 10x8.
plt.figure(figsize=(10,8))
# class 1
plt.subplot(221)
plt.scatter(class_1_samples[:,0], class_1_samples[:,1], c='r')
plt.xlim([4, 9])
plt.ylim([1.5, 5])
# class 2
plt.subplot(222)
plt.scatter(class_2_samples[:,0], class_2_samples[:,1], c='g')
plt.xlim([4, 9])
plt.ylim([1.5, 5])
# class 3
plt.subplot(223)
plt.scatter(class_3_samples[:,0], class_3_samples[:,1], c='b')
plt.xlim([4, 9])
plt.ylim([1.5, 5])
# all three classes
plt.subplot(224)
plt.scatter(data_2dim[:,0], data_2dim[:,1], c=iris.target, cmap=plt.cm.Set1)
plt.xlim([4, 9])
plt.ylim([1.5, 5])
plt.show()
(a) Napišite kôd koji u petlji iscrtava grafove normalnih distribucija definiranih s parametarima $\mu$ i $\sigma$:
Dakle, generirat ćete pet grafova normalnih distribucija: $\mathcal{N}_{1}(\mu = 3, \sigma = 1)$, $\mathcal{N}_{2}(\mu = 3, \sigma = 2)$, ... , $\mathcal{N}_{1}(\mu = 3, \sigma = 5)$.
Grafove iscrtajte na istoj slici tako da su vidljive točke iz intervala $x \in [-15, 15]$ i $y \in [0, 0.5]$. Za svaki graf upotrijebite drugu boju. Za domenu koristite $[-50, 50]$ (uzorkujte 1000 točaka). Također napravite legendu u gornjem lijevom kutu koji će sve grafove nazvati onako kako su i u zadatku definirani ($\LaTeX$ kôd radi unutar znakovnih nizova koji definiraju oznaku unutar legende), npr. $\mathcal{N}_{1}(\mu = 3, \sigma = 5)$.
xs = np.linspace(-50, 50, 1000)
sigmas = range(1, 6)
for sigma, color in zip(sigmas, "rgbmy"):
n_dist = stats.norm.pdf(xs, loc=3, scale=sigma)
label = "$\mathcal{N}_{1}(\mu = 3, \sigma = " + str(sigma) + ")$"
plt.plot(xs, n_dist, color, label=label)
plt.xlim([-15, 15])
plt.ylim([0, 0.5])
plt.legend(loc="upper left")
plt.show()
Sada pretpostavite da imate zadanu distribuciju ocjena na nekom kolegiju koja se pokorava normalnoj distribuciji $\mathcal{N}_{G}(\mu = 62, \sigma = 13)$. Najprije je iscrtajte (nebitno kako), ali osigurajte da je domena $[0, 100]$ (raspon mogućih bodova na kolegiju) također uzorkovana u 1000 točaka.
xsg = np.linspace(0, 100, 1000)
n_g = stats.norm.pdf(xsg, loc=62, scale=13)
plt.plot(xsg, n_g, 'b-')
plt.show()
Međutim, vi polažete kolegij naknadno na roku, a profesoru se zaista ne da ispravljati vaš ispit. Kako bi tome doskočio, profesor često koristi tradicionalnu metodu stubišta (https://www.linkedin.com/pulse/20140414044726-2259773-a-guide-to-grading-exams) koju možemo aproksimirati nasumičnim odabirom broja iz distribucije bodova na ispitu. Napišite kôd koji iz distribucije bodova $\mathcal{N}_{G}$ dohvaća slučajnu vrijednost koja predstavlja vaš broj bodova (zaokružite bodove na cijeli broj).
points = int(stats.norm.rvs(loc=62, scale=13))
print "Na ispitu sam osvojio", points, "bodova."
Na ispitu sam osvojio 59 bodova.
Iscrtajte konture 2-dimenzijske Gausove distribucije $\mathcal{N} (\vec{\mu}, \Sigma)$ sa sljedećim parametrima:
1 & 1 \ 0.5 & 3 \ \end{pmatrix}$
Za domenu uzmite $x_{1} \in [-1, 2]$ i $y_{2} \in [-2, 2]$.
mnormal = stats.multivariate_normal([1, 1], [[1, 1], [0.5, 3]])
x_1 = np.linspace(-1, 2)
x_2 = np.linspace(-2, 2)
X1, X2 = np.meshgrid(x_1, x_2)
X1X2 = np.dstack((X1, X2))
plt.contourf(X1, X2, mnormal.pdf(X1X2))
plt.show()