[PYTHON] J'ai essayé l'analyse factorielle avec des données Titanic!

Aperçu

En utilisant les données Titanic qui sont souvent utilisées au début de kaggle, J'ai essayé l'analyse factorielle. Cependant, cette fois, cela n'a pas été fait à des fins de prédiction. Le but était simplement d'observer les caractéristiques des données à l'aide d'une méthode d'analyse statistique. J'ai donc décidé d'effectuer une analyse factorielle sur les données train / test.

supposition

―― Qu'est-ce que l'analyse factorielle? Envisagez d'exprimer les variables explicatives comme une «combinaison linéaire de facteur commun et de facteur unique».

X=FA+UB

$ X: Données (nombre de données (N) x nombre de variables explicatives (n)) $ $ F: matrice de facteurs communs (N x nombre de facteurs (m)) $

(Chaque élément $ a_ {ij} $ du chargement factoriel A est Dans les conditions d'analyse suivantes (1) et (2), qui est également l'analyse de cet article, C'est la valeur de corrélation entre le facteur commun $ F_ {i} $ et la variable explicative $ X_ {i} $.

① Facteur commun: facteur orthogonal (2) Variable explicative: normalisée et utilisée (moyenne 0 distribution 1) )

Dans l'analyse factorielle, cette quantité de charge factorielle A est obtenue. En saisissant les caractéristiques des facteurs communs à partir du chargement factoriel obtenu Les facteurs communs sont souvent utilisés comme résumé des données.

Analysis_Overview

Analyse_Détails

  1. Importation de la bibliothèque
import os
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display
from sklearn.decomposition import PCA
  1. Définition de variable (destination de stockage de données csv titanesques, etc.)
#Dossier en cours
forlder_cur = os.getcwd()
print(" forlder_cur : {}".format(forlder_cur))
print(" isdir:{}".format(os.path.isdir(forlder_cur)))

#emplacement de stockage des données
folder_data = os.path.join(forlder_cur , "data")
print(" folder_data : {}".format(folder_data))
print(" isdir:{}".format(os.path.isdir(folder_data)))

#fichier de données

## train.csv
fpath_train = os.path.join(folder_data , "train.csv")
print(" fpath_train : {}".format(fpath_train))
print(" isdir:{}".format(os.path.isfile(fpath_train)))

## test.csv
fpath_test = os.path.join(folder_data , "test.csv")
print(" fpath_test : {}".format(fpath_test))
print(" isdir:{}".format(os.path.isfile(fpath_test)))

# id
id_col = "PassengerId"

#Variable objectif
target_col = "Survived"
  1. Importez les données Titanic Les données "all_data" (train + test) créées par le code ci-dessous seront utilisées ultérieurement.
# train.csv
train_data = pd.read_csv(fpath_train)
print("train_data :")
print("n = {}".format(len(train_data)))
display(train_data.head())

# test.csv
test_data = pd.read_csv(fpath_test)
print("test_data :")
print("n = {}".format(len(test_data)))
display(test_data.head())

# train_and_test
col_list = list(train_data.columns)
tmp_test = test_data.assign(Survived=None)
tmp_test = tmp_test[col_list].copy()
print("tmp_test :")
print("n = {}".format(len(tmp_test)))
display(tmp_test.head())

all_data = pd.concat([train_data , tmp_test] , axis=0)
print("all_data :")
print("n = {}".format(len(all_data)))
display(all_data.head())

all_data.jpg

  1. Prétraitement La conversion de variable factice, la complétion manquante et la suppression de variable sont effectuées pour chaque variable, et les données créées "proc_all_data" seront utilisées ultérieurement.
#copie
proc_all_data = all_data.copy()

# Sex -------------------------------------------------------------------------
col = "Sex"

def app_sex(x):
    if x == "male":
        return 1
    elif x == 'female':
        return 0
    #Disparu
    else:
        return 0.5
proc_all_data[col] = proc_all_data[col].apply(app_sex)

print("columns:{}".format(col) , "-" * 40)
display(all_data[col].value_counts())
display(proc_all_data[col].value_counts())
print("n of missing :" , len(proc_all_data.query("{0} != {0}".format(col))))

