quadratic equations solving function on python - python

def quadSolve(a,b,c,r):
r = list()
if a != 0:
if b**2 - 4*a*c > 0:
k1 = (-b + (b**2-4*a*c)**(1/2))/2*a
k2 = (-b - (b**2-4*a*c)**(1/2))/2*a
r.append(k1)
r.append(k2)
if b**2 - 4*a*c == 0:
k0 = -b / 2*a
r.append(k0)
if b**2 - 4*a*c < 0:
r.clear()
if a == 0 and b != 0:
k3 = -c/b
r.append(k3)
if a==0 and b == 0:
r.clear()
return r
main():
print("ax^2 + bx + c = 0")
a = input("a is?: ")
b = input("b is?: ")
c = input("c is?: ")
r = list()
answer = quadSolve(a,b,c,r)
if len(answer) == 0:
print("no roots")
else:
print("answer is", answer)
print()
Can someone point out what's wrong here??
I'm trying to make a function that solves quadratic equations using list r
I don't know what is wrong with the main code.

Look, IDK how to use the "def something ():", but this is the way that it ran for me:
My code is:
## The rules:
# function == ax2 + bx + c
# delta == b2 - 4ac
# if delta == 0: one answer
# if delta < 0: don't exist answer E R
# if delta > 0: two answers
# result is: (+/- r/delta - b)/2a
answer = 'answer ='
print('ax^2 + bx^2 + c = 0')
a = int(input('a is: '))
b = int(input('b is: '))
c = int(input('c is: '))
delta = b**2 - 4*a*c
if delta > 0:
x = (delta**(1/2) - b)/(2*a)
x2 = (-delta**(1/2) - b)/(2*a)
print(answer, x, x2)
if delta == 0:
x = (-b)/(2*a)
print(answer, x)
if delta < 0:
print("Doesn't exist Real solution.")
PyShell example:
ax^2 + bx^2 + c = 0
a is: 1
b is: -4
c is: -12
answer = 6.0 -2.0

Another way to do, based in your code is:
Look the int(input())was added and the main(): was deleted
def quadSolve(a,b,c,r):
r = list()
if a != 0:
if b**2 - 4*a*c > 0:
k1 = (-b + (b**2-4*a*c)**(1/2))/2*a
k2 = (-b - (b**2-4*a*c)**(1/2))/2*a
r.append(k1)
r.append(k2)
if b**2 - 4*a*c == 0:
k0 = -b / 2*a
r.append(k0)
if b**2 - 4*a*c < 0:
r.clear()
if a == 0 and b != 0:
k3 = -c/b
r.append(k3)
if a==0 and b == 0:
r.clear()
return r
print("ax^2 + bx + c = 0")
a = int(input("a is?: "))
b = int(input("b is?: "))
c = int(input("c is?: "))
r = list()
answer = quadSolve(a,b,c,r)
if len(answer) == 0:
print("no roots")
else:
print("answer is", answer)
print()

Related

im trying use bisection method to find the root of the function x^4 - 5x^3 + (22/3)x^2 - (116/27)x + (8/9) in [0,1] with e = 0.01

here's the code i made
def bisection(f, a, b, e):
step = 1
condition = True
while condition:
c = (a+b)/2
if f(a) * f(c) < 0:
b = c
else:
a = c
if f(c) == 0:
break
step = step + 1
condition = abs(f(a)-f(b)) > e
print(c)
return(c)
if f(a)* f(b) > 0:
print("no roots")
else:
bisection(f, a, b, e)
a, b, e = input().split(' ')
a = float(a)
b = float(b)
print(round(root, 4))
but I'm getting a root of c = 0.171875
instead of 0.6875

How to print a function in the main function

