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.
―― 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: 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.
import os
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display
from sklearn.decomposition import PCA
#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"
# 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())
#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 :
#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):
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:
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)
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))
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.
À 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