# Age -------------------------------------------------------------------------
col = "Age"

medi = proc_all_data[col].median()
proc_all_data[col] = proc_all_data[col].fillna(medi)

print("columns:{}".format(col) , "-" * 40)
display(all_data[col].value_counts())
display(proc_all_data[col].value_counts())
print("n of missing :" , len(proc_all_data.query("{0} != {0}".format(col))))
print("median :" , medi)

# Fare -------------------------------------------------------------------------
col = "Fare"

medi = proc_all_data[col].median()
proc_all_data[col] = proc_all_data[col].fillna(medi)

print("columns:{}".format(col) , "-" * 40)
display(all_data[col].value_counts())
display(proc_all_data[col].value_counts())
print("n of missing :" , len(proc_all_data.query("{0} != {0}".format(col))))
print("median :" , medi)

# Embarked -------------------------------------------------------------------------
col = "Embarked"

proc_all_data = pd.get_dummies(proc_all_data , columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

# Cabin -------------------------------------------------------------------------
col = "Cabin"

proc_all_data = proc_all_data.drop(columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

# Ticket -------------------------------------------------------------------------
col = "Ticket"

proc_all_data = proc_all_data.drop(columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

# Name -------------------------------------------------------------------------
col = "Name"

proc_all_data = proc_all_data.drop(columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

# Embarked_C -------------------------------------------------------------------------
col = "Embarked_C"

proc_all_data = proc_all_data.drop(columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

# Embarked_Q -------------------------------------------------------------------------
col = "Embarked_Q"

proc_all_data = proc_all_data.drop(columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

# Embarked_S -------------------------------------------------------------------------
col = "Embarked_S"

proc_all_data = proc_all_data.drop(columns=[col])

print("columns:{}".format(col) , "-" * 40)
display(all_data.head())
display(proc_all_data.head())

proc_all_data : proc_all_data.jpg

  1. Analyse factorielle 5-1. Normalisation, ajustement Après avoir normalisé les variables explicatives, effectuez une analyse factorielle.
#Variable explicative
feature_cols = list(set(proc_all_data.columns) - set([target_col]) - set([id_col]))
print("feature_cols :" , feature_cols)
print("len of feature_cols :" , len(feature_cols))

features_tmp = proc_all_data[feature_cols]
print("features(Avant la normalisation):")
display(features_tmp.head())

#Standardisation
ss = StandardScaler()
features = pd.DataFrame(
    ss.fit_transform(features_tmp)
    , columns=feature_cols
)
print("features(Après normalisation):")
display(features.head())

fonctionnalités (avant et après la normalisation): standardscaler.jpg

5-2. Matrice de chargement des facteurs

#Analyse factorielle
n_components = 2
fact_analysis = FactorAnalysis(n_components=n_components)
fact_analysis.fit(features)

#Matrice de chargement factoriel(X = FA +UB A)
print("Matrice de chargement factoriel(X = FA +UB A) :")
components_df = pd.DataFrame(
    fact_analysis.components_
    ,columns=feature_cols
)
display(components_df)

components_df: factor_loadings.jpg

5-3. [Référence] ① Matrice factorielle ② Corrélation entre facteurs ③ "Corrélation entre la matrice de chargement factoriel (A) - facteur (F) et variable explicative (X)" Ceci est une sortie pour référence. Concernant (2), confirmez qu'il s'agit d'un facteur orthogonal. À propos de ③ Cette fois, les variables explicatives sont des facteurs standardisés et orthogonaux, donc Confirmez que la différence est de 0 (bien qu'il y ait une erreur car il s'agit d'une solution approximative).

#facteur
print("Matrice factorielle(X = FA +UB F) :")
fact_columns = ["factor_{}".format(i+1) for i in range(n_components)]
factor_df = pd.DataFrame(
    fact_analysis.transform(features)
    , columns=fact_columns
)
display(factor_df)

#Corrélation entre les facteurs
corr_fact_df = factor_df.corr()
print("Corrélation entre les facteurs:")
display(corr_fact_df)

#Corrélation entre les facteurs(Notation fractionnaire)
def show_float(x):
    return "{:.5f}".format(x)
print("* Notation fractionnaire:")
display(corr_fact_df.applymap(show_float))

# [Matrice de chargement factoriel(A)] - [facteur(F)Et variables explicatives(X)Corrélation de]
##facteur(F)Et variables explicatives(X)Corrélation de
fact_exp_corr_df = pd.DataFrame()
for exp_col in feature_cols:
    data = list()
    for fact_col in fact_columns:
        x = features[exp_col]
        f = factor_df[fact_col]
        data.append(x.corr(f))
    fact_exp_corr_df[exp_col] = data
print("facteur(F)Et variables explicatives(X)Corrélation de:")
display(fact_exp_corr_df)

print("[Matrice de chargement factoriel(A)] - [facteur(F)Et variables explicatives(X)Corrélation de]:")
display(components_df - fact_exp_corr_df)

factor_matrix.jpg check_corr.jpg

5-4. Création du graphe _1 / 2 (Vérifier le chargement des facteurs pour chaque facteur)

#Graphisme(Graphique à barres / lignes brisées_Charge factorielle de chaque facteur)
for i in range(len(fact_columns)):
    #Charge du facteur cible
    fact_col = fact_columns[i]
    component = components_df.iloc[i]
    #Montant de la charge et sa valeur absolue, rang de la valeur absolue
    df = pd.DataFrame({
        "component":component
        , "abs_component":component.abs()
    })
    df["rank_component"] = df["abs_component"].rank(ascending=False)
    df.sort_values(by="rank_component" , inplace=True)
    print("[{}]".format(fact_col) , "-" * 80)
    display(df)
    
    #Graphisme(Graphique à barres: chargement du facteur, ligne de rupture: valeur absolue)
    x_ticks = df.index.tolist()
    x_ticks_num = [i for i in range(len(x_ticks))]
    fig = plt.figure(figsize=(12 , 5))
    plt.bar(x_ticks_num , df["component"] , label="factor loadings" , color="c")
    plt.plot(x_ticks_num , df["abs_component"] , label="[abs] factor loadings" , color="r" , marker="o")
    plt.legend()
    plt.xticks(x_ticks_num , labels=x_ticks)
    plt.xlabel("features")
    plt.ylabel("factor loadings")
    plt.show()
    
    fig.savefig("bar_{}.png ".format(fact_col))

graph_1_fact_1.jpg graph_1_fact_2.jpg

5-5. Graphing_2 / 2 (Tracer les chargements de facteurs sur deux axes composés des deux facteurs)

#Graphisme(Charge factorielle de deux facteurs)

#Fonction d'affichage graphique
def plotting_fact_load_of_2_fact(x_fact , y_fact):
    #Trame de données pour graphique
    df = pd.DataFrame({
        x_fact : components_df.iloc[0].tolist()
        , y_fact : components_df.iloc[1].tolist()    
        }
        ,index = components_df.columns
    )

    fig = plt.figure(figsize=(10 , 10))
    for exp_col in df.index.tolist():
        data = df.loc[exp_col]
        x_label = df.columns.tolist()[0]
        y_label = df.columns.tolist()[1]
        x = data[x_label]
        y = data[y_label]
        plt.plot(x
                 , y
                 , label=exp_col
                 , marker="o"
                 , color="r")
        plt.annotate(exp_col , xy=(x , y))
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.grid()
    
    print("x = [{x_fact}] , y = [{y_fact}]".format(
        x_fact=x_fact
        , y_fact=y_fact
    ) , "-" * 80)
    display(df)
    plt.show()
    fig.savefig("plot_{x_fact}_{y_fact}.png ".format(
        x_fact=x_fact
        , y_fact=y_fact
    ))

#affichage graphique
plotting_fact_load_of_2_fact("factor_1" , "factor_2")

En principe, la plage de valeurs de la classe P (classe passager) va de 1 à 3, et il semble que la plus petite soit la plus élevée.

À propos du premier facteur La charge factorielle du tarif (frais d'embarquement) est importante et la classe P (classe passager) est petite. (Autrement dit, plus la classe est élevée, plus la charge factorielle est élevée) Donc, le premier facteur est "Indicateur pour évaluer la richesse" Il semble que vous puissiez y penser.

À propos du deuxième facteur En valeurs absolues, Parch (nombre de parents et d'enfants) et SibSp (nombre de frères et sœurs et de conjoints) sont à la fois grands et positifs. Le deuxième facteur est donc "Indicateur du nombre de familles" Il semble que vous puissiez y penser.

graph_2_table.jpg plot_factor_1_factor_2.png

Résumé

À la suite d'une analyse factorielle avec deux facteurs Comme premier facteur, «un indice pour évaluer la richesse» Et comme deuxième facteur, "un index indiquant le nombre de familles" a été obtenu.

Le premier facteur est "Premier composant principal lors de la précédente analyse en composants principaux" C'est devenu un index similaire à. Dans un livre d'analyse multivariée Il a été déclaré que l’essence de l’analyse en composantes principales et de l’analyse factorielle est la même, C'est un sentiment que le résultat le montre clairement.

Recommended Posts

J'ai essayé l'analyse factorielle avec des données Titanic!
J'ai essayé d'analyser les principaux composants avec les données du Titanic!
Analyse des données Titanic 1
Analyse des données Titanic 3
J'ai essayé l'analyse de régression multiple avec régression polypoly
J'ai essayé d'apprendre avec le Titanic de Kaggle (kaggle②)
Analyse de données avec python 2
Analyse de données avec Python
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé d'obtenir des données CloudWatch avec Python
J'ai essayé de prédire la survie du Titanic avec PyCaret
J'ai essayé DBM avec Pylearn 2 en utilisant des données artificielles
J'ai essayé l'analyse de données IRMf avec python (Introduction au décodage des informations cérébrales)
J'ai essayé fp-growth avec python
J'ai essayé Learning-to-Rank avec Elasticsearch!
J'ai essayé de prédire le match de la J League (analyse des données)
[OpenCV / Python] J'ai essayé l'analyse d'image de cellules avec OpenCV
J'ai essayé le clustering avec PyCaret
J'ai essayé de collecter des données sur un site Web avec Scrapy
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
J'ai essayé de prédire et de soumettre les survivants du Titanic avec Kaggle
J'ai essayé de créer diverses "données factices" avec Python faker
J'ai essayé d'analyser les données scRNA-seq en utilisant l'analyse des données topologiques (TDA)
J'ai essayé AdaNet pour les données de table
J'ai essayé de résumer des phrases avec summpy
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé webScraping avec python.
J'ai essayé de déplacer de la nourriture avec SinGAN
J'ai essayé d'implémenter DeepPose avec PyTorch
J'ai essayé la détection de visage avec MTCNN
J'ai joué avec Mecab (analyse morphologique)!
Analyse de données à partir de python (visualisation de données 1)
J'ai essayé d'exécuter prolog avec python 3.8.2.
J'ai essayé la communication SMTP avec Python
J'ai essayé la génération de phrases avec GPT-2
Analyse de données à partir de python (visualisation de données 2)
J'ai essayé d'apprendre LightGBM avec Yellowbrick
J'ai essayé la reconnaissance faciale avec OpenCV
J'ai essayé la même analyse de données avec kaggle notebook (python) et PowerBI en même temps ②
J'ai essayé la même analyse de données avec kaggle notebook (python) et PowerBI en même temps ①
[Pandas] J'ai essayé d'analyser les données de ventes avec Python [Pour les débutants]
J'ai essayé de récupérer les données de conversation d'ASKfm
J'ai essayé d'envoyer un SMS avec Twilio
J'ai essayé d'utiliser Amazon SQS avec django-celery
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé linebot avec flacon (anaconda) + heroku
J'ai essayé de visualiser AutoEncoder avec TensorFlow
Vérifiez les données brutes avec Kaggle's Titanic (Kaggle ⑥)
J'ai essayé de commencer avec Hy
J'ai essayé l'analyse de séries chronologiques! (Modèle AR)
J'ai essayé d'utiliser du sélénium avec du chrome sans tête
J'ai essayé le rendu non réaliste avec Python + opencv
J'ai essayé un langage fonctionnel avec Python
J'ai essayé la récurrence avec Python ② (séquence de nombres Fibonatch)