text_plain_output_1.png image_output_1.png
from sklearn.cross_validation import KFold

from sklearn.metrics import log_loss

from sklearn.preprocessing import LabelEncoder

import matplotlib.pyplot as plt

import numpy as np

import pandas as pd

gatrain = pd.read_csv('../input/gender_age_train.csv')
gatest = pd.read_csv('../input/gender_age_test.csv')

letarget = LabelEncoder().fit(gatrain.group.values)
y = letarget.transform(gatrain.group.values)
n_classes = len(letarget.classes_)

phone = pd.read_csv('../input/phone_brand_device_model.csv', encoding='utf-8')

phone = phone.drop_duplicates('device_id', keep='first')

lebrand = LabelEncoder().fit(phone.phone_brand)
phone['brand'] = lebrand.transform(phone.phone_brand)
m = phone.phone_brand.str.cat(phone.device_model)
lemodel = LabelEncoder().fit(m)
phone['model'] = lemodel.transform(m)

train = gatrain.merge(phone[['device_id', 'brand', 'model']], how='left', on='device_id')

ptrain = gatrain.merge(phone[['device_id', 'brand', 'model']], how='left', on='device_id')

class GenderAgeGroupProb(object):
    def __init__(self, prior_weight=10.0):
        self.prior_weight = prior_weight
    def fit(self, df, by):
        self.by = by
        self.prior = df['group'].value_counts().sort_index() / df.shape[0]
        c = df.groupby([by, 'group']).size().unstack().fillna(0)
        total = c.sum(axis=1)
        self.prob = c.add(self.prior_weight * self.prior).div(c.sum(axis=1) + self.prior_weight, axis=0)
        return self
    def predict_proba(self, df):
        pred = df[[self.by]].merge(self.prob, how='left', left_on=self.by, right_index=True).fillna(self.prior)[self.prob.columns]
        pred.loc[pred.iloc[:, 0].isnull(), :] = self.prior
        return pred.values
def score(ptrain, by, prior_weight=10.0):
    kf = KFold(ptrain.shape[0], n_folds=10, shuffle=True, random_state=0)
    pred = np.zeros((ptrain.shape[0], n_classes))
    for itrain, itest in kf:
        train = ptrain.iloc[itrain, :]
        test = ptrain.iloc[itest, :]
        ytrain, ytest = (y[itrain], y[itest])
        clf = GenderAgeGroupProb(prior_weight=prior_weight).fit(train, by)
        pred[itest, :] = clf.predict_proba(test)
    return log_loss(y, pred)

weights = [0.5, 1.0, 5.0, 10.0, 20.0, 40.0, 100.0]
res = [score(ptrain, 'brand', prior_weight=w) for w in weights]

weights = [0.5, 1.0, 5.0, 10.0, 20.0, 40.0, 100.0]
res = [score(ptrain, 'model', prior_weight=w) for w in weights]

kf = KFold(ptrain.shape[0], n_folds=10, shuffle=True, random_state=0)
predb = np.zeros((ptrain.shape[0], n_classes))
predm = np.zeros((ptrain.shape[0], n_classes))
for itrain, itest in kf:
    train = ptrain.iloc[itrain, :]
    test = ptrain.iloc[itest, :]
    ytrain, ytest = (y[itrain], y[itest])
    clf = GenderAgeGroupProb(prior_weight=40.0).fit(train, 'brand')
    predb[itest, :] = clf.predict_proba(test)
    clf = GenderAgeGroupProb(prior_weight=40.0).fit(train, 'model')
    predm[itest, :] = clf.predict_proba(test)
log_loss(y, 0.5 * (predb + predm))