# access yelp.csv using a relative path
import pandas as pd
yelp = pd.read_csv('/GA-SEA-DAT2/data/yelp.csv')
yelp.head(1)

"""
Explanation: Linear regression homework with Yelp votes
Introduction
This assignment uses a small subset of the data from Kaggle's Yelp Business Rating Prediction competition.
Description of the data:

yelp.json is the original format of the file. yelp.csv contains the same data, in a more convenient format. Both of the files are in this repo, so there is no need to download the data from the Kaggle website.
Each observation in this dataset is a review of a particular business by a particular user.
The "stars" column is the number of stars (1 through 5) assigned by the reviewer to the business. (Higher stars is better.) In other words, it is the rating of the business by the person who wrote the review.
The "cool" column is the number of "cool" votes this review received from other Yelp users. All reviews start with 0 "cool" votes, and there is no limit to how many "cool" votes a review can receive. In other words, it is a rating of the review itself, not a rating of the business.
The "useful" and "funny" columns are similar to the "cool" column.

Task 1
Read yelp.csv into a DataFrame.
End of explanation
"""


# read the data from yelp.json into a list of rows
# each row is decoded into a dictionary named "data" using using json.loads()
import json
import pandas as pd
with open('../data/yelp.json', 'rU') as f:
    data = [json.loads(row) for row in f]

# show the first review
data[0]

# convert the list of dictionaries to a DataFrame
df = pd.DataFrame.from_dict(data, orient='columns')

print(df)

# add DataFrame columns for cool, useful, and funny

df['cool'] = [row['votes']['cool'] for row in data]
df['useful'] = [row['votes']['useful'] for row in data]
df['funny'] = [row['votes']['funny'] for row in data]


# drop the votes column and then display the head

df.drop('votes', axis=1, inplace=True)

"""
Explanation: Task 1 (Bonus)
Ignore the yelp.csv file, and construct this DataFrame yourself from yelp.json. This involves reading the data into Python, decoding the JSON, converting it to a DataFrame, and adding individual columns for each of the vote types.
End of explanation
"""


# treat stars as a categorical variable and look for differences between groups by comparing the means of the groups
df.groupby('stars').mean()

# display acorrelation matrix of the vote types (cool/useful/funny) and stars
%matplotlib inline
import seaborn as sns
sns.heatmap(df.corr())

# display multiple scatter plots (cool, useful, funny) with linear regression line
sns.lmplot(x='cool', y='stars', data=df, ci=95, fit_reg=True)
sns.plt.xlim(-1, 90)
sns.plt.ylim(-1, 10)



sns.lmplot(x='funny', y='stars', data=df, ci=95, fit_reg=True)
sns.plt.xlim(-1, 90)
sns.plt.ylim(-1, 10)


sns.lmplot(x='useful', y='stars', data=df, ci=95, fit_reg=True)
sns.plt.xlim(-1, 90)
sns.plt.ylim(-1, 10)

"""
Explanation: Task 2
Explore the relationship between each of the vote types (cool/useful/funny) and the number of stars.
End of explanation
"""


#feature matrix
feature_cols = ['cool', 'useful', 'funny']
X = df[feature_cols]

#response vector 
response_vector = ['stars']
y = df[response_vector]

"""
Explanation: Task 3
Define cool/useful/funny as the feature matrix X, and stars as the response vector y.
End of explanation
"""


from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X, y)

print reg.intercept_
print reg.coef_

"""
Explanation: Task 4
Fit a linear regression model and interpret the coefficients. Do the coefficients make intuitive sense to you? Explore the Yelp website to see if you detect similar trends.
End of explanation
"""


from sklearn.cross_validation import train_test_split
from sklearn import metrics
import numpy as np

# define a function that accepts a list of features and returns testing RMSE
def rmse_train_test(feature_cols):
    X = df[feature_cols]
    yy = df[response_vector]
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=777)
    reg = LinearRegression()
    reg.fit(X_train, y_train)
    y_pred = reg.predict(X_test)
    return np.sqrt(metrics.mean_squared_error(y_test, y_pred))

# calculate RMSE with all three features
#rmse_train_test(feature_cols)

#alt 
rmse_train_test(['cool', 'useful', 'funny'])

"""
Explanation: Task 5
Evaluate the model by splitting it into training and testing sets and computing the RMSE. Does the RMSE make intuitive sense to you?
End of explanation
"""


print("RMSE for funny feature:")
print(rmse_train_test(['funny']))


print("RMSE for cool feature:")
print(rmse_train_test(['cool']))


print("RMSE for useful feature:")
print(rmse_train_test(['useful']))


#cool and useful seem to be the features that work best
print("RMSE for cool and useful feature:")
print(rmse_train_test(['cool', 'useful']))


print("RMSE for cool and funny feature:")
print(rmse_train_test(['cool', 'funny']))


print("RMSE for funny and useful feature:")
print(rmse_train_test(['funny', 'useful']))


print("RMSE for all feature:")
print(rmse_train_test(['cool', 'useful', 'funny']))

"""
Explanation: Task 6
Try removing some of the features and see if the RMSE improves.
End of explanation
"""


# new feature: 

df['sum_votes'] = df['cool'] + df['useful'] + df['funny']

# new features: 
feature_cols = ['cool', 'useful', 'funny', 'sum_votes']
X = df[feature_cols]

# add new features to the model and calculate RMSE
print("RMSE for total votes:")
print(rmse_train_test(['sum_votes']))

"""
Explanation: Task 7 (Bonus)
Think of some new features you could create from the existing data that might be predictive of the response. Figure out how to create those features in Pandas, add them to your model, and see if the RMSE improves.
End of explanation
"""


#test train split 
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=777)


# NUMPY array with the same shape as y_test
y_null = np.zeros_like(y_test, dtype=float)


# fill the array with the mean value of y_test
y_null = pd.DataFrame(y_null)
#print(y_test.mean())
y_null.fillna(3.7732)

# compute null RMSE
np.sqrt(metrics.mean_squared_error(y_test, y_null))

"""
Explanation: Task 8 (Bonus)
Compare your best RMSE on the testing set with the RMSE for the "null model", which is the model that ignores all features and simply predicts the mean response value in the testing set.
End of explanation
"""


