I have this program that I’ve done that gives the user a survey and saves their answers to different files for different political parties. The program is supposed to learn by using the previous answers from previous surveys to calculate the probability of the party the user belongs to before the user finishes the survey. I’ve got it working right now, but I have a sticky situation where some beliefs overlap between a couple of different parties. For example, Socialists and Democrats both believe in Climate Change. But there are also stark differences on some issues, for example Libertarians don’t believe in paying taxes at all, and Republicans believe in lower taxes. I would like to improve my program by assigning numerical weights to the answer choices so that way the program can factor that into the probability calculations and make better guesses faster. Like in the Libertarian-Republican tax example, the Libertarian no tax answer would have a different weight that would tell the program that the user is more likely to be a Libertarian. I want the program to be able to figure out and adjust the weights for itself.
public class Main {
public static void main(String[] args) {
Map<PoliticalParty, ProbabilityManager> probabilityManagerMap = new HashMap<>();
probabilityManagerMap.put(PoliticalParty.REPUBLICAN, new ProbabilityManager(PoliticalParty.REPUBLICAN, 0.25));
probabilityManagerMap.put(PoliticalParty.DEMOCRAT, new ProbabilityManager(PoliticalParty.DEMOCRAT, 0.25));
probabilityManagerMap.put(PoliticalParty.SOCIALIST, new ProbabilityManager(PoliticalParty.SOCIALIST, 0.25));
probabilityManagerMap.put(PoliticalParty.LIBERTARIAN, new ProbabilityManager(PoliticalParty.LIBERTARIAN, 0.25));
Map<String, Integer> answerNumbers = new HashMap<>();
answerNumbers.put("a", 1);
answerNumbers.put("b", 2);
answerNumbers.put("c", 3);
Survey survey = new Survey();
SurveyUserInput userInputCheck = new SurveyUserInput(answerNumbers);
String userInput = "";
Map<Integer, Integer> answerIndices = new HashMap<>();
ProbabilityCalculator cal = new ProbabilityCalculator(probabilityManagerMap);
int answerNumber = 0;
String user = "";
Scanner s = new Scanner(System.in);
SurveyManager.printProb(probabilityManagerMap);
SurveyManager surv = new SurveyManager();
for(int i = 0; i<survey.surveyComponentArray.length; i++) {
SurveyManager.printProb(probabilityManagerMap);
System.out.println(surv.printGuess(probabilityManagerMap));
SurveyComponent c = survey.getQuestion(i);
answerNumber = userInputCheck.performSurvey(i, c);
answerIndices.put(i, answerNumber);
cal.recalculate(i, answerNumber);
}
PoliticalParty party = userInputCheck.askParty();
probabilityManagerMap.get(party).saveAnswerIndices(answerIndices);
}
}
public class SurveyUserInput {
Map<String, Integer> mapKey;
public SurveyUserInput(Map<String, Integer> mapKey) {
this.mapKey = mapKey;
}
Scanner scanner = new Scanner(System.in);
Survey survey = new Survey();
public int performSurvey(int questionNumber, SurveyComponent com) {
String user = "";
int a;
System.out.println(com.question);
for(String answer : com.getAnswers()) {
System.out.println(answer);
}
do {
user = scanner.next().toLowerCase();
} while(!user.equals("a") && !user.equals("b") && !user.equals("c"));
a = mapKey.get(user);
return a;
}
public PoliticalParty askParty() {
String userInput = "";
System.out.println("What party? nA) Republican nB) Democrat nC)Libertarian nD) Socialist");
do {
userInput = scanner.next().toLowerCase();
} while(!userInput.equals("a") && !userInput.equals("b") && !userInput.equals("c") && !userInput.equals("d"));
int index = userInput.codePointAt(0) - 'a';
return PoliticalParty.values()[index];
}
}
public class SurveyFileIO {
public static void writeToFile(String fileName, Map<Integer, Integer> answerList) {
try {
File file = new File(fileName + ".txt");
if(!file.exists()) {
file.createNewFile();
}
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(file));
for(Map.Entry<Integer, Integer> answer : answerList.entrySet()) {
int key = answer.getKey();
int value = answer.getValue();
fileWriter.append(key + "=" + value);
fileWriter.newLine();
}
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Map<Integer, Integer> readFromFile(String fileName) {
Map<Integer, Integer> fileContents = new HashMap<>();
try {
File file = new File(fileName + ".txt");
if(file.exists()) {
BufferedReader fileReader = new BufferedReader(new FileReader(fileName + ".txt"));
String line;
while((line = fileReader.readLine()) != null) {
String[] parts = line.split("=") ;
if(parts.length == 2) {
int key = Integer.parseInt(parts[0]);
int value = Integer.parseInt(parts[1]);
fileContents.put(key, value);
}
}
fileReader.close();
} else {
fileContents.put(0, 0);
}
} catch(IOException e) {
e.printStackTrace();
}
return fileContents;
}
}
public class SurveyComponent {
String question;
String[] answers;
SurveyComponent(String question, String...answers) {
this.question = question;
this.answers = answers;
}
public String[] getAnswers() {
return answers;
}
}
public class Survey {
SurveyComponent[] surveyComponentArray;
public Survey() {
surveyComponentArray = new SurveyComponent[10];
surveyComponentArray = new SurveyComponent[10];
surveyComponentArray[0] = new SurveyComponent("How do you feel about the issue of guns?",
"A) I believe in the 2nd Amendment completely.", "B) I believe in gun control",
"C) I don't care");
surveyComponentArray[1] = new SurveyComponent("How do you feel about the USA's involvement in with other nations?",
"A) I believe we should focus on America.", "B) I believe we need to be involved.",
"C) I don't even believe in foregin aid.");
//etc. for all the questions
}
public SurveyComponent getQuestion(int index) {
return surveyComponentArray[index];
}
}
public class SurveyManager {
public PoliticalParty printGuess(Map<PoliticalParty, ProbabilityManager> proMap) {
double maxProb = Double.NEGATIVE_INFINITY;
PoliticalParty most = null;
for(Map.Entry<PoliticalParty, ProbabilityManager> entry : proMap.entrySet()) {
ProbabilityManager pro = entry.getValue();
double partyProbability = pro.getProbability();
if(partyProbability > maxProb) {
maxProb = partyProbability;
most = entry.getKey();
}
}
return most;
}
public static void printProb(Map<PoliticalParty, ProbabilityManager> proMap) {
for(PoliticalParty party : PoliticalParty.values()) {
System.out.println(party.name() + new DecimalFormat("0.00").format(proMap.get(party).getProbability()*100));
}
}
}
public class ProbabilityManager {
public PoliticalParty party;
private double partyProbability;
private String fileName;
private Map<Integer, Integer> previousSurveyData;
public ProbabilityManager(PoliticalParty party, double partyProbability) {
this.party = party;
this.partyProbability = partyProbability;
this.fileName = party.name().toLowerCase();
previousSurveyData=SurveyFileIO.readFromFile(
fileName);
}
public void setProbability(double partyProbability) {
this.partyProbability = partyProbability;
}
public double getProbability() {
return partyProbability;
}
public double calculateProbOfAnswerGivenParty(int questionNumber, int answerNumber) {
int counter = 0;
if((previousSurveyData.containsKey(questionNumber)) && previousSurveyData.get(questionNumber) == answerNumber) {
counter++;
} else {
return (double)counter;
}
return (double)counter / previousSurveyData.size();
}
public void saveAnswerIndices(Map<Integer, Integer> answerIndices) {
for(Map.Entry<Integer, Integer> entry : answerIndices.entrySet()) {
int key = entry.getKey();
int value = entry.getValue();
this.previousSurveyData.put(key, value);
}
SurveyFileIO.writeToFile(fileName, previousSurveyData);
}
}
public class ProbabilityCalculator {
private final Map<PoliticalParty, ProbabilityManager> partyMap;
public ProbabilityCalculator(Map<PoliticalParty, ProbabilityManager> partyMap) {
this.partyMap = partyMap;
}
public void recalculate(int questionNumber, int answerNumber) {
double totalProb = 0;
Map<PoliticalParty, Double> probOfAnswerGivenParty = new HashMap<>();
for(PoliticalParty party : PoliticalParty.values()) {
ProbabilityManager probManager = partyMap.get(party);
if(probManager != null) {
double probOfAnsGivenP = probManager.calculateProbOfAnswerGivenParty(questionNumber, answerNumber);
totalProb += probManager.getProbability() * probOfAnsGivenP;
probOfAnswerGivenParty.put(party, probOfAnsGivenP);
} else {
System.out.println("no");
}
}
for(PoliticalParty party : PoliticalParty.values()) {
ProbabilityManager probManager = partyMap.get(party);
double probOfPartyGivenANS = probManager.getProbability() * probOfAnswerGivenParty.get(party) / totalProb;
probManager.setProbability(probOfPartyGivenANS);
}
}
}
public enum PoliticalParty {
REPUBLICAN,
DEMOCRAT,
LIBERTARIAN,
SOCIALIST
}
I was thinking about trying to set the weights up in the ProbabilityManager class. The thing I’m having the most trouble with is how to set up the weights for what I’m calling the “deciding answers”. That is, the answers that ONLY a Libertarian or ONLY a Socialist would choose, like my tax example.
I would really appreciate some help.
Thanks! 🙂