import math
return def is_valid(filing_status, income):
"""Function determines whether the input is valid. If valid, it returns 'True'. The filing status must come from the list of options given and the income must be an integer greater than 0. If these qualifications are not met, the function will return 'False'."""
x = filing_status
y = income
def setup(x, y):
if x in ('single', 'married filing jointly', 'married filing separately', 'widow', 'head of household') and y >= 0:
print "True"
else:
print "False"
setup(x, y)
return def tax(filing_status, income):
"""Fuction displays the value of taxes that different groups of people are required to pay based on their income."""
f = filing_status
i = income
def calculation(f, i):
if f in ('single') and int(0 < i <= 9275):
print int(i*0.100)
elif 9276 <= i <= 37650:
print int((i-9276.00)*0.15 + 9275.*0.1)
elif 37651 <= i <= 91150:
print int((i-37651)*0.25 + 28375*0.15 + 9275*0.1)
elif 91151 <= i <= 190150:
print int((i-91151)*0.28 + 53500*0.25 + 28375*0.15 + 9275*0.1)
elif 190151 <= i <= 413350:
print int((i-190151)*0.33 + 99000*0.28 + 53500*0.25 + 28375*0.15 + 9275*0.1)
elif 413351 <= i <= 415050:
print int((i-413351)*0.35 + 223200*0.33 + 99000*0.28 + 53500*0.25 + 28375*0.15 + 9275*0.1)
elif i >= 415051:
print int((i-415051)*0.396 + 1700*0.35 + 223200*0.33 + 99000*0.28 + 53500*0.25 + 28375*0.15 + 9275*0.1)
calculation(f,i)
return def tax(filing_status,income):
c = filing_status
d = income
def calculation(c,d):
if c in ('widow','married filing jointly') and 0 < d <= 18550:
print int(d*0.1)
elif 18551 <= d <= 75300:
print int((d-18551)*0.15 + 18550*0.1)
elif 75301 <= d <= 151900:
print int((d-75301)*0.25 + 56750*0.15 + 18550*0.1)
elif 151901 <= d <= 231450:
print int((d-151901)*0.28 + 76600*0.25 + 56750*0.15 + 18550*0.1)
elif 231451 <= d <= 413350:
print int((d-231451)*0.33 + 79550*0.28 +76600*0.25 + 56750*0.15 + 18550*0.1)
elif 413351 <= d <= 466950:
print int((d-413351)*0.35 + 181900*0.33 + 79550*0.28 +76600*0.25 + 56750*0.15 + 18550*0.1)
elif d >= 466951:
print int((d-466951)*0.396 + 53600*0.35 + 181900*0.33 + 79550*0.28 +76600*0.25 + 56750*0.15 + 18550*0.1)
calculation(c,d)
return def tax(filing_status,income):
g = filing_status
h = income
def calculation(g,h):
if g in ('married filing separately') and 0 < h <= 9275:
print int(h*0.1)
elif 9276 <= h <= 37650:
print int((h-9276)*0.15 + 9275*0.1)
elif 37651 <= h <= 75950:
print int((h-37651)*0.25 + 28375*0.15 + 9275*0.1)
elif 75951 <= h <= 115725:
print int((h-75951)*0.28 + 38300*0.25 + 28375*0.15 + 9275*0.1)
elif 115726 <= h <= 206675:
print int((h-115726)*0.33 + 39775*0.28 +38300*0.25 + 28375*0.15 + 9275*0.1)
elif 206676 <= h <= 233475:
print int((h-206676)*0.35 + 90950*0.33 + 39775*0.28 +38300*0.25 + 28375*0.15 + 9275*0.1)
elif h >= 233476:
print int((h-233476)*0.396 + 26800*0.35 + 90950*0.33 + 39775*0.28 +38300*0.25 + 28375*0.15 + 9275*0.1)
calculation(g,h)
return def tax(filing_status,income):
m = filing_status
n = income
def calculation(m,n):
if m in ('head of household') and 0 < n <= 13250:
print int(n*0.1)
elif 13251 <= n <= 50400:
print int((n-13251)*0.15 + 13250*0.1)
elif 50401 <= n <= 130150:
print int((n-50401)*0.25 + 37150*0.15 + 13250*0.1)
elif 130151 <= n <= 210800:
print int((n-130151)*0.28 + 79750*0.25 + 37150*0.15 + 13250*0.1)
elif 210801 <= n <= 413350:
print int((n-210801)*0.33 + 80649*0.28 +79750*0.25 + 37150*0.15 + 13250*0.1)
elif 413351 <= n <= 441000:
print int((n-413351)*0.35 + 202550*0.33 + 80649*0.28 +79750*0.25 + 37150*0.15 + 13250*0.1)
elif n >= 441001:
print int((n-441001)*0.396 + 27649*0.35 + 202550*0.33 + 80649*0.28 +79750*0.25 + 37150*0.15 + 13250*0.1)
calculation(m,n)
return def percent_of_income(tax, income):
"""Function calculates the percent of income that goes to taxes."""
t = tax
s = income
def calc_percent (t, s):
print (t/s)*100
calc_percent(t, s)
return def main(filing_status,income):
"""Function brings the previous functions together to describe taxes and the percent of income of individuals based on their filing statuses"""
w = filing_status
o = income
v = tax(filing_status, income)
if w not in ('single', 'married filing jointly', 'married filing separately', 'widow', 'head of household'):
print "Invalid input. Filing status must be 'single', 'married filing jointly', 'married filing separately', 'widow', or 'head of household'. Income must be greater than or equal to zero."
if o < 0:
print "Income must be greater than or equal to zero."
else:
return ('Tax: $', str(v))
return ('Tax as % of income: $', str(percent_of_income(tax, income)) + '%')
Trying to print the tax and percent of income functions in the main. How do I reference this? I am not sure if the variables in the percent of income are documented correctly, and everytime i try to run the function, it won't print the tax value inside of the string "Tax;". I also tried concatenating that.
I think I need a little more info to help you out, but I'll try.
It looks like with this function that you are only printing if the first or second ifs are executed. If they are not, you are executing the else, which only returns a tuple without printing. Also, the second return will not be executed. Once a return is executed, the function ends.

