How can i draw a quadratic function? - python

I have a questions concerning numpy.
i listed my data from csv package and used sklearn to plot the data.
i compiled, then plotted graph was weird.
i want to graph as "y = a * x**2 + b * x + c", gentle curve.
How can i change my code to have quadratic function?
data_list = pd.read_csv(r\'과제3_data_list.csv')
type_list = list(["B2V","B3V","B5V","B8V","B9V","A0V","A2V","A3V","A7V","F0V","F3V","F7V","G0V","G8V","K0V","K2V","K3V","K4V","K5V","K6V"])
def N(x):
y = list()
for i in range(len(x)):
if np.isnan(x[i]) == False:
y.insert(i,x[i])
return y
Type = np.array(type_list).reshape(-1,1)
standard = np.array(N(np.array(data_list["NO"]))).reshape(-1,1)
standard_mb = np.array(N(np.array(data_list["mb"]))).reshape(-1,1)
standard_size = np.array(N(np.array(data_list["mean"]))).reshape(-1,1)
star_number = np.array(N(np.array(data_list["number"]))).reshape(-1,1)
star_mbmv = np.array(N(np.array(data_list["mb-mv"]))).reshape(-1,1)
star_mv = np.array(N(np.array(data_list["mv"]))).reshape(-1,1)
evas_mbmv = np.array(N(np.array(data_list["evas_mb-mv"]))).reshape(-1,1)
evas_Mv = np.array(N(np.array(data_list["evas_Mv"]))).reshape(-1,1)
Linear = LinearRegression()
standard_size_sorted = sorted(standard_size)
Poly = PolynomialFeatures(degree=2,include_bias=False)
x_poly = Poly.fit_transform(standard_size)
Linear.fit(x_poly,standard_mb)
y = Linear.predict(x_poly)
def Poly_func(x):
y = Linear.coef_[0][0] * x + Linear.coef_[0][1] * x **2 + Linear.intercept_
return y
plt.scatter(standard_size,standard_mb) # this is just x, y value
plt.plot(standard_size,Poly_func(standard_size)) # this plot have a trouble.
plt.show()

Related

Difference in numpy and sympy lambdify results for basic optimization

I wrote following code for basic optimization based on Newton's method by writing derivatives explicitly and by calculating them using sympy. Why are the results different?
Writing derivatives explicitly:
import numpy as np
def g(x):
return 1.95 - np.exp(-2/x) - 2*np.exp(-np.power(x,4))
# gd: Derivative of g
def gd(x):
return -2*np.power(x,-2)*np.exp(-2/x) + 8*np.power(x,3)*np.exp(-np.power(x,4))
def gdd(x):
return -4*np.power(x,-3)*np.exp(-2/x)-4*np.power(x,-4)*np.exp(-2/x)+24*np.power(x,2)*np.exp(-np.power(x,4))-32*np.power(x,6)*np.exp(-np.power(x,4))
# Newton's
def newton_update(x0,g,gd):
return x0 - g(x0)/gd(x0)
# Main func
x0 = 1.00
condition = True
loops = 1
max_iter = 20
while condition and loops<max_iter:
x1 = newton_update(x0,gd,gdd)
loops += 1
condition = np.abs(x0-x1) >= 0.001
x0 = x1
print('x =',x0)
if loops == max_iter:
print('Solution failed to converge. Try another starting value!')
Output:
x = 1.66382322329
x = 1.38056881356
x = 1.43948432592
x = 1.46207570893
x = 1.46847791968
x = 1.46995571549
x = 1.47027303095
Using sympy and lambdify:
import sympy as sp
x = sp.symbols('x',real=True)
f_expr = 1.95 - exp(-2/x) - 2*exp(-x**4)
dfdx_expr = sp.diff(f_expr, x)
ddfdx_expr = sp.diff(dfdx_expr, x)
# lambidify
f = sp.lambdify([x],f_expr,"numpy")
dfdx = sp.lambdify([x], dfdx_expr,"numpy")
ddfdx = sp.lambdify([x], ddfdx_expr,"numpy")
# Newton's
x0 = 1.0
condition = True
loops = 1
max_iter = 20
while condition and loops<max_iter:
x1 = newton_update(x0,dfdx,ddfdx)
loops += 1
condition = np.abs(x0-x1) >= 0.001
x0 = x1
print('x =',x0)
if loops == max_iter:
print('Solution failed to converge. Try another starting value!')
Output:
x = 1.90803013971
x = 3.96640484492
x = 6.6181614689
x = 10.5162392894
x = 16.3269006983
x = 25.0229734288
x = 38.0552735534
x = 57.5964036862
x = 86.9034400129
x = 130.860980508
x = 196.795321033
x = 295.695535237
x = 444.044999522
x = 666.568627836
x = 1000.35369299
x = 1501.03103981
x = 2252.04689304
x = 3378.57056168
x = 5068.35599056
Solution failed to converge. Try another starting value!
I made it to work by step halving in newton_update function whenever sign of derivative changes in the update. But I couldn't figure out why the results were so different with the same starting point. Also is it possible to get the same results from both?
There is a mistake in the second derivative formula in the function gdd. changing
def gdd(x):
return -4*np.power(x,-3)*np.exp(-2/x)-4*np.power(x,-4)*np.exp(-2/x)+24*np.power(x,2)*np.exp(-np.power(x,4))-32*np.power(x,6)*np.exp(-np.power(x,4))
to
def gdd(x):
return 4*np.power(x,-3)*np.exp(-2/x)-4*np.power(x,-4)*np.exp(-2/x)+24*np.power(x,2)*np.exp(-np.power(x,4))-32*np.power(x,6)*np.exp(-np.power(x,4))
should resolve the issue and produce the same result in both cases, which will be
x = 1.90803013971
x = 3.96640484492
x = 6.6181614689
x = 10.5162392894
x = 16.3269006983
x = 25.0229734288
x = 38.0552735534
x = 57.5964036862
x = 86.9034400129
x = 130.860980508
x = 196.795321033
x = 295.695535237
x = 444.044999522
x = 666.568627836
x = 1000.35369299
x = 1501.03103981
x = 2252.04689304
x = 3378.57056168
x = 5068.35599056
Solution failed to converge. Try another starting value!
This points to a problem with choosing the step size as per the comment

