train = pd.read_csv("train.csv")
train.describe()

"""
Explanation: Load Data
End of explanation
"""


# Cleanup Gender and Embarked
train['Sex'] = np.where(train['Sex'] == 'male', 0, 1)
train['Embarked'] = train['Embarked'].fillna('Z').map(dict(C=0, S=1, Q=2, Z=3))

# AGE -- quickly look at data
train['hasage'] = np.isnan(train['Age'])
train.hist('Age', by='Survived', bins=25)
train.groupby('Survived').mean()

"""
Explanation: Clean Data
On the outset it seems that there are some issues with the number of observations for the columns (e.g., Age, Cabin, Embarked).
* Gender is non numeric
* Embarked is also a string
* Age -- Missing and incorrect data
End of explanation
"""


# Age is missing values
train['Age'] = np.where(np.isfinite(train['Age']), train['Age'], -1)

"""
Explanation: There is a clear difference in the distributions in ages between thoes who survived and not.  Also from the table you can see the differences in the mean values of the passenger class (pclass), ages, and Fares.  Note it is also more likely to have a missing age if you did not survive.  Rather than attempting to model the missing ages, I include -1 age class
End of explanation
"""


# Remap cabin to a numeric value depending on the letter
m = {chr(i+97).upper():i for i in range(26)}
shortenmap = lambda x: m[x[0]]
train['cleancabin'] = train['Cabin'].fillna('Z').apply(shortenmap)
train['cleancabin'].hist()

# Get person title / family name
# These might be overfitting the data since the title is correlated with gender
# and family name and siblings, however they seems to add more information.
train['family'] = train['Name'].apply(lambda x: x.split(',')[0])
train['title'] = train['Name'].apply(lambda x: x.split(',')[1].split()[0])

nfamily = dict(train['family'].value_counts())
train['nfamily'] = train['family'].map(nfamily)

ntitle = {title:i for i,title in enumerate(np.unique(train['title']))}
train['ntitle'] = train['title'].map(ntitle)

train.groupby('Survived').mean()

"""
Explanation: Feature Creation
End of explanation
"""


predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked", 'cleancabin', 'nfamily', 'ntitle']

from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier, AdaBoostRegressor
from sklearn.svm import SVC, LinearSVC
from sklearn.ensemble import VotingClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import AdaBoostClassifier

from sklearn import cross_validation

"""
Explanation: Classify!
First test different techniques to see how well they predict the training set.
End of explanation
"""


scores = cross_validation.cross_val_score(
    LogisticRegression(random_state=0),
    train[predictors],
    train["Survived"],
    cv=3
)

print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: Logistic Regression
End of explanation
"""


scores = cross_validation.cross_val_score(
    RandomForestClassifier(
        random_state=0,
        n_estimators=150,
        min_samples_split=4,
        min_samples_leaf=2
    ),
    train[predictors],
    train["Survived"],
    cv=3
)

print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: Random Forest
End of explanation
"""


scores = cross_validation.cross_val_score(
    GradientBoostingClassifier(n_estimators=100, 
                               learning_rate=1.0, 
                               max_depth=1, 
                               random_state=0),
    train[predictors],
    train["Survived"],
    cv=3
)
print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: Gradient Boost
End of explanation
"""


scores = cross_validation.cross_val_score(
    SVC(random_state=0),
    train[predictors],
    train["Survived"],
    cv=3
)
print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: Support Vector Machine Classifier
End of explanation
"""


scores = cross_validation.cross_val_score(
    AdaBoostRegressor(SVC(kernel='poly', random_state=0), random_state=0, n_estimators=500, learning_rate=0.5),
    train[predictors],
    train["Survived"],
    cv=3
)
print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: Support Vector Machine Classifier with AdaBoost?!
Broken!
End of explanation
"""


scores = cross_validation.cross_val_score(
    AdaBoostClassifier(random_state=0, n_estimators=100),
    train[predictors],
    train["Survived"],
    cv=3
)
print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: AdaBoost
End of explanation
"""


bagging = BaggingClassifier(KNeighborsClassifier(), max_samples=0.5, max_features=0.5, random_state=0)
scores = cross_validation.cross_val_score(
    bagging,
    train[predictors],
    train["Survived"],
    cv=3
)
print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: K Nearest Neighbors + Bagging
End of explanation
"""


est = [('GNB', GaussianNB()), 
       ('LR', LogisticRegression(random_state=1)), 
       ('RFC',RandomForestClassifier(random_state=1))]
alg = BaggingClassifier(VotingClassifier(est, voting='soft'), max_samples=0.5, max_features=0.5)


scores = cross_validation.cross_val_score(
    alg,
    train[predictors],
    train["Survived"],
    cv=3
)
print('{:0.1f}'.format(100*scores.mean()))

"""
Explanation: Voting Classifier with multiple classifiers
End of explanation
"""


forest = ExtraTreesClassifier(n_estimators=250,
                              random_state=0)
forest.fit(train[predictors], train['Survived'])
importances = forest.feature_importances_
std = np.std([tree.feature_importances_ for tree in forest.estimators_],
             axis=0)
indices = np.argsort(importances)[::-1]

ind = np.arange(len(indices))

pylab.errorbar(ind, importances[indices], yerr=std, fmt='s')
pylab.xticks(ind, [predictors[i] for i in indices], rotation='vertical')
pylab.axhline(0.0, color='orange', lw=2)
for index in indices:
    print index, predictors[index], importances[index]

"""
Explanation: Measure feature Strength
End of explanation
"""


