In [300]:
%matplotlib inline
import numpy as np
import pandas as pd
import scipy
import sklearn
import matplotlib.pyplot as plt
import seaborn as sns
import math
from matplotlib.mlab import PCA as mlabPCA
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn import preprocessing
from sklearn.feature_selection import SelectKBest
import seaborn as sns
import scipy.stats as stats
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.naive_bayes import BernoulliNB
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import cross_val_score, KFold
import matplotlib.pyplot as plt
from sklearn.model_selection import StratifiedKFold
from sklearn.feature_selection import RFECV
from sklearn.datasets import make_classification
from sklearn.feature_selection import RFE
from sklearn.model_selection import cross_val_predict
from sklearn import metrics
from sklearn.decomposition import PCA as sklearn_pca
import locale
from locale import atof
import warnings
from IPython.display import display
from sklearn import linear_model
from sklearn.cross_validation import cross_val_score, cross_val_predict
from sklearn.feature_selection import f_regression
import statsmodels.formula.api as smf
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import xlrd
In [301]:
# Import FBI Raw Data
fbidata = pd.read_csv('https://raw.githubusercontent.com/Thinkful-Ed/data-201-resources/master/New_York_offenses/NEW_YORK-Offenses_Known_to_Law_Enforcement_by_City_2013%20-%2013tbl8ny.csv', delimiter=",", thousands=',',decimal=".")
fbiraw = pd.DataFrame(fbidata)
fbiraw.head()
Out[301]:
In [302]:
#Transform FBI Raw Data
#Rename columns with row 3 from the original data set
fbiraw_t1 = fbiraw.rename(columns=fbiraw.iloc[3])
#Delete first three rows don´t contain data for the regression model
fbiraw_t2 = fbiraw_t1.drop(fbiraw_t1.index[0:4])
In [303]:
#Delete column "Rape (revised definition)1 as it contains no data
fbiraw_t2 = fbiraw_t2.drop('Rape\n(revised\ndefinition)1', axis = 1)
In [304]:
#Delete Arson Column as there is insufficient data
# 'The FBI does not publish arson data unless it receives data from either the agency or the state
# for all 12 months of the calendar year.'
fbiraw_t2 = fbiraw_t2.drop('Arson3', axis = 1)
In [305]:
#Clean tail from the data set
#Re-shape dataset excluding the last 3 rows of the dataset as they don´t contain relevant information for the model
fbiraw_t2 = fbiraw_t2[:-3]
#Change names in Columns
fbiraw_t2= fbiraw_t2.rename(columns={'Violent\ncrime': 'Violent Crime', 'Murder and\nnonnegligent\nmanslaughter': 'Murder','Rape\n(legacy\ndefinition)2': 'Rape', 'Robbery': 'Robbery', 'Aggravated\nassault': 'Assault', 'Property\ncrime': 'PropertyCrime', 'Burglary': 'Burglary', 'Larceny-\ntheft': 'Larceny & Theft', 'Motor\nvehicle\ntheft': 'MotorVehicleTheft'})
In [306]:
#Analyse missing information
fbiraw_t2.info()
In [307]:
#Change all columns from object to float
locale.setlocale(locale.LC_NUMERIC, '')
fbiraw_t2['Population'] = fbiraw_t2['Population'].apply(atof)
fbiraw_t2['Violent Crime'] = fbiraw_t2['Violent Crime'].apply(atof)
fbiraw_t2['Murder'] = fbiraw_t2['Murder'].apply(atof)
fbiraw_t2['Rape'] = fbiraw_t2['Rape'].apply(atof)
fbiraw_t2['Robbery'] = fbiraw_t2['Robbery'].apply(atof)
fbiraw_t2['Assault'] = fbiraw_t2['Assault'].apply(atof)
fbiraw_t2['PropertyCrime'] = fbiraw_t2['PropertyCrime'].apply(atof)
fbiraw_t2['Burglary'] = fbiraw_t2['Burglary'].apply(atof)
fbiraw_t2['Larceny & Theft'] = fbiraw_t2['Larceny & Theft'].apply(atof)
fbiraw_t2['MotorVehicleTheft'] = fbiraw_t2['MotorVehicleTheft'].apply(atof)
fbiraw_t2.info()
In [308]:
#Reindex the dataframe
fbiraw_t3 = fbiraw_t2.reset_index(drop=True)
fbiraw_t2.head()
Out[308]:
In [309]:
#Extract only the columns that are needed
fbiraw_t3 = fbiraw_t2
In [310]:
#Eliminate outliers
fbiraw_t3 = fbiraw_t3[fbiraw_t3.PropertyCrime < 450].reset_index(drop=True)
#Describe the dataset
fbiraw_t3.describe()
Out[310]:
In [311]:
#Print length of dataset and sort values by Population to see how many datapoints are excluded
print(len(fbiraw_t3), len(fbiraw_t2) - len(fbiraw_t3))
fbiraw_t3.sort_values('PropertyCrime',ascending=False).head()
Out[311]:
In [312]:
#Plot the relationships between variables
sns.set_style("white")
#Conisder only the vairables suitable for the model
dfcont = fbiraw_t3
# Scatterplot matrix.
g = sns.PairGrid(dfcont, diag_sharey=False)
g.map_upper(plt.scatter, alpha=.5)
# Fit line summarizing the linear relationship of the two variables.
g.map_lower(sns.regplot, scatter_kws=dict(alpha=0))
# Give information about the univariate distributions of the variables.
g.map_diag(sns.kdeplot, lw=3)
plt.show()
In [313]:
#Create the new feature Population2
#fbiraw_t3['Population2'] = fbiraw_t3['Population']*fbiraw_t3['Population']
In [314]:
#Convert Robbery into a categorical feature
fbiraw_t3.loc[fbiraw_t3['Robbery'] > 0, 'Robbery'] = 1
In [315]:
#Convert Murder into a categorical feature
fbiraw_t3.loc[fbiraw_t3['Murder'] > 0, 'Murder'] = 1
In [316]:
# Initialize the figure with a logarithmic x axis
f, ax = plt.subplots(figsize=(7, 6))
ax.set_xscale("log")
# Define the variables that are going to be plot
df_long = fbiraw_t3
#Boxplot vairables
ax = sns.boxplot(data=df_long, orient="h", palette="Set2")
In [317]:
fbiraw_t2.head()
Out[317]:
In [318]:
#Transform dataset into final dataset with features
fbidata = fbiraw_t3.drop('City',axis=1)
In [319]:
names = fbidata.columns
df_scaled = pd.DataFrame(preprocessing.scale(fbidata), columns = names)
df_scaled.describe()
Out[319]:
In [320]:
fbidata.to_csv('fbidata.csv')
In [321]:
# Instantiate and fit our model.
regr = linear_model.LinearRegression()
#Create Variables for the model by dropping variables from the initial list
Y = df_scaled['PropertyCrime'].values.ravel()
X = df_scaled.drop(['Violent Crime','Murder','Larceny & Theft','PropertyCrime', 'Rape','MotorVehicleTheft','Assault'],axis=1)
regr.fit(X, Y)
# Inspect the results.
print('\nCoefficients: \n', regr.coef_)
print('\nIntercept: \n', regr.intercept_)
print('\nR-squared:')
print(regr.score(X, Y))
print('\nVariables in the model: \n',list(X.columns))
In [322]:
# Initialize the figure with a logarithmic x axis
f, ax = plt.subplots(figsize=(7, 6))
# Define the variables that are going to be plot
df_long = X
#Boxplot vairables
ax = sns.boxplot(data=df_long, orient="h", palette="Set2")
In [323]:
# Establish the pair outcome-feature we want to compare
outcome = Y
feature = X['Burglary']
# Plot the data as-is. Looks a mite quadratic.
plt.scatter( feature,outcome)
plt.title('Relationshib between Outcome & Features')
plt.xlabel('Features')
plt.ylabel('Outcome')
plt.show()
In [324]:
# Extract predicted values.
predicted = regr.predict(X).ravel()
actual = df_scaled['PropertyCrime']
# Calculate the error, also called the residual.
residual = actual - predicted
# Plot the distribution of errors.
plt.hist(residual)
plt.title('Residual counts')
plt.xlabel('Residual')
plt.ylabel('Count')
plt.show()
In [325]:
plt.scatter(predicted, residual)
plt.xlabel('Predicted')
plt.ylabel('Residual')
plt.axhline(y=0)
plt.title('Residual vs. Predicted')
plt.show()
In [326]:
# Build up the correlation mtrix
Z = X
correlation_matrix = Z.corr()
display(correlation_matrix)
In [327]:
#Eigenvectores & Eigenvalues
eig_vals, eig_vecs = np.linalg.eig(correlation_matrix)
# Inspecting the eigenvalues and eigenvectors.
for i in range(len(eig_vals)):
eigvecs = eig_vecs[:, i].reshape(1, len(X.columns)).T
print('Eigenvector {}: \n{}'.format(i + 1, eigvecs))
print('Eigenvalue {}: {}'.format(i + 1, eig_vals[i]))
print(40 * '-')
sklearn_pca = PCA(n_components=len(X.columns))
Y_sklearn = sklearn_pca.fit_transform(correlation_matrix)
print(
'The percentage of total variance in the dataset explained by each',
'component from Sklearn PCA.\n',
sklearn_pca.explained_variance_ratio_
)
In [328]:
#From the Scree plot.
plt.plot(eig_vals)
plt.show()
In [329]:
# create the RFE model and select features
nfeatures = (len(X.columns))
rfe = RFE(regr,nfeatures)
fit = rfe.fit(X,Y)
# summarize the selection of the features
result_RFE = pd.DataFrame(list(zip(X.head(0), rfe.ranking_, rfe.support_)),columns=['Features','Ranking','Support'] )
result_RFE.sort_values('Ranking')
Out[329]:
In [330]:
#Result as a list for "keywords"
result= result_RFE[result_RFE.Support == False]
drop = result["Features"].tolist()
drop
Out[330]:
In [ ]:
#Initiating the cross validation generator, N splits = 10
kf = KFold(10)
In [331]:
#Cross validate the model on the folds
scores = cross_val_score(regr, X, Y, cv=kf)
print('Cross-validated scores:', scores)
print('Cross-validation average:', scores.mean())
In [332]:
#Plot Predictions vs values
predictions = cross_val_predict(regr, X, Y, cv=kf)
plt.scatter(Y, predictions)
plt.xlabel('Real Values')
plt.ylabel('Predicted Values')
plt.axhline(y=0)
plt.title('Real vs. Predicted')
plt.show()
In [333]:
#Predictive accuracy
accuracy = metrics.r2_score(Y, predictions)
print ('Cross-Predicted Accuracy:', accuracy)
In [366]:
#Testing the results with statsmodel
linear_formula = 'PropertyCrime ~ Population+Robbery+Burglary'
lm = smf.ols(formula=linear_formula, data=df_scaled).fit()
print('Coefficients: \n', lm.params)
print('\n P values: \n', lm.pvalues)
print('\n R squared: \n', lm.rsquared)
print('\n Confidence Interval: \n', lm.conf_int())
In [367]:
# Use wls_prediction_std to build confidence intervals
prstd, iv_l, iv_u = wls_prediction_std(lm)
plt.figure()
plt.plot(iv_u[0:15], 'o', color='r')
plt.plot(iv_l[0:15], 'o', color='r')
plt.plot(lm.fittedvalues[0:15], 'o', color='b')
plt.title('blue: predicted, red: 95% CI')
plt.show()
In [368]:
import pickle
# save the model to disk
filename = 'finalized_regr.sav'
pickle.dump(regr, open(filename, 'wb'))
In [ ]: