# подгружаем все нужные пакеты
import pandas as pd
import numpy as np
# для встроенных картинок
%pylab inline
# чуть покрасивше картинки:
pd.set_option('display.mpl_style', 'default')
figsize(12, 9)
import warnings
warnings.filterwarnings("ignore")
#plt.rcParams['figure.figsize'] = 10, 7.5
#plt.rcParams['axes.grid'] = True
pd.set_option('display.max_columns', None)
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = 'Ubuntu'
plt.rc('text', usetex=False)
plt.rc('font', family='serif')
plt.rc('font', weight='bold')
plt.rc('xtick', labelsize=14)
plt.rc('ytick', labelsize=14)
# чтобы был русский шрифт
from matplotlib import rc
font = {'family': 'Verdana',
'weight': 'normal'}
rc('font', **font)
transactions = pd.read_csv('transactions.csv') # d:\\Competitions\\sdsj\\
print (transactions.shape)
transactions[:5]
tr_mcc_codes = pd.read_csv('tr_mcc_codes.csv', sep=';')
print (tr_mcc_codes.shape, transactions.mcc_code.nunique())
tr_mcc_codes[:5]
tr_types = pd.read_csv('tr_types.csv', sep=';')
print (tr_types.shape, transactions.tr_type.nunique())
tr_types[:5]
customers_gender_train = pd.read_csv('customers_gender_train.csv')
print (customers_gender_train.shape)
customers_gender_train[:5]
# присоедниение пола
transactions = pd.merge(transactions, customers_gender_train, on='customer_id', how='outer')
print (transactions.shape)
transactions[:5]
transactions['num_day'] = transactions['tr_datetime'].apply(lambda x: int(x.split(' ')[0]))
transactions['datetime'] = transactions['tr_datetime'].apply(lambda x: x.split(' ')[1])
transactions['hour'] = transactions['datetime'].apply(lambda x: int(x.split(':')[0]))
transactions['minute'] = transactions['datetime'].apply(lambda x: int(x.split(':')[1]))
transactions['second'] = transactions['datetime'].apply(lambda x: int(x.split(':')[2]))
del transactions['tr_datetime']
transactions[:5]
# день недели
transactions['dayofweek'] = transactions['num_day'].apply(lambda x: (x + 4) % 7)
transactions[:5]
figsize(14, 5)
p = transactions.dayofweek.hist(bins=7) # там есть 60!
p.set_xlabel('dayofweek')
p.set_ylabel('count')
p.set_xlim([0, 6])
p.set_xticklabels([u'пн', u'вт', u'ср', u'чт', u'птн', u'сб', u'вск'])
p.set_title(u'Число транзакций в разные дни недели')
transactions.dayofweek.value_counts()
figsize(12,5)
plt.hist(transactions.dayofweek.values, bins=7, color='#770000', label=u'все', alpha=0.3, width=0.8) # , histtype='stepfilled', normed=True,
plt.hist(transactions[transactions.gender==0].dayofweek.values, bins=7, color='#007700', label=u'ж', alpha=0.6, width=0.7)
plt.hist(transactions[transactions.gender==1].dayofweek.values, bins=7, color='#000077', label=u'м', alpha=1.0, width=0.6)
plt.xticks(0.25+ 0.85*np.arange(7), [u'пн', u'вт', u'ср', u'чт', u'птн', u'сб', u'вск']) # , rotation='vertical'
plt.title(u'Число транзакций в разные дни недели')
plt.legend()
figsize(12,5)
# там есть 60!
plt.hist(transactions.second.values, bins=61, color='#770000', label=u'все', alpha=0.3, width=0.8) # , histtype='stepfilled', normed=True,
plt.hist(transactions[transactions.gender==0].second.values, bins=61, color='#007700', label=u'ж', alpha=0.6, width=0.7)
plt.hist(transactions[transactions.gender==1].second.values, bins=61, color='#000077', label=u'м', alpha=1.0, width=0.6)
plt.xlabel('second')
plt.ylabel('count')
plt.title(u'Вхождения секунд во времена транзакций')
plt.legend()
plt.xlim([0, 60.5])
transactions.second.value_counts()[:5]
print (transactions[transactions.gender==0].second.value_counts()[:5])
print (transactions[transactions.gender==1].second.value_counts()[:5]) # у мужчин это чаще!!!
figsize(12,5)
# там есть 60!
plt.hist(transactions.minute.values, bins=60, color='#770000', label=u'все', alpha=0.3, width=0.8) # , histtype='stepfilled', normed=True,
plt.hist(transactions[transactions.gender==0].minute.values, bins=60, color='#007700', label=u'ж', alpha=0.6, width=0.7)
plt.hist(transactions[transactions.gender==1].minute.values, bins=60, color='#000077', label=u'м', alpha=1.0, width=0.6)
plt.xlabel('minute')
plt.ylabel('count')
plt.title(u'Вхождения минут во времена транзакций')
plt.legend()
plt.xlim([0, 60.5])
transactions.minute.value_counts()[:5]
transactions['new'] = (transactions.minute==0) & (transactions.second==0) & (transactions.hour==0)
pd.crosstab(transactions.new, transactions.gender)
# что это за нулевое время...
transactions[transactions.new==True][::50000]
# transactions[transactions.new==True]['tr_type'].unique()
figsize(12,5)
# там есть 60!
plt.hist(transactions.hour.values, bins=24, color='#770000', label=u'все', alpha=0.3, width=0.8) # , histtype='stepfilled', normed=True,
plt.hist(transactions[transactions.gender==0].hour.values, bins=24, color='#007700', label=u'ж', alpha=0.6, width=0.7)
plt.hist(transactions[transactions.gender==1].hour.values, bins=24, color='#000077', label=u'м', alpha=1.0, width=0.6)
plt.xlabel('hour')
plt.ylabel('count')
plt.title(u'Вхождения часов во времена транзакций')
plt.legend()
plt.xlim([0, 24])
transactions.hour.value_counts()[:5]
# число дней
transactions.num_day.nunique()
figsize(12,5)
# там есть 60!
plt.hist(transactions.num_day.values, bins=457, color='#770000', label=u'все', alpha=0.3, width=0.9) # , histtype='stepfilled', normed=True,
plt.hist(transactions[transactions.gender==0].num_day.values, bins=457, color='#007700', label=u'ж', alpha=0.6, width=0.7)
plt.hist(transactions[transactions.gender==1].num_day.values, bins=457, color='#000077', label=u'м', alpha=1.0, width=0.5)
plt.xlabel('day')
plt.ylabel('count')
plt.title(u'Вхождения дней во времена транзакций')
plt.legend()
plt.xlim([0, 457])
# plt.xlim([153-10, 153+(120-1) + 4 + 10])
transactions.num_day.value_counts()[:5]
457-153
tmp = transactions.groupby('customer_id')
f1 = tmp.amount.count().values
f2 = tmp.amount.mean().values
g = tmp.gender.mean().values
plt.scatter(np.log(f1[g==0]+1), np.sign(f2[g==0])*np.log(np.abs(f2[g==0])+1), c='#990000')
plt.scatter(np.log(f1[g==1]+1), np.sign(f2[g==1])*np.log(np.abs(f2[g==1])+1), c='#000099')
plt.xlabel(u'~ log число транзакций')
plt.ylabel(u'~ log средняя транзакция')
tmp = transactions.groupby('customer_id')
f1 = tmp.amount.apply(lambda x: sum(x[x>0])).values
f2 = tmp.amount.apply(lambda x: sum(x[x<0])).values
g = tmp.gender.mean().values
figsize(7, 6)
plt.scatter(np.log(f1[g==0] + 1.0), np.log(1.0 - f2[g==0]), c='#990000', s=20, alpha = 0.3, label=u'ж')
plt.scatter(np.log(f1[g==1] + 1.0), np.log(1.0 - f2[g==1]), c='#000099', s=20, alpha = 0.3, label=u'м')
plt.xlabel(u'~ log сумма начислений')
plt.ylabel(u'~ log сумма трат')
plt.xlim([-0.5, 25])
plt.ylim([-0.5, 25])
plt.title(u'Общий баланс', fontsize=12)
plt.legend()
figsize(12, 5)
plt.hist(np.log(f1[g==1] + 1.0), bins=100, color='#000077', label=u'м', alpha=0.6, normed=True)
plt.hist(np.log(f1[g==0] + 1.0), bins=100, color='#007700', label=u'ж', alpha=0.3, normed=True)
plt.legend()
plt.xlabel(u'~ log сумма начислений')
plt.show()
figsize(12, 5)
plt.hist(np.log(f1[g==1] + 1.0) - np.log(-f2[g==1] + 1.0), bins=100, color='#000077', label=u'м', alpha=0.6, normed=True)
plt.hist(np.log(f1[g==0] + 1.0) - np.log(-f2[g==0] + 1.0), bins=100, color='#007700', label=u'ж', alpha=0.3, normed=True)
plt.legend()
plt.xlabel(u'~ log сумма начислений - log сумма трат')
plt.show()
tmp = np.log(f1[g==1] + 1.0) - np.log(f2[g==1] + 1.0)
max(tmp), min(tmp)
tmp = transactions.groupby('customer_id')
f1 = tmp.amount.apply(lambda x: mean(x[x>0])).values
f2 = tmp.amount.apply(lambda x: mean(x[x<0])).values
g = tmp.gender.mean().values
figsize(7, 6)
plt.scatter(np.log(f1[g==0] + 1.0), np.log(1.0 - f2[g==0]), c='#990000', s=5, alpha = 0.5, label=u'ж')
plt.scatter(np.log(f1[g==1] + 1.0), np.log(1.0 - f2[g==1]), c='#000099', s=5, alpha = 0.5, label=u'м')
plt.xlabel(u'~ log среднее начисление')
plt.ylabel(u'~ log средняя трата')
plt.xlim([-0.5, 20])
plt.ylim([-0.5, 20])
plt.title(u'Общий баланс средних')
plt.legend()
# просто эксперимент
df = pd.DataFrame({'a':[1,1,1,1,1,1,2,2,2,2,2], 'b':[3,2,4,2,3,1,2,3,4,3,2]})
df.groupby('a').b.apply(lambda x: sum(x==1))
# Самые популярные tr_types
tmp = transactions.groupby('tr_type').amount.count()
tmp.sort(ascending=False)
figsize(12, 5)
tmp.plot(kind='bar')
# plt.bar(np.arange(len(f)), f) f = tmp.values
plt.xlabel('tr_type')
plt.ylabel('count')
plt.title(u'Число транзакций с разными tr_type')
pd.merge(tmp[:15].reset_index(), tr_types)
#plt.plot(np.sort(tmp.amount.sum().values))
# Гендерные tr_types
tmp = pd.merge(pd.crosstab(transactions.tr_type, transactions.gender).reset_index(), tr_types)
tmp[:5]
abs(tmp[0.0] - tmp[1.0])/(tmp[0.0] + tmp[1.0])
tmp['k'] = (abs(tmp[0.0] - tmp[1.0])/(tmp[0.0] + tmp[1.0]))
tmp = tmp[(tmp[0.0] + tmp[1.0]) > 50] # е. достаточно статистики
tmp.sort('k', ascending=False, inplace=True)
#del tmp['gender']
tmp.columns = [u'tr_type', u'ж', u'м', u'tr_type_description', u'k']
tmp.set_index(tmp.tr_type, inplace=True)
del tmp['tr_type']
tmp[:10]
p = tmp[:50].k.plot(kind='bar')
p.set_ylabel(u'коэффициент различаемости')
p.set_title(u'tr_type мужчин и женщин')
# Популярные mcc_code
tmp = transactions.groupby('mcc_code').amount.count()
tmp.sort(ascending=False)
figsize(15, 5)
tmp[:50].plot(kind='bar') ##### 50!
# plt.bar(np.arange(len(f)), f) f = tmp.values
plt.xlabel('mcc_code')
plt.ylabel('count')
plt.title('Число транзакций с разными mcc_code (выведены первые 50)')
pd.merge(tmp[:15].reset_index(), tr_mcc_codes)
#plt.plot(np.sort(tmp.amount.sum().values))
# гендерные mcc_code
tmp = pd.merge(pd.crosstab(transactions.mcc_code, transactions.gender).reset_index(), tr_mcc_codes)
tmp[:5]
abs(tmp[0.0] - tmp[1.0])/(tmp[0.0] + tmp[1.0])
tmp['k'] = (abs(tmp[0.0] - tmp[1.0])/(tmp[0.0] + tmp[1.0]))
tmp.sort('k', ascending=False, inplace=True)
#del tmp['gender']
tmp.columns = [u'mcc_code', u'ж', u'м', u'mcc_description', u'k']
tmp.set_index(tmp.mcc_code, inplace=True)
del tmp['mcc_code']
tmp[:10]
p = tmp[:50].k.plot(kind='bar')
p.set_ylabel(u'коэффициент различаемости')
p.set_title(u'mmc_code мужчин и женщин')
figsize(12,5)
# там есть 60!
plt.hist(transactions[transactions.amount.abs()<70].amount.values, bins=(69*2+1), color='#770000', label=u'все', alpha=0.3, width=0.8) # , histtype='stepfilled', normed=True,
plt.hist(transactions[transactions.amount.abs()<70][transactions.gender==0].amount.values, bins=(69*2+1), color='#007700', label=u'ж', alpha=0.6, width=0.7)
plt.hist(transactions[transactions.amount.abs()<70][transactions.gender==1].amount.values, bins=(69*2+1), color='#000077', label=u'м', alpha=1.0, width=0.6)
plt.xlabel('сумма')
plt.ylabel('число транзакций')
plt.title(u'Распределение сумм транзакций')
plt.legend()
#plt.xlim([0, 24])
#transactions.amount.value_counts()[:5]
tmp = transactions.amount.values
p = transactions[transactions.amount.abs()<1000].amount.hist(bins=200)
p.set_xlabel('сумма')
p.set_ylabel('число транзакций')
p.set_title('Распределение сумм транзакций (небольшие суммы)')
p = transactions[transactions.amount.abs()<1000].amount.apply(lambda x: np.log(np.abs(x))).hist(bins=100)
p.set_xlabel('сумма')
p.set_ylabel('число транзакций')
p.set_title('Распределение сумм транзакций (небольшие суммы)')
tmp = transactions.groupby(['num_day', 'customer_id']).amount.count()
p = tmp[tmp<=30].hist(bins=30)
p.set_xlabel('число транзакций в день')
p.set_ylabel('число таких случаев (пар "клиент, день")')
p.set_title('Встречаемость определённого количества транзакций в день')
tmp.value_counts()[:10]