# load neccessary library
library(jsonlite);
library(tm);
library(SnowballC);

# load data
train_raw <- fromJSON("../input/train.json", flatten = TRUE);
test_raw <- fromJSON("../input/test.json", flatten = TRUE);

# check out the kinds of cuisines and compute the prior
cuisine_category <- unique(train_raw$cuisine);
cuisine_category_code <- as.integer(as.factor(cuisine_category));
prior <- as.numeric(prop.table(table(train_raw$cuisine)));
# barplot(table(train_raw$cuisine), main = "cuisines", xlab = "cuisine", ylab = "counts");

# construct the document-term matrix for train data
# ingredients <- train_raw$ingredients;
# for(i in 1:length(train_raw$ingredients))
# {
# 	for(j in 1:length(train_raw$ingredients[[i]]))
# 	{
# 		ingredients[[i]][j] <- gsub(" ", "-", train_raw$ingredients[[i]][j]);         # 构造词项矩阵时可以考虑先在ingredients的每一个词之间加上一条短线
# 	}
# }
train_ingredients <- Corpus(VectorSource(train_raw$ingredients));
train_ingredients <- tm_map(train_ingredients, stemDocument);
train_ingredientsDTM <- DocumentTermMatrix(train_ingredients);
train_sparse <- removeSparseTerms(train_ingredientsDTM, 0.99);
train_ingredientsDTM <- as.data.frame(as.matrix(train_sparse));
# train_ingredientsDTM <- as.data.frame(as.matrix(train_ingredientsDTM));

train_ingredients_name <- names(train_ingredientsDTM);
train_ingredientsDTM$cuisine <- as.integer(as.factor(train_raw$cuisine));

# construct the condition probability matrix
condition_prob_matrix <- data.frame(train_ingredients_name);
for(i in 1:length(cuisine_category_code))
{
	df <- train_ingredientsDTM[which(train_ingredientsDTM$cuisine == i),];
	df_ingredients_counts <- colSums(df)[1:dim(df)[2] - 1];
	cuisine_name <- cuisine_category[which(cuisine_category_code == i)];
	condition_prob_matrix <- data.frame(cbind(condition_prob_matrix, as.numeric(df_ingredients_counts) / (dim(df)[1])));
	condition_prob_matrix_names <- names(condition_prob_matrix);
	condition_prob_matrix_names[i + 1] <- cuisine_name;
	names(condition_prob_matrix) <- condition_prob_matrix_names;
}

# construct the document-term matrix for test data
test_ingredients <- Corpus(VectorSource(test_raw$ingredients));
test_ingredients <- tm_map(test_ingredients, stemDocument);
test_ingredientsDTM <- DocumentTermMatrix(test_ingredients);
test_sparse <- removeSparseTerms(test_ingredientsDTM, 0.99);
test_ingredientsDTM <- as.data.frame(as.matrix(test_sparse));

test_ingredients_name <- names(test_ingredientsDTM);

# classify new cuisine according to the ingredients
test_cuisines <- c();
for(i in 1:dim(test_ingredientsDTM)[1])
{
	probability <- 0;
	test_terms <- test_ingredients_name[which(test_ingredientsDTM[i,] != 0)];
	terms_match <- intersect(test_terms, train_ingredients_name);
	if(length(terms_match) < 1)
	{
		test_cuisines[i] <- "italian";
	}
	else
	{
		for(k in 1:length(cuisine_category_code))
		{
			match_probs <- condition_prob_matrix[match(terms_match, train_ingredients_name), k + 1];
			match_probs[which(match_probs == 0)] <- 0.0001;
			tmp_probability <- prior[k] * prod(match_probs);
			if(tmp_probability > probability)
			{
				probability <- tmp_probability;
				tmp_cuisine <- k;
			}
		}
		test_cuisines[i] <- cuisine_category[which(cuisine_category_code == tmp_cuisine)];
	}
}

result <- data.frame(id = test_raw$id, cuisine = test_cuisines);
write.csv(result, "result.csv", quote = FALSE, row.names = FALSE);