Calculating conditional entropy for a decision tree - java

I'm trying to calculate conditional entropy in order to calculate information gain for decision trees. I'm having a little trouble with the implementation in Java. An example may look like:
X Y f(x)
1 0 A
1 0 A
0 1 B
Given this example, how would I go about calculating conditional entropy in Java? I understand the math behind it but am just confused on the implementation.
An example can be found here: http://en.wikipedia.org/wiki/Conditional_entropy

Conditional entropy for variable Y:
(Probability of Y = 0)(Entropy of f(x) when Y=0) + (Prob. of Y = 1)(Entropy of f(x) when Y=1)
In your example:
(2/3)(-1(2/2*log(2)) + (1/3)*(-1(1/1*log(1)) = (2/3)*0 + (1/3)*0 = 0
i.e. this is a bad example because your conditional entropy is always 0. May be this will help: http://www.onlamp.com/pub/a/php/2005/03/24/joint_entropy.html?page=3

Related

Polynomial Regression values generated too far from the coordinates

As per the the below code for Polynomial Regression coefficients value, when I calculate the regression value at any x point. Value obtained is way more away from the equivalent y coordinate (specially for the below coordinates). Can anyone explain why the difference is so high, can this be minimized or any flaw in understanding. The current requirement is not a difference of more 150 at every point.
import numpy as np
x=[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100]
y=[0,885,3517,5935,8137,11897,10125,13455,14797,15925,16837,17535,18017,18285,18328,18914,19432,19879,20249,20539,20746]
z=np.polyfit(x,y,3)
print(z)
I have also tried various various codes available in java, but the coefficient values are same every where for this data. Please help with the understanding.For example
0.019168 * N^3 + -5.540901 * N^2 + 579.846493 * N + -1119.339450
N equals 5 Value equals 1643.76649Y value 885
N equals 10 Value equals 4144.20338Y value 3517
N equals 100; Value=20624.29985 Y value 20746
The polynomial fit performs as expected. There is no error here, just a great deviation in your data. You might want to rescale your data though. If you add the parameter full=True to np.polyfit, you will receive additional information, including the residuals which essentially is the sum of the square fit errors. See this other SO post for more details.
import matplotlib.pyplot as plt
import numpy as np
x = [0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100]
y = [0,885,3517,5935,8137,11897,10125,13455,14797,15925,16837,17535,18017,18285,18328,18914,19432,19879,20249,20539,20746]
m = max(y)
y = [p/m for p in y] # rescaled y such that max(y)=1, and dimensionless
z, residuals, rank, sing_vals, cond_thres = np.polyfit(x,y,3,full=True)
print("Z: ",z) # [ 9.23914285e-07 -2.67082878e-04 2.79497972e-02 -5.39544708e-02]
print("resi:", residuals) # 0.02188 : quite decent, depending on WHAT you're measuring ..
Z = [z[3] + q*z[2] + q*q*z[1] + q*q*q*z[0] for q in x]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(x,y)
ax.plot(x,Z,'r')
plt.show()
After I reviewed the answer of #Magnus, I reduced the limits used for the data in a 3rd order polynomial. As you can see, the points within my crudely drawn red circle cannot both lie on a smooth line with the nearby data. While I could fit smooth lines such as a Hill sigmoidal equation through the data, the data variance (noise) itself appears to be the limiting factor in achieving a peak absolute error of 150 with this data set.

Find solutions for a set of quadratic equations

I have a set of quadratic equations, like
x² + x + y = 7
x + 3y = -3
y² + x² + z = 11
All coefficients are integers. The set of equations could either have no solution, one solution of a whole set of solutions.
Does anybody know a method to find out whether these equations have a solution?
My first idea was to solve these equations one by one in double and use the results to solve the other equations. The problems are the rounding errors: If, in theory, I have two equations
x + y = 5
x = 5 - y
there would be plenty of solutions. But if my method results in
x + y = 4.999999
x = 5 - y
the system suddenly has no solution. In the next step, I could add epsilons to compensate for rounding errors, but I am not sure how large they should be. Any ideas or better approaches?
PS: The background is to find intersection points of a complicated set of circles and lines in the plane.
Since you have exact input with integers you could use exact algorithms.
You could, for instance, compute a Groebner basis of the polynomials corresponding to your equations, e.g.
x² + x + y - 7
x + 3y + 3
y² + x² + z - 11
With lexicographic ordering of the terms you will get a Groebner basis in a kind of "triangular" form, where the first polynomial contains as few variables as possible, e.g.
81z² - 176z + 92
2y + 9z - 8
2x - 27z + 30
This gives you two real roots for z and unique values for y and x once z is fixed. If the first polynomial of the computed basis does not contain a variable, then your set of equations does not have any solutions. If the first polynomial in the computed bases contains two variables, then you have an infinite number of solutions (possibly complex).
You can experiment with Groebner bases online with Wolfram Alpha (e.g. compute the basis for your example). A Groebner basis can be computed using the Buchberger algorithm, for which a few implementations are available in Java.
Note: the worst case complexity of the Buchberger algorithm is double exponential in the maximal total degree of the input, but in your application this might not matter.

Numerical Solve in Java [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I'm looking to incorporate some sort of implementation of numerical solving for linear algebraic solutions in Java, like this:
5x + 4 = 2x + 3
Ideally, I would prefer to parse as little as possible, and avoid using traditional "human" methods of solutions (i.e. combine like terms, etc). I've been looking into Newton's Method and plugging in values for x to approximate a solution.
I'm having trouble getting it to work though.
Does anyone know the best general way to do this, and how it should be done in code (preferably Java)?
Additional
In Netwon's Method, you iterate until the approximation is to acceptable accuracy. The formula looks like this:
x1 = x0 - (f(x0) / (f '(x0))
where x1 is the next value for x in the iteration, and x0 is the current value (or starting guess if on first iteration).
What is f prime? Assuming f(x0) is the function of your current x estimation, what expression does f'(x0) represent?
Clarification
This is still a question of how to PROGRAM this math evaluation, not simply how to do the math.
f'(x0) is the derivative of f evaluated at x0. You can compute an approximation to f' by evaluating:
f'(x0) ~ (f(x0+epsilon) - f(x0))/epsilon
for a suitably tiny value epsilon (because f is linear, any reasonable value of epsilon will give essentially the same result; for more general functions f the subtlety of choosing a good epsilon to use is entirely too subtle to be discussed in a S.O. post -- enroll in an upper-division undergraduate numerical analysis course).
However, since you want to avoid "human" methods, I should point out that for the specific case of linear equations, Newton's method always converges in a single iteration, and is in fact essentially equivalent to the usual algebraic solution technique.
To illustrate this, consider your example. To use Newton's method, one needs to transform the equation so that it looks like f(x) = 0:
5x + 4 = 2x + 3
5x + 4 - (2x + 3) = 0
So f(x) = 5x + 4 - (2x + 3). The derivative of f(x) is f'(x) = 5 - 2 = 3. If we start with an initial guess x0 = 0, then Newton's method gives us:
x1 = x0 - f(x0)/f'(x0)
= 0 - (5*0 + 4 - (2*0 + 3))/3
= 0 - (4-3)/3
= -1/3
This is actually exactly the same operations that a human would use to solve the equation, somewhat subtly disguised. Taking the derivative isolated the x terms (5x - 2x = 3x), and evaluating at zero isolated the terms without an x (4-3 = 1). Then we divided the constant coefficient by the linear coefficient and negated to get x.
Assuming that you don't want to use some new algorithms or rewrite old algorithms, you can use equation solver.

Minimize complex linear multivariable function in java

I need to minimize a complex linear multivariable function under some constraints.
Let x be an array of complex numbers of length L.
a[0], a[1], ..., a[L-1] are complex coefficients and
F is the complex function F(x)= x[0]*a[0] + x[1]*a[1] + ... + x[L-1]*a[L-1] that has to be minimized.
b[0], b[1], ..., b[L-1] are complex coefficients and there is a constraint
1 = complexConjuate(x[0])*x[0] + complexConjuate(x[1])*x[1] + ... + complexConjuate(x[L-1])*x[L-1] that has to be fulfilled.
I already had a detailed look at http://math.nist.gov/javanumerics/ and went through many documentations. But I couldn't find a library which does minimization for complex functions.
You want to minimize a differentiable real-valued function f on a smooth hypersurface S. If such a minimum exists - in the situation after the edit it is guaranteed to exist because the hypersurface is compact - it occurs at a critical point of the restriction f|S of f to S.
The critical points of a differentiable function f defined in the ambient space restricted to a manifold M are those points where the gradient of f is orthogonal to the tangent space T(M) to the manifold. For the general case, read up on Lagrange multipliers.
In the case where the manifold is a hypersurface (it has real codimension 1) defined (locally) by an equation g(x) = 0 with a smooth function g, that is particularly easy to detect, the critical points of f|S are the points x on S where grad(f)|x is collinear with grad(g)|x.
Now the problem is actually a real (as in concerns the real numbers) problem and not a complex (as in concerning complex numbers) one.
Stripping off the unnecessary imaginary parts, we have
the hypersurface S, which conveniently is the unit sphere, globally defined by (x|x) = 1 where (a|b) denotes the scalar product a_1*b_1 + ... + a_k*b_k, the gradient of g at x is just 2*x
a real linear function L(x) = (c|x) = c_1*x_1 + ... + c_k*x_k, the gradient of L is c independent of x
So there are two critical points of L on the sphere (unless c = 0 in which case L is constant), the points where the line through the origin and c intersects the sphere, c/|c| and -c/|c|.
Obviously L(c/|c|) = 1/|c|*(c|c) = |c| and L(-c/|c|) = -1/|c|*(c|c) = -|c|, so the minimum occurs at -c/|c| and the value there is -|c|.
Each complex variable x can be considered as two real variables, representing the real and imaginary part, respectively, of x.
My recommendation is that you reformulate your objective function and constraint using the real and imaginary parts of each variable or coefficient as independent components.
According to the comments, you only intend to optimize the real part of the objective function, so you can end up with a single objective function subject to optimization.
The constraint can be split into two, where the "real" constraint should equal 1 and the "imaginary" constraint should equal 0.
After having reformulated the optimization problem this way, you should be able to apply any optimization algorithm that is applicable to the reformulated problem. For example, there is a decent set of optimizers in the Apache Commons Math library, and the SuanShu library also contains some optimization algorithms.

isolate real number in complex number in java

There is a formula i need to use for my app : here
the part Sqrt(5-25) , can be positive or negative , and of course when negative we got a imaginary part that java cant handle.
i've searched around to find a complex class to handle that , but found only basic operation (+-*/).
how can i solve this in java knowing i only need to get the real part ?(imaginary have no importance)
i precise that i develop on android platform
(i post on stack because it's concerning application in java , but if its belong to math.se , tell me)
You can simply compute verything before:
plot 25-20+((2Pi0.3²)/(Pi10²)Sqrt[2*980(1+(Pi10²)/(Pi10²))]t)² from 0 to 38
or
plot 25-20+((2*0.3²)/(10²)Sqrt[2*980(1+1)]t)² from 0 to 38
or
25 - 20 + 4 * 0.0000081 * 3920*t^2 from 0 to 38 (I have some factor wrong, but you get the idea)
just apply basic math to the constants and remove the middle (imaginary part) after applying the 2nd binomic formula.
There is nothing to do with complex numbers.
Taking the Square root of a general complex number can be done with the basic arithmetic operations on real numbers (plus taking square root of reals): http://www.mathpropress.com/stan/bibliography/complexSquareRoot.pdf (one technique is to utilise De Moivre's theorem: Any complex number a + bi can be written as r(cos θ + i sin θ) where
r = sqrt(a^2 + b^2), cos θ = a/r, sin θ = b/r
Update: the formula r(cos θ + i sin θ) is originaly due to Euler, whereas De Moivre's theorem is
(a + ib)ⁿ = rⁿ(cos nθ + i sin nθ)
You are confused about the math. Square root of -25 is square root of 25*(-1) and that is square root of 25 * square root of -1 and that is 5i. Real part of that number is 0.
If you want the 5, just check for the sign of the number to be "rooted" and change it if it is negative.
It's not right to say that "Java can't handle it". No language that returns a double from a square root can handle it, but if you have a Complex class it's not an issue. Python has one built in; it's easy to write one in Java.
The square root of an integer is going to be an integer or a complex number whose real part is zero. The real part of the square root of a negative integer is zero. Always.
So ...
public double realPartOfSquareRoot(int i) {
return (i > 0) Math.sqrt(i) : 0;
}
But how I solve this? If I replace the squareroot by 0, I don't get a good result. Do I suppose the imaginary part do something on the real with the rest of the formula.
I expect that's so! (The idea of discarding the imaginary part didn't make much sense to me ... but I assumed you had a sound reason to do this.)
The real answer is to find a Java library that will do complex arithmetic. I've never needed to use it, but the first one to examine should be the Apache Commons Maths library.

Categories

Resources