[PYTHON] Résumé de Kaggle: Redhat (Partie 1)

introduction

Nous mettrons à jour les informations de Kaggle qui a participé dans le passé. Ici, nous reprendrons l'introduction des données sur Prédire la valeur commerciale de Red Hat et la discussion de premier plan dans le forum. Le code du gagnant du concours est résumé dans Kaggle Summary: Red Hat (Part 2), qui est un résumé, une discussion et un exemple de code. (Actuellement en construction)

Cet article utilise Python 2.7, numpy 1.11, scipy 0.17, scikit-learn 0.18, matplotlib 1.5, seaborn 0.7, pandas 0.17. Il a été confirmé qu'il fonctionne sur le notebook jupyter. (Veuillez modifier correctement% matplotlib inline) Si vous trouvez des erreurs lors de l'exécution de l'exemple de script, il serait utile que vous puissiez commenter.

table des matières

  1. Vue d'ensemble
  2. Indice d'évaluation
  3. Présentation des données
  4. kernels

Contexte

front_page.png

Comme pour de nombreuses entreprises, RedHat est en mesure de collecter les informations clients qui y sont liées par ordre chronologique. Red Hat recherche une méthode pour prédire quel individu doit être approché et comment l'aborder à partir de la prédiction en fonction du comportement du client. Dans ce concours, Kaggler tente de créer un algorithme de classification pour prédire la valeur commerciale potentielle de Red Hat à partir des caractéristiques et des activités des clients.

Les points caractéristiques de cette époque sont les suivants.

2. Indice d'évaluation