How to calculate error in Polynomial Linear Regression?

I am trying to calculate the error rate of the training data I'm using.
I believe I'm calculating the error incorrectly. The formula is as shown:
y is calculated as shown:
I am calculating this in the function fitPoly(M) at line 49. I believe I am incorrectly calculating y(x(n)), but I don't know what else to do.
Below is the Minimal, Complete, and Verifiable example.
import numpy as np
import matplotlib.pyplot as plt
dataTrain = [[2.362761180904257019e-01, -4.108125266714775847e+00],
[4.324296163702689988e-01, -9.869308732049049127e+00],
[6.023323504115264404e-01, -6.684279243433971729e+00],
[3.305079685397107614e-01, -7.897042003779912278e+00],
[9.952423271981121200e-01, 3.710086310489402628e+00],
[8.308127402955634011e-02, 1.828266768673480147e+00],
[1.855495407116576345e-01, 1.039713135916495501e+00],
[7.088332047815845138e-01, -9.783208407540947560e-01],
[9.475723071629885697e-01, 1.137746192425550085e+01],
[2.343475721257285427e-01, 3.098019704040922750e+00],
[9.338350584099475160e-02, 2.316408265530458976e+00],
[2.107903139601833287e-01, -1.550451474833406396e+00],
[9.509966727520677843e-01, 9.295029459100994984e+00],
[7.164931165416982273e-01, 1.041025972594300075e+00],
[2.965557300301902011e-03, -1.060607693351102121e+01]]
def strip(L, xt):
ret = []
for i in L:
ret.append(i[xt])
return ret
x1 = strip(dataTrain, 0)
y1 = strip(dataTrain, 1)
# HELP HERE
def getY(m, w, D):
y = w[0]
y += np.sum(w[1:] * D[:m])
return y
# HELP ABOVE
def dataMatrix(X, M):
Z = []
for x in range(len(X)):
row = []
for m in range(M + 1):
row.append(X[x][0] ** m)
Z.append(row)
return Z
def fitPoly(M):
t = []
for i in dataTrain:
t.append(i[1])
w, _, _, _ = np.linalg.lstsq(dataMatrix(dataTrain, M), t)
w = w[::-1]
errTrain = np.sum(np.subtract(t, getY(M, w, x1)) ** 2)/len(x1)
print('errTrain: %s' % (errTrain))
return([w, errTrain])
#fitPoly(8)
def plotPoly(w):
plt.ylim(-15, 15)
x, y = zip(*dataTrain)
plt.plot(x, y, 'bo')
xw = np.arange(0, 1, .001)
yw = np.polyval(w, xw)
plt.plot(xw, yw, 'r')
#plotPoly(fitPoly(3)[0])
def bestPoly():
m = 0
plt.figure(1)
plt.xlim(0, 16)
plt.ylim(0, 250)
plt.xlabel('M')
plt.ylabel('Error')
plt.suptitle('Question 3: training and Test error')
while m < 16:
plt.figure(0)
plt.subplot(4, 4, m + 1)
plotPoly(fitPoly(m)[0])
plt.figure(1)
plt.plot(fitPoly(m)[1])
#plt.plot(fitPoly(m)[2])
m+= 1
plt.figure(3)
plt.xlabel('t')
plt.ylabel('x')
plt.suptitle('Question 3: best-fitting polynomial (degree = 8)')
plotPoly(fitPoly(8)[0])
print('Best M: %d\nBest w: %s\nTraining error: %s' % (8, fitPoly(8)[0], fitPoly(8)[1], ))
bestPoly()
Updated: This solution uses numpy's np.interp which will connect the points as a kind of "best fit". We then use your error function to find the difference between this interpolated line and the predicted y values for the degree of each polynomial.
import numpy as np
import matplotlib.pyplot as plt
import itertools
dataTrain = [
[2.362761180904257019e-01, -4.108125266714775847e+00],
[4.324296163702689988e-01, -9.869308732049049127e+00],
[6.023323504115264404e-01, -6.684279243433971729e+00],
[3.305079685397107614e-01, -7.897042003779912278e+00],
[9.952423271981121200e-01, 3.710086310489402628e+00],
[8.308127402955634011e-02, 1.828266768673480147e+00],
[1.855495407116576345e-01, 1.039713135916495501e+00],
[7.088332047815845138e-01, -9.783208407540947560e-01],
[9.475723071629885697e-01, 1.137746192425550085e+01],
[2.343475721257285427e-01, 3.098019704040922750e+00],
[9.338350584099475160e-02, 2.316408265530458976e+00],
[2.107903139601833287e-01, -1.550451474833406396e+00],
[9.509966727520677843e-01, 9.295029459100994984e+00],
[7.164931165416982273e-01, 1.041025972594300075e+00],
[2.965557300301902011e-03, -1.060607693351102121e+01]
]
data = np.array(dataTrain)
data = data[data[:, 0].argsort()]
X,y = data[:, 0], data[:, 1]
fig,ax = plt.subplots(4, 4)
indices = list(itertools.product([0,1,2,3], repeat=2))
for i,loc in enumerate(indices, start=1):
xx = np.linspace(X.min(), X.max(), 1000)
yy = np.interp(xx, X, y)
w = np.polyfit(X, y, i)
y_pred = np.polyval(w, xx)
ax[loc].scatter(X, y)
ax[loc].plot(xx, y_pred)
ax[loc].plot(xx, yy, 'r--')
error = np.square(yy - y_pred).sum() / X.shape[0]
print(error)
plt.show()
This prints out:
2092.19807848
1043.9400277
1166.94550318
252.238810889
225.798905379
155.785478366
125.662973726
143.787869281
6553.66570273
10805.6609259
15577.8686283
13536.1755299
108074.871771
213513916823.0
472673224393.0
1.01198058355e+12
Visually, it plots out this:
From here, it's just a matter of saving those errors to a list and finding the minimum.
I may contribute :
def pol_y(x, w):
y = 0; power = 0;
for i in w:
y += i*(x**power);
power += 1;
return y
The M is included implicitly because it is the final index of w. So if w = [0, 0, 1], then pol_y(x, w) is as same as f(x) = x^2.
If you want to map the 1st column of the dataTrain :
get_Y = [pol_y(i, w) for i in x1 ]
The error may be calculated by
vec_error = [(y1[i] - getY[i])**2 for i in range(0, len(y1)];
train_error = np.sum(vec_error)/len(y1);
Hope this helps.

What is the cause of the artifacts of this convoluted signal?

I am trying to find out the cause of the artifacts that appear after convolution, they are to be seen in the plot arround x = -.0016 and x= .0021 (please see the code below). I am convoluting the "lorentzian" function (or the derivative of the langevin function) which I define in the code, with 2 Dirac impulses in the function "ditrib".
I would appreciate your help.
Thank you
Here is my code:
import numpy as np
import matplotlib.pyplot as plt
def Lorentzian(xx):
if not hasattr(xx, '__iter__'):
xx = [ xx ]
res = np.zeros(len(xx))
for i in range(len(xx)):
x = xx[i]
if np.fabs(x) < 0.1:
res[i] = 1./3. - x**2/15. + 2.* x**4 / 189. - x**6/675. + 2.* x**8 / 10395. - 1382. * x**10 / 58046625. + 4. * x**12 / 1403325.
else:
res[i] = (1./x**2 - 1./np.sinh(x)**2)
return res
amp = 18e-3
a = 1/.61e3
b = 5.5
t_min = 0
dt = 1/5e6
t_max = (10772) * dt
t = np.arange(t_min,t_max,dt)
x_min = -amp/b
x_max = amp/b
dx = dt*(x_min-x_max)/(t_min-t_max)
x = np.arange(x_min,x_max,dx)
func1 = lambda x : Lorentzian(b*(x/a))
def distrib(x):
res = np.zeros(np.size(x))
res[int(np.floor(np.size(x)/3))] = 1
res[int(3*np.floor(np.size(x)/4))] = 3
return res
func2 = lambda x,xs : np.convolve(distrib(x), func1(xs), 'same')
plt.plot(x, func2(x,x))
plt.xlabel('x (m)')
plt.ylabel('normalized signal')
try removing the "pedestal" of func1
func1(x)[0], func1(x)[-1]
Out[7]: (0.0082945964013920719, 0.008297677313152443)
just subtract
func2 = lambda x,xs : np.convolve(distrib(x), func1(xs)-func1(x)[0], 'same')
gives a smooth convolution curve
depending on the result you want you may have to add it back in after, weighted by the Dirac sum

SVM implementation not classifing right

I am building a SVM in python. However, my implemtation is generating the wrong plane. I think it has something to do with my parameters(langrage multipliers) being so small but I am not sure. I think I am doing the convex optimization right. Maybe my data isn't in the right format. I based my code on theses tutorials:http://tullo.ch/articles/svm-py/ and http://www.mblondel.org/journal/2010/09/19/support-vector-machines-in-python/.
Here is my code and output:
import numpy
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import cvxopt
from matplotlib import cm
from cvxopt import matrix, solvers
from itertools import izip
#http://www.tristanfletcher.co.uk/SVM%20Explained.pdf
class SVM:
def __init__(self,X,y):
self.X = X
self.y = y
def findParameters(self,X,y):
# min 1/2 x^T P x + q^T x
#Ax = b
#y's are answer vectors
#put in cvxopt
#
"""P = cvxopt.matrix(np.outer(self.y,self.y)* self.gramMatrix())
q = cvxopt.matrix((numpy.ones(len(self.y))).T)
#G =
#h =
limits = np.asarray(self.y)
A = cvxopt.matrix(limits.T)
#genrates matrix of zzeros
b = cvxopt.matrix(numpy.zeros(len(self.y)))
# actually comp
param = cvxopt.solvers.qp(P,q,G,h,A,b);"""
n_samples, n_features = X.shape
K = self.gramMatrix(X)
P = cvxopt.matrix(np.outer(y, y) * K)
q = cvxopt.matrix(-1 * np.ones(n_samples))
Gtry = cvxopt.matrix(np.diag(np.ones(n_samples) * -1))
htry = cvxopt.matrix(np.zeros(n_samples))
A = cvxopt.matrix(y, (1, n_samples))
b = cvxopt.matrix(0.0)
param = cvxopt.solvers.qp(P, q, Gtry, htry, A, b)
array = param['x']
return array
def WB_calculator(self,X,y):
#calculates w vector
yi = self.y
X = np.asarray(X)
y = np.asarray(y)
important = self.findParameters(X,y)
print("these are parameters")
print(important)
firstsum = [0 for x in range(0,len(y))]
for point in range(0,len(important)):
liste = X[point]*important[point]*yi[point]
firstsum = [x + y for x, y in zip(firstsum,liste)]
#this part calculates bias
#this is a very naive implementation of bias
#xstuff is the x_coordinate vector we find this by transpose
b = 0
for i in range(0,len(important)):
b = b+ (yi[i]- np.dot(firstsum,X[i]))
avgB = b/len(important)
answer = (firstsum , avgB)
print("w vector")
print(firstsum)
return answer
def polynomialK(self,u,v,b):
return (np.dot(u,v)+b)**2
#Guassian Kernal Funciton
def gaussianK(self,v1, v2, sigma):
return np.exp(-norm(v1-v2, 2)**2/(2.*sigma**2))
#computes the gramMatrix given a set of all points included in the data
#this is basicly a matrix of dot prodducts
def gramMatrix(self,X):
gramMatrix = []
data = np.asarray(self.X)
dataTran = data
#print(dataTran)
for x in dataTran:
row = []
#print(row)
for y in dataTran:
row.append(np.dot(x,y))
gramMatrix.append(row)
#print(row)
return gramMatrix
def determineAcceptance(self,point,X,y):
# I'm not sure if this is the proper bounding lets checl
cutoff = self.WB_calculator(X,y)
if(np.dot(cutoff[0],point)+cutoff[1] >0):
print("You got in")
elif(np.dot(cutoff[0],point)+cutoff[1]<0):
print("Study")
# plots plane and points
def Graph(self,X,y):
important_stuff = self.WB_calculator(X,y)
weights = important_stuff[0]
c = important_stuff[1]
#here we actaually graph the functionb
graphable = X.T
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
xs = graphable[0]
ys = graphable[1]
zs = graphable[2]
colors = self.y
ax.scatter(xs,ys,zs,c=colors)
ax.set_xlabel("A")
ax.set_ylabel("B")
ax.set_zlabel("C")
#this changes orientation and look of surface
ax.view_init(azim = 180+40,elev = 22)
X = np.arange(-2, 2, 0.25)
Y = np.arange(-2, 2, 0.25)
X, Y = np.meshgrid(X, Y)
Z = ((-weights[0]*X + -weights[1]*Y - c)/(weights[2]))
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
linewidth=0, antialiased=True)
plt.show()
#list of points to test
a = [[-.1,-.1,-.1],[-.2,-.2,-.2],[.15,.15,.15],[.9,.9,.9],[.95,.95,.95]]
check = np.asarray(a)
b = [.01,.01,.01,1,1]
bigger =np.asarray(b)
d = SVM(a,b)
print(d.gramMatrix(check)[0])
print("parameters ya")
print(d.findParameters(check,bigger))
print(d.WB_calculator(check,bigger))
d.Graph(check,bigger)
d.determineAcceptance([.01,.01,.01],check,bigger)

