Related
I'm having a curve (parabol) from 0 to 1 on both axes as follows:
I generate another curve by moving the original curve along the x-axis and combine both to get the following graph:
How can I remove the intersected section to have only the double bottoms pattern like this:
The code I use for the graph:
import numpy as np
import matplotlib.pyplot as plt
def get_parabol(start=-1, end=1, steps=100, normalized=True):
x = np.linspace(start, end, steps)
y = x**2
if normalized:
x = np.array(x)
x = (x - x.min())/(x.max() - x.min())
y = np.array(y)
y = (y - y.min())/(y.max() - y.min())
return x, y
def curve_after(x, y, x_ratio=1/3, y_ratio=1/2, normalized=False):
x = x*x_ratio + x.max() - x[0]*x_ratio
y = y*y_ratio + y.max() - y.max()*y_ratio
if normalized:
x = np.array(x)
x = (x - x.min())/(x.max() - x.min())
y = np.array(y)
y = (y - y.min())/(y.max() - y.min())
return x, y
def concat_arrays(*arr, axis=0, normalized=True):
arr = np.concatenate([*arr], axis=axis).tolist()
if normalized:
arr = np.array(arr)
arr = (arr - arr.min())/(arr.max() - arr.min())
return arr
x, y = get_parabol()
new_x, new_y = curve_after(x, y, x_ratio=1, y_ratio=1, normalized=False)
new_x = np.add(x, 0.5)
# new_y = np.add(y, 0.2)
xx = concat_arrays(x, new_x, normalized=True)
yy = concat_arrays(y, new_y, normalized=True)
# plt.plot(x, y, '-')
plt.plot(xx, yy, '--')
I'm doing a research on pattern analysis that requires me to generate patterns with mathematical functions.
Could you show me a way to achieve this? Thank you!
First off, I would have two different parabola functions such that:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y1 = np.add(x, 0.3)**2 # Parabola centered at -0.3
y2 = np.add(x, -0.3)**2 # Parabola centered at 0.3
You can choose your own offsets for y1 and y2 depending on your needs.
And then it's simply take the min of the two arrays
y_final = np.minimum(y1, y2)
plt.plot(x, y_final, '--')
This involves curve fitting. You need to find the intersection part before you drop the values. Since the values of x and y have been normalized, we would have to determine exactly where the two datasets meet. We can see that they meet when x[i] >x[i+1]. Using your cobined xx and yy from the data provided, We therefore can do the following:
data_intersect = int(np.where(np.r_[0,np.diff(xx)] < 0)[0])
x1 = xx[:data_intersect]
x2 = xx[data_intersect:]
y1 = yy[:data_intersect]
y2 = yy[data_intersect:]
difference = np.polyfit(x1, y1, 2) - np.polyfit(x2,y2,2)
meet = np.roots(difference) # all points where the two curves meet
meet = meet[(meet < max(x1)) & (meet >min(x1))] # only point curve meet
xxx = np.r_[x1[x1<meet], x2[x2>meet]]
yyy = np.r_[y1[x1<meet], y2[x2>meet]]
plt.plot(xxx, yyy, '--')
I implemented logistic regression and use it on a data set. (This is an exercise in Coursera's ML course Week #3 (which normally uses matlab and octave) using python (so this isn't cheating)).
I started with the implementation in sklearn to classify the data set used in week three of this course (http://pastie.org/10872959). Here is a small, reproducible example for anyone to try out what I used (it relies only on numpy and sklearn):
It takes the data set, splits it into the feature matrix and the output matrix, and then constructs 26 more features from the original 2 (i.e from
). I then use logistic regression in sklearn, but this does not give the contour plot desired (please see below).
from sklearn.linear_model import LogisticRegression as expit
import numpy as np
def thetaFunc(y, theta, x):
deg = 6
spot = 0
sum = 0
for i in range(1, deg + 1):
for j in range(i + 1):
sum += theta[spot] * x**(i - j) * y**(j)
spot += 1
return sum
def constructVariations(X, deg):
features = np.zeros((len(X), 27))
spot = 0
for i in range(1, deg + 1):
for j in range(i + 1):
features[:, spot] = X[:,0]**(i - j) * X[:,1]**(j)
spot += 1
return features
if __name__ == '__main__':
data = np.loadtxt("ex2points.txt", delimiter = ",")
X,Y = np.split(data, [len(data[0,:]) - 1], 1)
X = reg.constructVariations(X, 6)
oneArray = np.ones((len(X),1))
X = np.hstack((oneArray, X))
trial = expit(solver = 'sag')
trial = trial.fit(X = X,y = np.ravel(Y))
print(trial.coef_)
# everything below has been edited in
from matplotlib import pyplot as plt
txt = open("RegLogTheta", "r").read()
txt = txt.split()
theta = np.array(txt, float)
x = np.linspace(-1, 1.5, 100)
y = np.linspace(-1,1.5,100)
z = np.empty((100,100))
xx,yy = np.meshgrid(x,y)
for i in range(len(x)):
for j in range(len(y)):
z[i][j] = thetaFunc(yy[i][j], theta, xx[i][j])
plt.contour(xx,yy,z, levels = [0])
plt.show()
Here are the coefficients of the generic feature terms.
http://pastie.org/10872957 (i.e the coefficients to terms
and the contour it generates:
One potential source of error is that I'm misinterpreting the 7 X 4 matrix coefficient matrix stored in trial._coeff. I believe that these 28 values are the coefficients to the 28 "variations" above, and I've mapped the coefficients to the variations both column-wise and row-wise. By column-wise, I mean that [:][0] get mapped to the first 7 variations, [:][1] to the next 7 and so on, and my function constructVariations explains how the variations are systematically created. Now the API maintains than an array of shape (n_classes, n_features) is stored in trial._coeff, so should I infer that fit classified the data into four classes? Or have I run through this problem poorly in another way?
Update
My interpretation (and/or use) of the weights must be at fault:
Instead of relying on the prediction built into sklearn, I myself tried to calculate the values that set the following to 1/2
The values of theta are those found from printing trial._coeff and x and y are scalars. Those x,y are then plotted to give the contour.
The code I used (but did not originally add in) attempts to do this. What is wrong with the math behind it?
One potential source of error is that I'm misinterpreting the 7 X 4 matrix coefficient matrix stored in trial._coeff
This matrix is not 7x4, it is 1x28 (check print(trial.coef_.shape)). One coefficient for each of your 28 features (27 returned by constructVariations and 1 added manually).
so should I infer that fit classified the data into four classes?
No, you missinterpreted the array, it has a single row (for binary classificaation there is no point in having two).
Or have I run through this problem poorly in another way?
Code is fine, interpretation not. In particular, see actual decision boundary from your model (plotted by calling "predict" and plotting contour)
from sklearn.linear_model import LogisticRegression as expit
import numpy as np
def constructVariations(X, deg):
features = np.zeros((len(X), 27))
spot = 0
for i in range(1, deg + 1):
for j in range(i + 1):
features[:, spot] = X[:,0]**(i - j) * X[:,1]**(j)
spot += 1
return features
if __name__ == '__main__':
data = np.loadtxt("ex2points.txt", delimiter = ",")
X,Y = np.split(data, [len(data[0,:]) - 1], 1)
rawX = np.copy(X)
X = constructVariations(X, 6)
oneArray = np.ones((len(X),1))
X = np.hstack((oneArray, X))
trial = expit(solver = 'sag')
trial = trial.fit(X = X,y = np.ravel(Y))
print(trial.coef_)
from matplotlib import pyplot as plt
h = 0.01
x_min, x_max = rawX[:, 0].min() - 1, rawX[:, 0].max() + 1
y_min, y_max = rawX[:, 1].min() - 1, rawX[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
data = constructVariations(np.c_[xx.ravel(), yy.ravel()], 6)
oneArray = np.ones((len(data),1))
data = np.hstack((oneArray, data))
Z = trial.predict(data)
Z = Z.reshape(xx.shape)
plt.figure()
plt.scatter(rawX[:, 0], rawX[:, 1], c=Y, linewidth=0, s=50)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.show()
Update
In the code provided you forgot (in visualization) that you added column of "1"s to your data representation, thus your thetas are one "off", as theta[0] is a bias, theta1 is related to your 0'th variable etc.
def thetaFunc(y, theta, x):
deg = 6
spot = 0
sum = theta[spot]
spot += 1
for i in range(1, deg + 1):
for j in range(i + 1):
sum += theta[spot] * x**(i - j) * y**(j)
spot += 1
return sum
you also forgot about intercept term from logisticregression itself, thus
xx,yy = np.meshgrid(x,y)
for i in range(len(x)):
for j in range(len(y)):
z[i][j] = thetaFunc(yy[i][j], theta, xx[i][j])
z -= trial.intercept_
(image generated using fixed code of yours)
import numpy as np
from sklearn.linear_model import LogisticRegression as expit
def thetaFunc(y, theta, x):
deg = 6
spot = 0
sum = theta[spot]
spot += 1
for i in range(1, deg + 1):
for j in range(i + 1):
sum += theta[spot] * x**(i - j) * y**(j)
spot += 1
return np.exp(-sum)
def constructVariations(X, deg):
features = np.zeros((len(X), 27))
spot = 0
for i in range(1, deg + 1):
for j in range(i + 1):
features[:, spot] = X[:,0]**(i - j) * X[:,1]**(j)
spot += 1
return features
if __name__ == '__main__':
data = np.loadtxt("ex2points.txt", delimiter = ",")
X,Y = np.split(data, [len(data[0,:]) - 1], 1)
X = constructVariations(X, 6)
rawX = np.copy(X)
oneArray = np.ones((len(X),1))
X = np.hstack((oneArray, X))
trial = expit(solver = 'sag')
trial = trial.fit(X = X,y = np.ravel(Y))
from matplotlib import pyplot as plt
theta = trial.coef_.ravel()
x = np.linspace(-1, 1.5, 100)
y = np.linspace(-1,1.5,100)
z = np.empty((100,100))
xx,yy = np.meshgrid(x,y)
for i in range(len(x)):
for j in range(len(y)):
z[i][j] = thetaFunc(yy[i][j], theta, xx[i][j])
z -= trial.intercept_
plt.contour(xx,yy,z > 1,cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(rawX[:, 0], rawX[:, 1], c=Y, linewidth=0, s=50)
plt.show()
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)
I'm required to take a Python module for my course and I get this error for my script. It's plotting the trajectory of a projectile and calculating a few other variables. I've typed the script exactly as in the booklet we are given.
Because I am an absolute beginner I can't understand other answers to this error. I would appreciate it an awful lot if someone could give me a quick fix, I don't have time at the moment to learn enough to fix it myself.
Code:
import matplotlib.pyplot as plt
import numpy as np
import math # need math module for trigonometric functions
g = 9.81 #gravitational constant
dt = 1e-3 #integration time step (delta t)
v0 = 40 # initial speed at t = 0
angle = math.pi/4 #math.pi = 3.14, launch angle in radians
time = np.arange(0,10,dt) #time axis
vx0 = math.cos(angle)*v0 # starting velocity along x axis
vy0 = math.sin(angle)*v0 # starting velocity along y axis
xa = vx0*time # compute x coordinates
ya = -0.5*g*time**2 + vy0*time # compute y coordinates
fig1 = plt.figure()
plt.plot(xa, ya) # plot y versus x
plt.xlabel ("x")
plt.ylabel ("y")
plt.ylim(0, 50)
plt.show()
def traj(angle, v0): # function for trajectory
vx0 = math.cos(angle) * v0 # for some launch angle and starting velocity
vy0 = math.sin(angle) * v0 # compute x and y component of starting velocity
x = np.zeros(len(time)) #initialise x and y arrays
y = np.zeros(len(time))
x[0], y[0], 0 #projecitle starts at 0,0
x[1], y[1] = x[0] + vx0 * dt, y[0] + vy0 * dt # second elements of x and
# y are determined by initial
# velocity
i = 1
while y[i] >= 0: # conditional loop continuous until
# projectile hits ground
x[i+1] = (2 * x[i] - x[i - 1]) # numerical integration to find x[i + 1]
y[i+1] = (2 * y[i] - y[i - 1]) - g * dt ** 2 # and y[i + 1]
i = [i + 1] # increment i for next loop
x = x[0:i+1] # truncate x and y arrays
y = y[0:i+1]
return x, y, (dt*i), x[i] # return x, y, flight time, range of projectile
x, y, duration, distance = traj(angle, v0)
print "Distance:" ,distance
print "Duration:" ,duration
n = 5
angles = np.linspace(0, math.pi/2, n)
maxrange = np.zeros(n)
for i in range(n):
x,y, duration, maxrange [i] = traj(angles[i], v0)
angles = angles/2/math.pi*360 #convert rad to degress
print "Optimum angle:", angles[np.where(maxrange==np.max(maxrange))]
The error explicitly:
File "C:/Users/***** at *****", line 52, in traj
x = x[0:i+1] # truncate x and y arrays
TypeError: can only concatenate list (not "int") to list
As is pointed out in the comments, this is the offending line
i = [i + 1] # increment i for next loop
Here, i is not actually being incremented as the comment suggests. When i is 1, it's being set to [1 + 1], which evaluates to [2], the list containing only the number 2. Remove the brackets.
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).