from __future__ import print_function

import math
import csv
from IPython import display
from matplotlib import cm
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
from sklearn import metrics
import tensorflow as tf
from tensorflow.python.data import Dataset

#tf.logging.set_verbosity(tf.logging.ERROR)
pd.options.display.max_rows = 10
pd.options.display.float_format = '{:.1f}'.format

def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):
    features = {key:np.array(value) for key, value in dict(features).items()}

    ds = Dataset.from_tensor_slices((features,targets))
    ds = ds.batch(batch_size).repeat(num_epochs)

    if shuffle:
        ds = ds.shuffle(buffer_size=10000)

    features, labels = ds.make_one_shot_iterator().get_next()
    return features, labels

#Load Dataset
machine_info = pd.read_csv("/home/b/Downloads/microsoft-malware-prediction/train.csv")
print(machine_info.head())

#machine_info.describe()
#print(machine_info.dtypes)

unique_vals = {}

for col in machine_info:
    unique_vals[col] = machine_info[col].unique()
    #print(unique_vals[col])

#unique_df = pd.DataFrame.from_dict(data=unique_vals, orient='index')
#unique_df.to_csv('dict_file.csv', header=False)

machine_info = machine_info.reindex(np.random.permutation(machine_info.index))

#Define input Feature
myFeature = machine_info[["Census_TotalPhysicalRAM"]]

#Configure a numeric feature column for EngineVersion.
feature_columns = [tf.feature_column.numeric_column("Census_TotalPhysicalRAM")]

#Define the Label
targets = machine_info["HasDetections"]

my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.00000001)
my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)

linear_regressor = tf.estimator.LinearRegressor(feature_columns=feature_columns, optimizer=my_optimizer)

#TRAIN THE MODEL

_ = linear_regressor.train(input_fn = lambda:my_input_fn(myFeature, targets), steps = 100)

#EVALUATE THE MODEL

prediction_input_fn = lambda: my_input_fn(myFeature, targets, num_epochs=1, shuffle=False)

predictions = linear_regressor.predict(input_fn=prediction_input_fn)

predictions = np.array([item['predictions'][0] for item in predictions])

mean_squared_error = metrics.mean_squared_error(predictions, targets)
root_mean_squared_error = math.sqrt(mean_squared_error)
print("Mean Squared Error (on training data): %0.3f" % mean_squared_error)
print("Root Mean Squared Error (on training data): %0.3f" % root_mean_squared_error)