Python: heat density plot in a disk

My goal is to make a density heat map plot of sphere in 2D. The plotting code below the line works when I use rectangular domains. However, I am trying to use the code for a circular domain. The radius of sphere is 1. The code I have so far is:
from pylab import *
import numpy as np
from matplotlib.colors import LightSource
from numpy.polynomial.legendre import leggauss, legval
xi = 0.0
xf = 1.0
numx = 500
yi = 0.0
yf = 1.0
numy = 500
def f(x):
if 0 <= x <= 1:
return 100
if -1 <= x <= 0:
return 0
deg = 1000
xx, w = leggauss(deg)
L = np.polynomial.legendre.legval(xx, np.identity(deg))
integral = (L * (f(x) * w)[None,:]).sum(axis = 1)
c = (np.arange(1, 500) + 0.5) * integral[1:500]
def r(x, y):
return np.sqrt(x ** 2 + y ** 2)
theta = np.arctan2(y, x)
x, y = np.linspace(0, 1, 500000)
def T(x, y):
return (sum(r(x, y) ** l * c[:,None] *
np.polynomial.legendre.legval(xx, identity(deg)) for l in range(1, 500)))
T(x, y) should equal the sum of c the coefficients times the radius as a function of x and y to the l power times the legendre polynomial where the argument is of the legendre polynomial is cos(theta).
In python: integrating a piecewise function, I learned how to use the Legendre polynomials in a summation but that method is slightly different, and for the plotting, I need a function T(x, y).
This is the plotting code.
densityinterpolation = 'bilinear'
densitycolormap = cm.jet
densityshadedflag = False
densitybarflag = True
gridflag = True
plotfilename = 'laplacesphere.eps'
x = arange(xi, xf, (xf - xi) / (numx - 1))
y = arange(yi, yf, (yf - yi) / (numy - 1))
X, Y = meshgrid(x, y)
z = T(X, Y)
if densityshadedflag:
ls = LightSource(azdeg = 120, altdeg = 65)
rgb = ls.shade(z, densitycolormap)
im = imshow(rgb, extent = [xi, xf, yi, yf], cmap = densitycolormap)
else:
im = imshow(z, extent = [xi, xf, yi, yf], cmap = densitycolormap)
im.set_interpolation(densityinterpolation)
if densitybarflag:
colorbar(im)
grid(gridflag)
show()
I made the plot in Mathematica for reference of what my end goal is
If you set the values outside of the disk domain (or whichever domain you want) to float('nan'), those points will be ignored when plotting (leaving them in white color).

Categories

Resources