Lors de la création d'un modèle d'apprentissage automatique avec certaines données de table, il y avait une variable que je voulais éliminer la différence entre les classes, j'ai donc implémenté ce processus.
Le sous-échantillonnage est effectué pour chaque attribut dans chaque section spécifiée. Cette fois, nous avons utilisé des données titanesques de mer pour faire correspondre le nombre de personnes à chaque âge d'adolescent entre les groupes «oui» et «non» avec vivant. ..
OS:Windows10 conda:4.8.3 python:3.8.3 pandas:0.25.3 matplotlib:3.3.1 seaborn:0.11.0
Obtenez les données comme suit.
load_dataset.py
import seaborn as sns
data = sns.load_dataset("titanic")
Concernant les données acquises, la répartition par âge de chaque adolescent par vivant (statut de survie) est la suivante.
display_gragh.py
import matplotlib.pyplot as plt
sns.set_style(style='darkgrid')
fig, ax = plt.subplots(1,1, figsize=(4,4))
ax.set_xticks(range(0,100,10))
ax.set_ylim(0,150)
ax.set_ylabel('the number of people')
sns.distplot(data['age'][data['alive']=='yes'], kde=False, rug=False, bins=range(0,100,10),
label='alive', ax=ax)
sns.distplot(data['age'][data['alive']=='no'], kde=False, rug=False, bins=range(0,100,10),
label='dead', ax=ax)
ax.legend()
plt.show()
J'ai créé la fonction suivante pour la correspondance des données.
import pandas as pd
def adjust_number(data, target_column, attribute, period):
'''
target_column:Nom de colonne à ajuster
attribute :Attribut à ajuster (Ajuster le nombre de colonnes cibles entre ces attributs)
period :Largeur de section à régler
'''
##Réglage de la section initiale
#La limite inférieure commence à 0 si la valeur minimale du groupe de données cible est égale ou supérieure à 0, et commence à partir de la valeur minimale si elle est inférieure à 0.
lower = 0 if data[target_column].min() >= 0 else data[target_column].min()
#La limite supérieure est la limite inférieure + la largeur de la section-À partir de 1
upper = lower+period-1
data_adjusted = pd.DataFrame() #Pour stocker les données ajustées
maximum = data[target_column].max() #Obtenir la valeur maximale du groupe de données à ajuster
#Répétez jusqu'à ce que la limite inférieure dépasse la valeur maximale
while lower <= maximum:
#Extraire les données de la section cible
data_in_range = data[(lower<=data.loc[:,target_column]) & (data.loc[:,target_column]<=upper)]
#S'il n'y a pas de données dans la section cible ou s'il existe un attribut pour lequel il n'y a pas de données dans la section cible, passez à la section suivante
#(En raison du sous-échantillonnage, si le nombre de données d'un attribut est égal à 0, tout sera égal à 0)
if len(data_in_range) == 0 or set(data[attribute]) != set(data_in_range[attribute]):
lower += period
upper += period
continue
else:
#Acquérir le nombre de données pour chaque attribut dans la section cible
counts = data_in_range[attribute].value_counts()
#Sous-échantillonnage pour chaque attribut
sample = pd.DataFrame()
for att in counts.index:
sample = data_in_range[data_in_range[attribute]==att].sample(n=counts.min(), random_state=42)
#Concaténer les données ajustées de la section cible aux données ajustées stockées
data_adjusted = pd.concat([data_adjusted, sample],axis=0, ignore_index=True)
#Vers la section suivante
lower += period
upper += period
return data_adjusted
La répartition par âge de chaque adolescent après le traitement avec cette fonction (après appariement des âges) est la suivante. Il est affiché à nouveau avant la correction.
data_adjusted = adjust_number(data, target_column='age', attribute='alive', period=10)
fig, ax = plt.subplots(1,1, figsize=(4,4))
ax.set_xticks(range(0,100,10))
ax.set_ylim(0,150)
ax.set_ylabel('the number of people')
sns.distplot(data_adjusted['age'][data_adjusted['alive']=='yes'], kde=False, rug=False, bins=range(0,100,10),
label='alive', ax=ax)
sns.distplot(data_adjusted['age'][data_adjusted['alive']=='no'], kde=False, rug=False, bins=range(0,100,10),
label='dead', ax=ax)
ax.legend()
plt.show()
▼ Après correction ▼ Avant correction
J'ai pu le corriger en toute sécurité.
Même si j'ai changé la largeur de section de 10 à 5 (correspondant au nombre de personnes tous les 5 ans), cela a fonctionné sans problème.
data_adjusted = adjust_number(data, target_column='age', attribute='alive', period=5)
▼ Après correction ▼ Avant correction
Il n'y a pas de problème même si l'objectif d'ajustement est changé en tarif.
data_adjusted = adjust_number(data, target_column='fare', attribute='alive', period=30)
▼ Après correction ▼ Avant correction
Il n'y a pas de problème même si l'attribut cible est changé en sexe (genre).
data_adjusted = adjust_number(data, target_column='age', attribute='sex', period=10)
▼ Après correction ▼ Avant correction
C'est tout. Merci pour votre visite.
Recommended Posts