Python. Make asterisk graphic whith integers list

I can't print line with any integer from list.
I need result to be: if I have in list [5, 1, 2, 3], then it has to print:
*****
*
**
***
my code:
zv = []
l = 1
xa = 0
xb = 1
eil = int(input("Number of rows: "))
eill = eil
def piesinys(eil, zv):
while eil > 0:
print("*" * zv[xa:xb]) #<---- This is hard to do
xa = xa + 1
xb = xb + 1
eil = eil - 1
while eill > 0:
abc = int(input("Asterisk's in " + str(l) + " row: "))
zv.append(abc)
l = l + 1
eill = eill - 1
piesinys
Prints nothing.
Few issues with your code:
Add a global declaration so that your function can find the variables outside of it:
def piesinys(eil, zv):
global xa, xb
while eil > 0:
print("*" * zv[xa]) # This is hard to do
xa = xa + 1
xb = xb + 1
eil = eil - 1
And call the function at the end:
piesinys(eil, zv)
Completed working code:
zv = []
l = 1
xa = 0
xb = 1
eil = int(input("Įveskite eilučių skaičių: "))
eill = eil
def piesinys(eil, zv):
global xa, xb
while eil > 0:
print("*" * zv[xa])
xa = xa + 1
xb = xb + 1
eil = eil - 1
while eill > 0:
abc = int(input("Įveskite žvaigždučių skaičių " + str(l) + " eilutėje: "))
zv.append(abc)
l = l + 1
eill = eill - 1
piesinys(eil, zv)
And again, thanks everyone who helped me!
Problems I see:
piesinys is the name of the function; to actually call the function you need to do piesinys(eil, zv)
zv[xa:xb] returns a one-element list, ie [5], when you wanted the number 5. Try zv[xa] instead.
I would rewrite it as
def get_int(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
pass
def get_row_values(num_rows):
values = []
for i in range(1, num_rows + 1):
prompt = "Asterisks in row {}: ".format(i)
value = get_int(prompt)
values.append(value)
return values
def draw_histogram(values):
for value in values:
print('*' * value)
def main():
num_rows = get_int("Number of rows: ")
values = get_row_values(num_rows)
draw_histogram(values)
if __name__ == "__main__":
main()
Simplest solution will be:
>>> num_list = [5, 1, 2, 3]
>>> for x in num_list:
... print '*' * x
...
*****
*
**
***

PYTHON 3.0 Negative numbers aren't working as inputs

I'm trying to make a factoring program, but it doesn't seem to work with negative number a-, b- and c-inputs.
from fractions import gcd
factor = -1
opp = 0
number = 1
success = 0
a = int(input("a-value: "))
b = int(input("b-value: "))
c = int(input("c-value: "))
factors = []
d = 0
e = 0
while number <= abs(a*c):
#Checking for multiples
if abs(a*c) % number == 0:
factor += 1
factors.append(number)
number += 1
while (factor-opp) >= 0:
#Checking for actual factors
d = int(factors[factor])
e = int(factors[opp])
if (abs(d+e) or abs(d-e)) == abs(b):
success += 1
break
else:
factor -= 1
opp += 1
if success > 0:
if (d+e) == b:
e = e
elif (d-e) == b:
e -= 2*e
elif (e-d) == b:
d -= 2*d
elif (-d-e) == b:
d -= 2*d
e -= 2*e
#Figuring out the equation
if d % a == 0:
d /= a
f = 1
else:
f = a/gcd(d,a)
d /= gcd(d,a)
if e % a == 0:
e /= a
g = 1
else:
g = a/gcd(e,a)
e /= gcd(e,a)
#Displaying the answer
if d >= 0:
d = str("+" + str(int(d)))
if e >= 0:
e = str("+" + str(int(e)))
elif e < 0:
e = str(int(e))
else:
d = str(int(d))
if e >= 0:
e = str("+" + str(int(e)))
elif e < 0:
e = str(int(e))
if f == 1:
if g == 1:
print ("(x" + d + ")(x" + e + ")")
else:
g = str(int(g))
print ("(x" + d + ")(" + g + "x" + e + ")")
elif g == 1:
f = str(int(f))
print ("(" + f + "x" + d + ")(x" + e + ")")
else:
f = str(int(f))
g = str(int(g))
print ("(" + f + "x" + d + ")(" + g + "x" + e + ")")
else:
print("This equation cannot be factored into integers.")
More specifically, the problem is somewhere within this block, I think. I've tested it out with print statements:
while (factor-opp) >= 0:
#Checking for actual factors
d = int(factors[factor])
e = int(factors[opp])
if (abs(d+e) or abs(d-e)) == abs(b):
success += 1
break
else:
factor -= 1
opp += 1
I've searched everywhere: my programming textbook, online searches about inputting negatives, everything. What am I doing wrong here?
Ok I am able to reproduce your issue for a simple testcase like - a=1 , b=0, c=-4 .
The issue is in the line -
if (abs(d+e) or abs(d-e)) == abs(b):
This does not check whether abs(b) is equal to abs(d+e) or abs(d-e) , instead it first evaluates the result of (abs(d+e) or abs(d-e)) , which would return the first non-zero result , and then compare that against abs(b) , so for negative numbers this does not evaluate the result correctly. Change that condition to -
if abs(d+e) == abs(b) or abs(d-e) == abs(b):
or you can also use a set -
if abs(b) in {abs(d+e), abs(d-e)}: #Though I doubt if using set would give any performance improvement because of the overhead of creating a set.
Demo after changes -
a-value: 1
b-value: 0
c-value: -4
(x+2)(x-2)
a-value: 1
b-value: -1
c-value: -6
(x-3)(x+2)
One more thing, there is something you have not considered , when a=-1 , b=-4 , c=-4 , the result should come to -(x+2)(x+2) , but the current program results in (x+2)(x+2) .

SVM: problems with SMO algorithm

I'm currently trying to code a non linear SVM for handwritten digits recognition using the MNIST data base.
I chose to use the SMO algorithm (based on Platt's paper and other books), but I have some trouble implementing it.
When I run the code over the training set, the bias goes higher and higher, sometimes until "Inf" value, leading the SVM to "classify" every example in the same class.
Here is my code:
import numpy
import gzip
import struct
import matplotlib
from sklearn import datasets
from copy import copy
class SVM:
def __init__(self, constant, data_set, label_set):
self._N = len(data_set)
if self._N != len(label_set):
raise Exception("Data size and label size don't match.")
self._C = constant
self._epsilon = 0.001
self._tol = 0.001
self._data = [numpy.ndarray.flatten((1/255)*elt) for elt in data_set]
self._dimension = len(self._data[0])
self._label = label_set
self._alphas = numpy.zeros((1, self._N))
self._b = 0
self._errors = numpy.ndarray((2, 0))
def kernel(self, x1, x2):
x1 = x1.reshape(1,self._dimension)
result = numpy.power(numpy.dot(x1, x2), 3)
return result
def evaluate(self, x):
result = 0
i = 0
while i < self._N:
result += self._alphas[0, i]*self._label[i]*self.kernel(x, self._data[i])
i += 1
result += self._b
return result
def update(self, i1, i2, E2):
i1 = int(i1)
i2 = int(i2)
if i1 == i2:
return 0
y1 = self._label[i1]
y2 = self._label[i2]
alpha1 = self._alphas[0, i1]
alpha2 = self._alphas[0, i2]
#If alpha1 is non-bound, its error is in the cache.
#So we check its position to extract its error.
#Else, we compute it.
if alpha1 > 0 and alpha1 < self._C :
position = 0
for i, elt in enumerate(self._errors[0, :]):
if elt == i1:
position = i
E1 = self._errors[1, position]
else:
E1 = self.evaluate(self._data[i1]) - y1
s = y1*y2
H = L = 0
if y1 != y2:
L = max(0, alpha2 - alpha1)
H = min(self._C, self._C + alpha2 - alpha1)
else:
L = max(0, alpha2 + alpha1 - self._C)
H = min(self._C, alpha2 + alpha1)
if H == L:
return 0
K11 = self.kernel(self._data[i1], self._data[i1])
K12 = self.kernel(self._data[i1], self._data[i2])
K22 = self.kernel(self._data[i2], self._data[i2])
eta = K11 + K22 - 2*K12
if eta > 0:
alpha2_new = alpha2 + (y2*(E1 - E2)/eta)
if alpha2_new < L:
alpha2_new = L
elif alpha2_new > H:
alpha2_new = H
else:
f1 = y1*(E1 + self._b) - alpha1*K11 - s*alpha2*K12
f2 = y2*(E2 + self._b) - alpha2*K22 - s*alpha1*K12
L1 = alpha1 + s*(alpha2 - L)
H1 = alpha1 + s*(alpha2 - H)
FuncL = L1*f1 + L*f2 + (1/2)*numpy.square(L1)*K11 + (1/2)*numpy.square(L)*K22 + s*L1*L*K12
FuncH = H1*f1 + H*f2 + (1/2)*numpy.square(H1)*K11 + (1/2)*numpy.square(H)*K22 + s*H1*H*K12
if FuncL < FuncH - self._epsilon:
alpha2_new = L
elif FuncL > FuncH + self._epsilon:
alpha2_new = H
else:
alpha2_new = alpha2
if numpy.abs(alpha2_new - alpha2) < self._epsilon*(alpha2_new+alpha2+ self._epsilon):
return 0
alpha1_new = alpha1 + s*(alpha2 - alpha2_new)
#Update of the threshold.
b1 = E1 + y1*(alpha1_new - alpha1)*K11 + y2*(alpha2_new - alpha2)*K12 + self._b
b2 = E2 + y1*(alpha1_new - alpha1)*K12 + y2*(alpha2_new - alpha2)*K22 + self._b
if L < alpha1_new < H:
b_new = b1
elif L < alpha2_new < H:
b_new = b2
else:
b_new = (b1+b2)/2
#Update the cache error
#If alpha2 was bound and its new value is non-bound, we add its index and its error to the cache.
#If alpha2 was unbound and its new value is bound, we delete it from the cache.
if (alpha2 == 0 or alpha2 == self._C) and (alpha2_new > 0 and alpha2_new < self._C):
vector_alpha2_new = numpy.array([i2, E2])
vector_alpha2_new = vector_alpha2_new.reshape((2, 1))
self._errors = numpy.concatenate((self._errors, vector_alpha2_new), 1)
if (alpha2 > 0 and alpha2 < self._C) and (alpha2_new == 0 or alpha2_new == self._C):
l = 0
position = 0
while l < len(self._errors[0, :]):
if self._errors[0, l] == i2:
position = l
l += 1
self._errors = numpy.delete(self._errors, position, 1)
#We do the exact same thing with alpha1.
if (alpha1 == 0 or alpha1 == self._C) and (alpha1_new > 0 and alpha1_new < self._C):
vector_alpha1_new = numpy.array([i1, E1])
vector_alpha1_new = vector_alpha1_new.reshape((2, 1))
self._errors = numpy.concatenate((self._errors, vector_alpha1_new), 1)
if (alpha1 > 0 and alpha1 < self._C) and (alpha1_new == 0 or alpha1_new == self._C):
l = 0
position = 0
while l < len(self._errors[0, :]):
if self._errors[0, l] == i1:
position = l
l += 1
self._errors = numpy.delete(self._errors, position, 1)
#Then we update the error for each non bound point using the new values for alpha1 and alpha2.
for i,error in enumerate(self._errors[1, :]):
self._errors[1, i] = error + (alpha2_new - alpha2)*y2*self.kernel(self._data[i2], self._data[int(self._errors[0, i])]) + (alpha1_new - alpha1)*y1*self.kernel(self._data[i1], self._data[int(self._errors[0, i])]) - self._b + b_new
#Storing the new values of alpha1 and alpha2:
self._alphas[0, i1] = alpha1_new
self._alphas[0, i2] = alpha2_new
self._b = b_new
print(self._errors)
return 1
def examineExample(self, i2):
i2 = int(i2)
y2 = self._label[i2]
alpha2 = self._alphas[0, i2]
if alpha2 > 0 and alpha2 < self._C:
position = 0
for i, elt in enumerate(self._errors[0, :]):
if elt == i2:
position = i
E2 = self._errors[1, position]
else:
E2 = self.evaluate(self._data[i2]) - y2
r2 = E2*y2
if (r2< -self._tol and alpha2 < self._C) or (r2 > self._tol and alpha2 > 0):
n = numpy.shape(self._errors)[1]
if n > 1:
i1 = 0
if E2 > 0:
min = self._errors[1, 0]
position = 0
for l, elt in enumerate(self._errors[1, :]):
if elt < min:
min = elt
position = l
i1 = self._errors[0, position]
else:
max = self._errors[1, 0]
position = 0
for l, elt in enumerate(self._errors[1, :]):
if elt > max:
max = elt
position = l
i1 = self._errors[0, position]
if self.update(i1, i2, E2):
return 1
#loop over all non bound examples starting at a random point.
list_index = [i for i in range(n)]
numpy.random.shuffle(list_index)
for i in list_index:
i1 = self._errors[0, i]
if self.update(i1, i2, E2):
return 1
#Loop over all the training examples, starting at a random point.
list_bound = [i for i in range(self._N) if not numpy.any(self._errors[0, :] == i)]
numpy.random.shuffle(list_bound)
for i in list_bound:
i1 = i
if self.update(i1, i2, E2):
return 1
return 0
def SMO(self):
numChanged = 0
examineAll = 1
cpt = 1
while(numChanged > 0 or examineAll):
numChanged = 0
if examineAll == 1:
for i in range(self._N):
numChanged += self.examineExample(i)
else:
for i in self._errors[0, :]:
numChanged += self.examineExample(i)
if examineAll == 1:
examineAll = 0
elif numChanged == 0:
examineAll = 1
cpt += 1
def load_training_data(a, b):
train = gzip.open("train-images-idx3-ubyte.gz", "rb")
labels = gzip.open("train-labels-idx1-ubyte.gz", "rb")
train.read(4)
labels.read(4)
number_images = train.read(4)
number_images = struct.unpack(">I", number_images)[0]
rows = train.read(4)
rows = struct.unpack(">I", rows)[0]
cols = train.read(4)
cols = struct.unpack(">I", cols)[0]
number_labels = labels.read(4)
number_labels = struct.unpack(">I", number_labels)[0]
image_list = []
label_list = []
if number_images != number_labels:
raise Exception("The number of labels doesn't match with the number of images")
else:
for l in range(number_labels):
if l % 1000 == 0:
print("l:{}".format(l))
mat = numpy.zeros((rows, cols), dtype = numpy.uint8)
for i in range(rows):
for j in range(cols):
pixel = train.read(1)
pixel = struct.unpack(">B", pixel)[0]
mat[i][j] = pixel
image_list += [mat]
lab = labels.read(1)
lab = struct.unpack(">B", lab)[0]
label_list += [lab]
train.close()
labels.close()
i = 0
index_a = []
index_b = []
while i < number_labels:
if label_list[i] == a:
index_a += [i]
elif label_list[i] == b:
index_b += [i]
i += 1
image_list = [m for i,m in enumerate(image_list) if (i in index_a) | (i in index_b)]
mean = (a+b)/2
label_list = [ numpy.sign(m - mean) for l,m in enumerate(label_list) if l in index_a+index_b]
return ([image_list, label_list])
def load_test_data():
test = gzip.open("t10k-images-idx3-ubyte.gz", "rb")
labels = gzip.open("t10k-labels-idx1-ubyte.gz", "rb")
test.read(4)
labels.read(4)
number_images = test.read(4)
number_images = struct.unpack(">I", number_images)[0]
rows = test.read(4)
rows = struct.unpack(">I", rows)[0]
cols = test.read(4)
cols = struct.unpack(">I", cols)[0]
number_labels = labels.read(4)
number_labels = struct.unpack(">I", number_labels)[0]
image_list = []
label_list = []
if number_images != number_labels:
raise Exception("The number of labels doesn't match with the number of images")
else:
for l in range(number_labels):
if l % 1000 == 0:
print("l:{}".format(l))
mat = numpy.zeros((rows, cols), dtype = numpy.uint8)
for i in range(rows):
for j in range(cols):
pixel = test.read(1)
pixel = struct.unpack(">B", pixel)[0]
mat[i][j] = pixel
image_list += [mat]
lab = labels.read(1)
lab = struct.unpack(">B", lab)[0]
label_list += [lab]
test.close()
labels.close()
return ([image_list, label_list])
data = load_training_data(0, 7)
images_training = data[0]
labels_training = data[1]
svm = SVM(0.1, images_training[0:200], labels_training[0:200])
svm.SMO()
def view(image, label=""):
print("Number : {}".format(label))
pylab.imshow(image, cmap = pylab.cm.gray)
pylab.show()
First, SMO is a fairly complicated algorithm - it is not one easy to debug in this kind of format.
Second, you are starting too high up in your testing. Some advice to help you debug your problems.
1) First, switch to using the linear kernel. Its much easier for you to compute the exact linear solution with another algorithm and compare what you are getting with the exact solution. This way its only the weight vectors and bias term. If you stay in the dual space, you'll have to compare all the coefficients and make sure things stay in the same order.
2) Start with a much simpler 2D problem where you know what the general solution should look like. You can then visualize the solution, and watch as it changes at each step - this can be a visual tool to help you find where something goes wrong.
One important thing is you said this:
b1 = E1 + y1*(alpha1_new - alpha1)*K11 + y2*(alpha2_new - alpha2)*K12 + self._b
b2 = E2 + y1*(alpha1_new - alpha1)*K12 + y2*(alpha2_new - alpha2)*K22 + self._b
Basically you're just adding to b every time with this code. Your b's should look more like this:
b1 = smo.b - E1 - y1 * (a1 - alpha1) * smo.K[i1, i1] - y2 * (a2 - alpha2) * smo.K[i1, i2]
b2 = smo.b - E2 - y1 * (a1 - alpha1) * smo.K[i1, i2] - y2 * (a2 - alpha2) * smo.K[i2, i2]
This version is not perfect, but I recommend checking apex51's version on Github for pointers:
SVM-and-sequential-minimal-optimization
The mathematical basis in the notes are very strong (despite some minor discrepancies with Platt's paper) and the code is not perfect, but a good direction for you. I would also suggest looking at other, completed SMOs and trying to tweak that code to math your needs instead of writing from scratch.

Categories