import csv #csv module
import random
import math
def loadCsv(filename):
	print('loading data.....')
	lines = csv.reader(open(filename, "r"))#read dataset
	dataset = list(lines)  #list datatype
	del dataset[0]
	for i in range(len(dataset)):
		dataset[i] = [float(x) for x in dataset[i]]
	return dataset

def splitDataset(dataset, splitRatio):
	print('split dataset.....')
	trainSize = int(len(dataset) * splitRatio)
	trainSet = []
	copy = list(dataset)
	while len(trainSet) < trainSize:
		index = random.randrange(len(copy))#generate a random number
		trainSet.append(copy.pop(index))#pop this number in copy set and append it into trainSet
	return [trainSet, copy]
	
def separateByClass(dataset):
	print('separate dataset.....')
	separated = {}
	for i in range(len(dataset)):
		vector = dataset[i]
		if (vector[0] not in separated):
			separated[vector[0]] = []
		separated[vector[0]].append(vector)
	return separated
	
def mean(numbers):
	return sum(numbers)/float(len(numbers))
	
def stdev(numbers):
	avg = mean(numbers)
	variance = sum([pow(x-avg,2) for x in numbers])/float(len(numbers)-1)
	return math.sqrt(variance)

def summarize(dataset):
	summaries = [(mean(attribute), stdev(attribute)) for attribute in zip(*dataset)]
	del summaries[0]
	return summaries

def summarizeByClass(dataset):
	separated = separateByClass(dataset)
	summaries = {}
	for classValue, instances in separated.items():
		summaries[classValue] = summarize(instances)
	return summaries

def calculateProbability(x, mean, stdev):
	if(stdev==0):
		return 1
	else:
		exponent = math.exp(-(math.pow(x-mean,2)/(2*math.pow(stdev,2))))
		return (1 / (math.sqrt(2*math.pi) * stdev)) *exponent

def calculateClassProbabilities(summaries, inputVector):
	probabilities = {}
	for classValue, classSummaries in summaries.items():
		probabilities[classValue] = 1
		for i in range(len(classSummaries)):
			mean, stdev = classSummaries[i]
			x = inputVector[i]
			probabilities[classValue] *= calculateProbability(x, mean, stdev)
	return probabilities
 
def predict(summaries, inputVector):
	probabilities = calculateClassProbabilities(summaries, inputVector)
	bestLabel, bestProb = None, -1
	for classValue, probability in probabilities.items():
		if bestLabel is None or probability > bestProb:
			bestProb = probability
			bestLabel = classValue
	return bestLabel

def getPredictions(summaries, testSet):
	predictions = []
	for i in range(len(testSet)):
		result = predict(summaries, testSet[i])
		predictions.append(result)
	return predictions

def getAccuracy(testSetlabel, predictions):
	print('calculate Accuracy.....')
	correct = 0
	for x in range(len(testSetlabel)):
		if testSetlabel[x] == predictions[x]:
			correct += 1
	return (correct/float(len(testSetlabel)))*100.0

 	
def main():
    filename = 'train.csv'
    #filename2 ='sampletest.csv'
    #filename3 ='sampletestlabel.csv'
    splitRatio=0.67
    #filename2 ='test.csv'
    dataset= loadCsv(filename)
    #print(dataset)
    #testSet = loadCsv(filename2)
    #testSetlabel=loadCsv(filename3)
    trainingSet, testSet = splitDataset(dataset, splitRatio)
    print(len(dataset), len(trainingSet), len(testSet))
    #print(testSet)
    # prepare model
    testSetlabel = []
    for x in range(len(testSet)):
         testSetlabel.append(testSet[x][0])
         del testSet[x][0]
    summaries = summarizeByClass(trainingSet)
    #print(summaries)
    #print(testSetlabel)
    #print(testSet)
	# test model
    predictions = getPredictions(summaries, testSet)
    #print(predictions)
    accuracy = getAccuracy(testSetlabel, predictions)
    print(accuracy)

main()
