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.
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.
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.
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
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.
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))
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.
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.
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
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.
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.
Il a une distribution assez caractéristique. Ensuite, comparez la distribution de char_38 avec train et test.
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.
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.
À 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.
Tout d'abord, regardons le statut de 6 clients qui ont changé leur résultat au milieu du processus dans l'ordre chronologique.
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.
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.
Ces "éléments intermédiaires" doivent être ramenés dans leurs groupes respectifs (0 ou 1).
L'analyse à ce jour soulève quelques questions.
En regardant ces derniers, cela devient comme suit.
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.
Autre chose, dans le groupe ambivalent, nous regarderons combien de fois le résultat a changé.
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.
Recommended Posts