A programming + Statistics Question:
Context:
I am currently building a model simulation (an agent-based model) where each agent (read: person) as a series of variables (i.e. gender, race, martial status, income bracket, education, etc).
This is not a homework question, it's a problem I am trying to solve for work so I do not have to hard code everything, and will make implementing changes to my model much easier and faster.
The variables essentially break down as follows:
gender: 0 = female, 1 = male
race: 1 = white, 2 = black, 3 = hispanic, 4 = other
marital status: 1 = married, 2 = divorced, 3 = no married
income: 1 = <20k, 2 = 20k-75k, 3= 75+k
education: 1 = <HS, 2 = HS, 3 = >HS
In my dataset I want to predict, for example, smoking status (0 = non-smoker, 1 = smoker).
Easy, do a logistic regression. Programming in the main effects would not be too difficult since the population model would be as follows:
SmokingStatus = b_0 + b_1(gender1) + b_2(race2) + b_3(race3) + b_4(race4) + ... + e
Problem 1:
As you can see from the equation above, categorical variables create k-1 dummy variables. Essentially the stats program will create the following dummy variables (using race as an example): race2, race3, race4. and each will have a beta estimate (that is the ln(OR) relative to the reference group, race1).
Question 1:
How would I write my java program to calculate the probability of smoking status from the regression output (the tables I have are SAS ouputs), without creating the corresponding dummy variables in my agent class.
Problem 2:
This problem gets even worse when I have interaction terms in my model, since the parameter estimates are the combinations of each variable's dummy-variable. For example, in above population model + an interaction term between gender and race would be:
SmokingStatus = b_0 + b_1(gender1) + b_2(race2) + b_3(race3) + b_4(race4) + B_5(gender1race2) + B_6(gender1race3) + B_7(gender1race4) ... + e
Question 2:
Given this added complexity, what would be the best approach?
My ultimate goal:
I am trying to write a java program that will take in a (csv) file of variables and their parameter estimates, and essentially 'plug in the values' to generate a probability for my response variable (e.g. smoking status).
Yes I know after I plug in all the values I will have to transform my answer via:
Math.exp(logitP)/(1 + Math.exp(logitP))
My current (and terrible) solution involves initializing all the dummy variables to 0, then doing a series of if statements to assign a value of 1, then multiplying all the dummies by the corresponding beta estimate (many of the terms will equate to 0)
for example:
int race2 = 0;
int race3 = 0;
int race4 = 0;
int sex0 = 0;
// race
if (alcoholAgent.getRace() == 2) {race2 = 1;}
else if (alcoholAgent.getRace() == 3) {race3 = 1;}
else if (alcoholAgent.getRace() == 4) {race4 = 1;}
// sex female is reference group == 0
if (alcoholAgent.getGender() == 1) {sex0 = 1;}
// age2-6_race2-4
if ((alcoholAgent.getAgeCat() == 2) && (alcoholAgent.getRace()==2)) {age2race2 = 1;}
else if ((alcoholAgent.getAgeCat() == 2) && (alcoholAgent.getRace()==3)) {age2race3 = 1;}
else if ((alcoholAgent.getAgeCat() == 2) && (alcoholAgent.getRace()==4)) {age2race4 = 1;}
else if ((alcoholAgent.getAgeCat() == 3) && (alcoholAgent.getRace()==2)) {age3race2 = 1;}
else if ((alcoholAgent.getAgeCat() == 3) && (alcoholAgent.getRace()==3)) {age3race3 = 1;}
else if ((alcoholAgent.getAgeCat() == 3) && (alcoholAgent.getRace()==4)) {age3race4 = 1;}
else if ((alcoholAgent.getAgeCat() == 4) && (alcoholAgent.getRace()==2)) {age4race2 = 1;}
else if ((alcoholAgent.getAgeCat() == 4) && (alcoholAgent.getRace()==3)) {age4race3 = 1;}
else if ((alcoholAgent.getAgeCat() == 4) && (alcoholAgent.getRace()==4)) {age4race4 = 1;}
else if ((alcoholAgent.getAgeCat() == 5) && (alcoholAgent.getRace()==2)) {age5race2 = 1;}
else if ((alcoholAgent.getAgeCat() == 5) && (alcoholAgent.getRace()==3)) {age5race3 = 1;}
else if ((alcoholAgent.getAgeCat() == 5) && (alcoholAgent.getRace()==4)) {age5race4 = 1;}
else if ((alcoholAgent.getAgeCat() == 6) && (alcoholAgent.getRace()==2)) {age6race2 = 1;}
else if ((alcoholAgent.getAgeCat() == 6) && (alcoholAgent.getRace()==3)) {age6race3 = 1;}
else if ((alcoholAgent.getAgeCat() == 6) && (alcoholAgent.getRace()==4)) {age6race4 = 1;}
Any model which makes use of the numerical values of categorical variables is misleading at best. In what sense is race=2 "greater than" race=1? In no sense, of course. My advice is to dump the logistic regression.
Since there is no real ordering of the categorical variables, the best you can do is a look-up table. Just make a multidimensional table indexed by the categorical variables, and count up examples which fall into each bin in the table to find the proportional of examples in each output category. That proportion is your probability of the output category for that combination of input variables.
A look-up table takes all interactions of variables into account. The disadvantage is that the number of table elements may be very large. You may be able to compute the probability of the output category as a product of probabilities from smaller tables (i.e., with fewer indices per table). This is what is called a "naive Bayes" model; it makes an assumption that input variables (or groups of them) are independent given the output category.
Related
What I need to do is write a program that makes the first character (which is charAt(0) )and the second character (which is charAt(1) ) to become a value that not exceeding 90 which is (0 ~ 90) , but I also have to define them as an independent digit , because my program will make it to invalid if it is other than a digit.
So for an example it will become invalid if I type in 91
and it will valid if I type in number between 0~90
but I have no idea how to do this...
if(Character.isDigit(loop1.charAt(0))&&
Character.isDigit(loop1.charAt(1)))
I have tried this ,but not working
if(Character.isDigit(loop1.charAt(0)) &&
Character.isDigit(loop1.charAt(1)) &&
((loop1 >= 0)&&(loop1 <= 90)))
also this one but this is not working( I have no idea what I'm doing)
if(Character.isDigit(loop1.charAt(0)) &&
(((int)loop1.charAt(0)) >= 0) && <=9
Character.isDigit(loop1.charAt(1)) &&
((int)loop1.charAt(1)) <= 9)
Please help me... thanks a million !
Assuming I understand your question, parse loop1 and test the values using a simple if check, like
int t = Integer.parseInt(loop1);
if (t < 0 || t > 90) {
System.out.println("Value outside accepted range.");
} else {
System.out.println("Value valid.");
}
If I am getting this right you want to convert the first two characters of a string into a number and check is that number bigger than 90. Also you want the digits to be stored in different variables(?). If so this code should do it:
int digit1 = loop1.charAt(0) - '0';
int digit2 = loop1.charAt(1) - '0';
int number = digit1 * 10 + digit2;
if ( number <= 90 && number >= 0 )
System.out.println("Input is good");
else
System.out.println("Input is bad");
Here x1 and v1 are initial position and velocity of car1, and x2 and v2 for car2. I need to find if the two cars meet at any point. It gives me error displaying "No" always.Any suggestions?
if (v1 > v2) {
while ((x1 + (v1 * i)) > (x2 + (v2 * i))) {
if ((x1 + (v1 * i)) == (x2 + (v2 * i))) {
prime = true;
break;
}
System.out.println(""+i);
i++;
}
if (prime == true) {
s = "Yes";
} else {
s = "No";
}
}
if (v2 > v1) {
while ((x2 + (v2 * i)) > (x1 + (v1 * i))) {
if ((x1 + (v1 * i)) == (x2 + (v2 * i))) {
prime = true;
break;
}
System.out.println(""+i);
i++;
}
if (prime == true) {
s = "Yes";
} else {
s = "No";
}
}
if (v1 == v2) {
if (x1 == x2) {
s = "Yes";
} else s = "No";
}
System.out.println(""+s);
}
}
This is a mathematical question not so much a programming one. Basically you don't need any loops and stuff to answer it. I assume (since there are no other implications) that both cars go in the same X direction with speed V where both X and V are positive numbers.
So basically your logic can be -> If the faster car is behind the slower one they will eventually meet. Otherwise they won't. And in this case you won't need any loops. The last check in the example below is if they are already in the same spot.
if((x1<x2 && v1>v2) || (x1>x2 && v1<v2) || (x1==x2)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
If V can be negative (for example to show going backwards which is a bit strange way because velosity cannot be negative) then it is still the same. You might go for a loop only if you want to know the point on the vector X where they met. But with some calculations you can still calculate it without loops. For example :
int vDiff=Math.abs(v1-v2);
int xDiff=Math.abs(x1-x2);
System.out.println("Meeting point: "+(((double)xDiff)/((double)vDiff)*v1+x1));
I think you're complicating the problem, with your iterations you're essentially finding the time step at which the cars meet, if they do meet.
There are actually only five possibilities for these two cars, when considered in one direction:
1) Car 1 is ahead of car 2, and moving faster than or the same speed as car 2 => Cars never meet
2) Car 1 is behind car 2, and moving faster than car 2 => Cars meet
3) Car 1 is ahead of car 2, and moving slower than car 2 => Cars meet
4) Car 1 is behind car 2, and moving slower than or the same speed as car 2 => Cars never meet
5) Cars have already met.
In code this might look like the following:
boolean carsMeet(x1,v1,x2,v2){
boolean output = false;
if(x1 > x2){
// Conditions 1 and 3. Car 1 is ahead of car 2
if (v2 > v1){
// Condition 3
output = true;
}
} else if (x1 < x2){
// Conditions 2 and 4. Car 2 is ahead of car 1
if (v1 > v2){
// Condition 2
output = true;
}
} else {
// Condition 5. Car 1 has already met car 2
output = true;
}
return output;
}
I haven't run this code to check it for syntax errors, but in general this is how I advise tackling the problem, rather than your current approach.
s = "No";
if (x1 == x2) {
s = "Yes";
} else if (v1 == v2) {
s = "No";
} else if ((x2-x1)/(v1-v2) > 0) {
s = "Yes";
}
I'm building a simple fighting game to test out loops and if statements, however I've run into a kind of complex logic issue.
The loop ends when either the player or enemy HP hits zero however I've discovered that my code can't detect which HP hits zero first results in the player always winning.
Is there a simple way of tracking which number hits zero first therefor breaking the loop?
do {
#SuppressWarnings("resource")
Scanner reader = new Scanner(System.in);
System.out.println("1: Attack. 2: Defend");
int n = reader.nextInt();
if (n == 1){
PHP = (PHP-EATK);
EHP = (EHP-PATK);
} else if (n == 2){
PHP = (PHP-Math.max(0, EATK-PDEF));
}
System.out.println("P "+PHP);
System.out.println(EHP);
}
while (PHP >= 1 || EHP >= 1);
if(PHP <= 0){
System.out.println("You Lose!");
}else if (EHP <= 0){
System.out.println("You win!");
}
Look at your loop continuation condition:
while (PHP >= 1 || EHP >= 1)
It means "while the player or his enemy can fight, go on". In other words, you continue fighting until they both die, at which point you declare the player the winner, even though it's a draw.
Changing the condition to ""while the player and his enemy can fight" will fix this problem.
change while (PHP >= 1 || EHP >= 1); to while (PHP >= 1 && EHP >= 1);.
You using OR operation where you want AND
newbie here,
I have two variables which generate random numbers through .Random. I want them keep rolling until both variables generate two different values, simultaneously. Therefore, I'm using while loop with && for this purpose. As I have understood, please correct me if I'm wrong, the line while ((diceRolled1 != 5) && (diceRolled2 != 4)) translates as, keep rolling until the values of diceRolled1 is not equal to 5 AND diceRolled2is not equal to 4. But the program ends if either variable matches its value (diceRolled1 = 5 OR diceRolled2 = 4). This is not what && is supposed to do, right? I have ran the code like 10s of times, but not a single time it generated 5 and 4 at the same time.
I also tried ==on both sides and either side, but in that case the program didn't run at all, nor it gave any error.
Your help will be much appreciated. Thanks
import java.util.Random;
import static java.lang.System.out;
public class DiceRoller {
public static void main(String[] args) {
Random dice1 = new Random();
Random dice2 = new Random(); //Removing this doesn't work either
int diceRolled1 = 0;
int diceRolled2 = 0;
while ((diceRolled1 != 5) && (diceRolled2 != 4)) { //& didn't work either
diceRolled1 = dice1.nextInt(6) + 1;
diceRolled2 = dice2.nextInt(6) + 1;
out.println(diceRolled1 + " " + diceRolled2);
}
out.println("Program ends");
}
}
Your logic is incorrect. The loop will continue as long as both values don't match - as soon as one value matches, the loop exits. We can invert your logic to show this:
while (!(diceRolled1 == 5 || diceRolled2 == 4)) {
which is logically equivalent to what you have.
What you want is this:
while (diceRolled1 != 5 || diceRolled2 != 4) {
which says "Continue while any variable does not have the desired value"
You're getting the logical result you describe, but it wasn't what you expect. Specifically, when either of your conditions evaluates to false the logical and will not evaluate to true. I think you wanted
while (!(diceRolled1 == 5 && diceRolled2 == 4)) {
which is while not dice1 equal to 5 and dice2 equal to 4. And then, using De Morgan's Laws that might also be expressed as
while (diceRolled1 != 5 || diceRolled2 != 4) {
which means loop while dice1 is not equal to 5 or dice2 is not equal to 4.
the while execute the statement untill the condition is true.
In your code the condition is given by (diceRolled1 != 5) && (diceRolled2 != 4).
The && operator require true that all operands be true.
Given this Your loop will end when at least one of the expression will be false.
To finish the program when it generate 5 and 4 you have to use this:
(!(diceRolled1 == 5) && (diceRolled2 == 4))
Yeah,it should be. The program should end if dicerolled is either 5 or 4 because as far as it is not 4 and not 5 it is in while loop. It exits the while loop if only the value is either 4 or 5. So your logic is incorrect. Sorry! :)
Try:
while (!(dicerolled ==4 && dicerolled == 5))
Is it possible to have a statement such as...
if(delco == 1 && heavy < 5)
System.out.println("The total cost of your delivery is: $" + OPT_ONE);
if(delco == 1 && heavy >= 5 && heavy <= 20)
System.out.println("The total cost of your delivery is: $" + OPT_TWO);
...that also applies boolean logic to express an output? Something like this...
boolean overnight;
if(delco == 1 && heavy < 5) && (overnightShip == YES)
System.out.println("The total cost of your delivery is: $" + OPT_ONE + OVERNIGHT);
if(delco == 1 && heavy >= 5 && heavy <= 20) && (overnightShip == NO)
System.out.println("The total cost of your delivery is: $" + OPT_TWO);
I have tried a few variations of this code and the error I'm receiving states that they are incomparable types. How do I go about making them comparable?
You just missed some parentheses, because your logic seems OK. It should be, e.g.:
if ( (delco == 1 && heavy < 5) && (overnightShip == YES) )
...
Note the outer parentheses.
Also that assumes that you've defined YES to be a boolean constant equal to true, and that is redundant, so:
if ( (delco == 1 && heavy < 5) && (overnightShip) )
...
And in this case, those parentheses are redundant as well, and the whole thing simplifies to:
if ( delco == 1 && heavy < 5 && overnightShip )
...
Just use the boolean on its own:
if (delco == 1 && heavy < 5 && overnightShip)
Comparing a boolean "flag" variable with a boolean constant is poor style - always prefer testing the boolean as-is.
Boolean types in Java have the values:
true
false
Not:
YES
NO
unless you have defined these constants yourself somewhere
So your code should look like:
(overnightShip == true)
(overnightShip == false)
or even:
(overnightShip) // true
(! overnightShip) // false