L'indice d'évaluation cette fois-ci est ROC. ([Version japonaise de wikipedia](https://ja.wikipedia.org/wiki/%E5%8F%97%E4%BF%A1%E8%80%85%E6%93%8D%E4%BD%9C % E7% 89% B9% E6% 80% A7))

ROC est l'indice le plus standard pour évaluer les problèmes de classification binaire. Des explications détaillées sont données sur divers sites, veuillez donc rechercher «ROC» et «F-mesure» pour plus de détails.

De plus, le format du fichier soumis exprime la correspondance entre l'identifiant d'activité et la probabilité du résultat en CSV.

activity_id,outcome
act1_1,0
act1_100006,0
act1_100050,0
etc.

3. Présentation des données

Ces données se composent de deux fichiers différents (fichier people, fichier act_train). Le fichier de personnes contient des informations personnelles associées à l'identifiant client. Le fichier d'activité contient l'historique du comportement du client associé à l'identifiant client et le résultat (résultat) de ce comportement.

Le fichier de personnes possède la nature du client (char *). Toutes les fonctionnalités (char *) à l'exception de char_38 sont des informations de catégorie anonymisées. char_38 contient des valeurs continues, pas des informations catégorielles.

Le résultat du fichier d'activité indique si le client a atteint un objectif particulier sur une période de temps. Le fichier d'activité contient également des informations appelées activity_category. Ceci indique la catégorie à laquelle appartient la quantité d'entités (char *) de chaque information d'index. Par exemple, les données de type 1 (char *) et les données de type 2-7 (char *) affichent des quantités d'entités différentes. Je vais.

Le but de ce concours est de prédire les clients qui vont générer de la valeur commerciale en fusionnant ces deux fichiers de données avec person_id.

act_test.csv


activity_id	date	activity_category	char_1	char_2	char_3	char_4	char_5	char_6	char_7	char_8	char_9	char_10
people_id													
ppl_100004	act1_249281	2022-07-20	type 1	type 5	type 10	type 5	type 1	type 6	type 1	type 1	type 7	type 4	NaN
ppl_100004	act2_230855	2022-07-20	type 5	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	type 682
ppl_10001	act1_240724	2022-10-14	type 1	type 12	type 1	type 5	type 4	type 6	type 1	type 1	type 13	type 10	NaN

people.csv


	char_1	group_1	char_2	date	char_3	char_4	char_5	char_6	char_7	char_8	...	char_29	char_30	char_31	char_32	char_33	char_34	char_35	char_36	char_37	char_38
people_id																					
ppl_100	type 2	group 17304	type 2	2021-06-29	type 5	type 5	type 5	type 3	type 11	type 2	...	False	True	True	False	False	True	True	True	False	36
ppl_100002	type 2	group 8688	type 3	2021-01-06	type 28	type 9	type 5	type 3	type 11	type 2	...	False	True	True	True	True	True	True	True	False	76
ppl_100003	type 2	group 33592	type 3	2022-06-10	type 4	type 8	type 5	type 2	type 5	type 2	...	False	False	True	True	True	True	False	True	True	99
  1. Kernels

4.1. Exploration of the date features Tout d'abord, importez la bibliothèque et les données.

import_data.py


import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
%matplotlib inline

train = pd.read_csv('../input/act_train.csv', parse_dates=['date'])
test = pd.read_csv('../input/act_test.csv', parse_dates=['date'])
ppl = pd.read_csv('../input/people.csv', parse_dates=['date'])

df_train = pd.merge(train, ppl, on='people_id')
df_test = pd.merge(test, ppl, on='people_id')
del train, test, ppl

Regardons le contenu des données.

show_day.py


for d in ['date_x', 'date_y']:
    print('Start of ' + d + ': ' + str(df_train[d].min().date()))
    print('  End of ' + d + ': ' + str(df_train[d].max().date()))
    print('Range of ' + d + ': ' + str(df_train[d].max() - df_train[d].min()) + '\n')

Cliquez ici pour le résultat de l'exécution.

Start of date_x: 2022-07-17
  End of date_x: 2023-08-31
Range of date_x: 410 days 00:00:00

Start of date_y: 2020-05-18
  End of date_y: 2023-08-31
Range of date_y: 1200 days 00:00:00

Vous pouvez voir que nous examinons des données depuis plusieurs années. En fait, ces données sont anonymisées, mais cette fois nous supposerons que nous traitons des données depuis plusieurs années. date_x contient des données pour un an et date_y contient des données pour trois ans. L'heure de fin est la même pour date_x et date_y.

4.1.1. Structure des données

Après le regroupement par date, visualisez la probabilité de résultat.

feature_structure.py


date_x = pd.DataFrame()
date_x['Class probability'] = df_train.groupby('date_x')['outcome'].mean()
date_x['Frequency'] = df_train.groupby('date_x')['outcome'].size()
date_x.plot(secondary_y='Frequency', figsize=(20, 10))

__results___6_1.png

En regardant le graphique, nous pouvons voir qu'il y a peu d'événements de week-end et la probabilité que le résultat soit 1 est également réduite. De plus, on constate que la valeur moyenne du résultat est stable les jours de semaine, mais elle chute à 0,4 à 0,3 le week-end. Regardons également date_y.

show_day_y.py


date_y = pd.DataFrame()
date_y['Class probability'] = df_train.groupby('date_y')['outcome'].mean()
date_y['Frequency'] = df_train.groupby('date_y')['outcome'].size()
# We need to split it into multiple graphs since the time-scale is too long to show well on one graph
i = int(len(date_y) / 3)
date_y[:i].plot(secondary_y='Frequency', figsize=(20, 5), title='date_y Year 1')
date_y[i:2*i].plot(secondary_y='Frequency', figsize=(20, 5), title='date_y Year 2')
date_y[2*i:].plot(secondary_y='Frequency', figsize=(20, 5), title='date_y Year 3')

Voici le résultat.

__results___8_1.png __results___8_2.png __results___8_3.png

Comme pour date_x, vous pouvez voir la différence en semaine et les jours fériés.

4.1.2. test set Dans l'analyse jusqu'à présent, nous avons vu la relation entre le résultat et la date. Nous vérifierons si cette relation est visible dans les données de test. Bien sûr, vous ne pouvez pas voir le résultat des données de test. Par conséquent, nous ne vérifierons que la distribution de l'échantillon.

show_test.py


date_x_freq = pd.DataFrame()
date_x_freq['Training set'] = df_train.groupby('date_x')['activity_id'].count()
date_x_freq['Testing set'] = df_test.groupby('date_x')['activity_id'].count()
date_x_freq.plot(secondary_y='Testing set', figsize=(20, 8), 
                 title='Comparison of date_x distribution between training/testing set')
date_y_freq = pd.DataFrame()
date_y_freq['Training set'] = df_train.groupby('date_y')['activity_id'].count()
date_y_freq['Testing set'] = df_test.groupby('date_y')['activity_id'].count()
date_y_freq[:i].plot(secondary_y='Testing set', figsize=(20, 8), 
                 title='Comparison of date_y distribution between training/testing set (first year)')
date_y_freq[2*i:].plot(secondary_y='Testing set', figsize=(20, 8), 
                 title='Comparison of date_y distribution between training/testing set (last year)

Le résultat est le suivant.

__results___10_1.png __results___10_2.png __results___10_3.png

Vérifiez la similitude avec les données de train du coefficient de corrélation.

correlation.py


print('Correlation of date_x distribution in training/testing sets: ' + str(np.corrcoef(date_x_freq.T)[0,1]))
print('Correlation of date_y distribution in training/testing sets: ' + str(np.corrcoef(date_y_freq.fillna(0).T)[0,1]))
Correlation of date_x distribution in training/testing sets: 0.853430807691
Correlation of date_y distribution in training/testing sets: 0.709589035055

Dans date_x, j'ai trouvé une structure similaire dans les données d'entraînement et de test. Cela signifie que les données de formation et de test sont réparties en fonction des personnes et non du temps ou d'autres facteurs. De même, les caractéristiques peuvent être observées en septembre et octobre.

Vous pouvez voir que la corrélation est faible à date_y. Les données de test contiennent de nombreux pics au cours de la première année, et il semble que la corrélation des pics change d'année en année. Regardons la corrélation par année.

correlation_date_y.py


print('date_y correlation in year 1: ' + str(np.corrcoef(date_y_freq[:i].fillna(0).T)[0,1]))
print('date_y correlation in year 2: ' + str(np.corrcoef(date_y_freq[i:2*i].fillna(0).T)[0,1]))
print('date_y correlation in year 3: ' + str(np.corrcoef(date_y_freq[2*i:].fillna(0).T)[0,1]))
date_y correlation in year 1: 0.237056344324
date_y correlation in year 2: 0.682344221229
date_y correlation in year 3: 0.807207224857

Vous pouvez voir que la corrélation la troisième année est la plus élevée.

4.1.3. Probability features Générons la probabilité de date en tant que quantité de caractéristiques.

probability_features.py


from sklearn.metrics import roc_auc_score
features = pd.DataFrame()
features['date_x_prob'] = df_train.groupby('date_x')['outcome'].transform('mean')
features['date_y_prob'] = df_train.groupby('date_y')['outcome'].transform('mean')
features['date_x_count'] = df_train.groupby('date_x')['outcome'].transform('count')
features['date_y_count'] = df_train.groupby('date_y')['outcome'].transform('count')
_=[print(f.ljust(12) + ' AUC: ' + str(round(roc_auc_score(df_train['outcome'], features[f]), 6))) for f in features.columns]
date_x_prob  AUC: 0.626182
date_y_prob  AUC: 0.720296
date_x_count AUC: 0.465697
date_y_count AUC: 0.475916

4.2. Group_1 date trick Dans ce concours, [fonctionnalités magiques publiées sur les noyaux](https://www.kaggle.com/ijkilchenko/predicting-red-hat-business-value/python-ver-of-group-1-and-date -trick / code ) A été utilisé pour atteindre un ROC supérieur à 90%. Ici, nous allons expliquer le noyau qui explique la fonctionnalité magique.

Tout d'abord, importez la bibliothèque.

import pandas as pd
import numpy as np
import datetime
from itertools import product
from scipy import interpolate ## For other interpolation functions.

Ensuite, lisez les données et encodez le booléen à 01. Modifiez également la date en type datetime.

# Load and transform people data. 
ppl = pd.read_csv('../input/people.csv')

# Convert booleans to integers.
p_logi = ppl.select_dtypes(include=['bool']).columns
ppl[p_logi] = ppl[p_logi].astype('int')
del p_logi

# Transform date.
ppl['date'] = pd.to_datetime(ppl['date'])

Faites de même pour le fichier d'acte. Remplissez la colonne des résultats avec nan et créez-la, puis combinez entraînement et test.

# Load activities.
# Read and combine.
activs = pd.read_csv('../input/act_train.csv')
TestActivs = pd.read_csv('../input/act_test.csv')
TestActivs['outcome'] = np.nan ## Add the missing column to the test set.
activs = pd.concat([activs, TestActivs], axis=0) ## Append train and test sets.
del TestActivs

Il existe de nombreuses variables dans le fichier act, mais nous ne ciblerons que people_id, result, activity_id et date. Les activs extraits sont liés du fichier people au ppl de lecture (people_id) et fusionnés.

# Extract only required variables.
activs = activs[['people_id', 'outcome', 'activity_id', 'date']] ## Let's look at these columns only.
# Merge people data into activities.
## This keeps all the rows from activities.
d1 = pd.merge(activs, ppl, on='people_id', how='right')
## These are the indices of the rows from the test set.
testset = ppl[ppl['people_id'].isin(d1[d1['outcome'].isnull()]['people_id'])].index

    d1['activdate'] = pd.to_datetime(d1['date_x'])

    del activs

4.3. Évaluation du résultat et du groupe_1, car_38

Tout d'abord, visualisons les données. Exemple ici n'inclut pas un exemple de script Cependant, le contenu de l'analyse est très simple. Le but ici est le suivant.

4.3.1. Que signifie char_38?

Regardons char_38, qui est la seule valeur continue donnée. Voici le résultat de la division de char_38 du train par le résultat.

unnamed-chunk-2-1.png

Il a une distribution assez caractéristique. Ensuite, comparez la distribution de char_38 avec train et test.

unnamed-chunk-3-1.png

Vous pouvez voir qu'ils ont presque la même distribution. Examinons ensuite la relation entre les données sur les personnes et les résultats. Tracez les clients avec tous les résultats 0 et 1 et les clients avec 0 et 1 dans un graphique à barres.

unnamed-chunk-4-1.png

Vous pouvez voir que presque tous les clients sont biaisés vers 0 ou 1. Enfin, visualisez la relation entre char_38 et ROC. Examinons ici le résultat de la prédiction lorsque vous n'utilisez que 0 ou 1 données client et le résultat de la prédiction des données client comprenant les deux. La description de dmi3kno ne décrit pas spécifiquement quel algorithme a été utilisé, mais je pense qu'il utilise probablement XGBoost.

unnamed-chunk-5-1.png

À partir des résultats ci-dessus, il a été constaté que les résultats de presque tous les clients peuvent être prédits avec une assez grande précision simplement en utilisant char_38. D'autre part, nous pouvons voir que l'estimation des clients qui ont changé de résultat en cours de route est faible.

4.3.2. Caractéristiques des fonctions magiques

Tout d'abord, regardons le statut de 6 clients qui ont changé leur résultat au milieu du processus dans l'ordre chronologique.

unnamed-chunk-6-1.png

Vous pouvez voir que de nombreux clients ne modifient le résultat qu'une seule fois pendant l'observation. Le problème cette fois est l'analyse des données de séries chronologiques qui prédit des changements dans ce résultat. Ensuite, regardons quand un cluster de clients particulier a changé le résultat. Regardons une variable qui contient peu de valeurs manquantes, ici la variable group_1. Regardons le même graphique que précédemment avec 6 group_1 sélectionnés au hasard.

unnamed-chunk-7-1.png

Vous pouvez voir que les changements sont exactement les mêmes que lorsqu'ils sont représentés graphiquement avec people_id. En d'autres termes, le but de cette compétition sera le problème de prédire le point de changement pour chaque groupe_1.

unnamed-chunk-8-1.png

Ces "éléments intermédiaires" doivent être ramenés dans leurs groupes respectifs (0 ou 1).

4.3.3. Questions

L'analyse à ce jour soulève quelques questions.

En regardant ces derniers, cela devient comme suit.

unnamed-chunk-9-1.png

Ici, ambivalent est un groupe contenant à la fois 0 et 1, uniforme est un groupe n'ayant qu'un seul 0 et 1, et unknown est un groupe unique au groupe de test. Voyons ensuite combien d'activités chaque groupe contient. Par exemple, si vous les prédisez de manière aléatoire (sans indicateur clair), vous pouvez voir quel sera le score le plus élevé en termes de maximisation d'entropie. L'utilisation de XGBoost et char_38 vous donnera un indice à ce sujet.

unnamed-chunk-10-1.png

Autre chose, dans le groupe ambivalent, nous regarderons combien de fois le résultat a changé. unnamed-chunk-11-1.png

le rebond est un groupe dans lequel des changements bidirectionnels se produisent de 0 à 1 et de 1 à 0. Parmi ces rebonds, nous examinerons certains groupes qui ont changé plus d'une fois.

## 
##     0     1     2     3 
## 25646  3687   565     1

Enfin, nous visualisons certains de ces groupes dont les résultats ont changé plusieurs fois.

unnamed-chunk-13-1.png

Recommended Posts

Résumé de Kaggle: Redhat (Partie 1)
Résumé de Kaggle: Redhat (partie 2)
Résumé de Kaggle: Outbrain # 2
Résumé de Kaggle: Outbrain # 1
Résumé lié à Kaggle
Kaggle ~ Analyse du logement ③ ~ Part1
Résumé de Kaggle: BOSCH (noyaux)
Résumé Kaggle: BOSCH (gagnant)
Résumé de la méthode du noyau de Kaggle [Image]
Résumé des connaissances de base de PyPy Partie 1
Résumé de Kaggle: Analyse du panier de marché Instacart
Résumé de Kaggle: BOSCH (intro + discussion du forum)
[Enquête] Kaggle - Résumé de la solution Quora 3e place
2014/02/28 Résumé du contenu démo à #ssmjp, partie 1
[Enquête] Kaggle - Résumé de la solution Quora 5e place
[Enquête] Kaggle - Résumé de la solution Quora 4e place
[Enquête] Kaggle - Récapitulatif de la solution Quora 2nd place
Mémorandum Kaggle ~ PNL avec tweets de catastrophe, partie 1 ~
Kaggle: Introduction à l'ingénierie manuelle des fonctionnalités, partie 1