Charger les données
Trouvez le chemin d’accès aux données
Copiez le chemin d’accès aux données
Chargez les bibliothèques nécessaires
Copiez le code ci-dessous et collez-le sous Google Colab :
import pandas as pd
# Demander à l'utilisateur d'entrer le chemin du fichier
file_path = input("Veuillez coller le chemin complet du fichier XLS : ")
# Charger le fichier XLS dans un DataFrame
data_original = pd.read_excel(file_path)
# Afficher le contenu du DataFrame
data_original
Installer les bibliothèques nécessaires
Copiez le code ci-dessous et collez-le sous Google Colab :
!pip install factor_analyzer
!pip install --upgrade scikit-learn
!pip install --upgrade --no-deps scikit-learn
!pip install --upgrade imbalanced-learn xgboost
Procéder à l’Analyse en Composantes Principales sans rotation
Copiez le code ci-dessous et collez-le sous Google Colab :
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from factor_analyzer import FactorAnalyzer
from factor_analyzer.factor_analyzer import calculate_kmo, calculate_bartlett_sphericity
from ipywidgets import interactive
import ipywidgets as widgets
# Fonction pour calculer l'alpha de Cronbach
def cronbach_alpha(df):
if len(df.columns) > 1:
k = df.shape[1]
variances = df.var(axis=0, ddof=1)
total_variance = df.sum(axis=1).var(ddof=1)
return (k / (k - 1)) * (1 - (variances.sum() / total_variance))
else:
print("⚠️ Pas assez de variables pour calculer l'alpha sans item.")
# Chargement des données (supposées déjà chargées dans data_original)
def select_columns(data):
print("\nColonnes disponibles :", list(data.columns))
selected_columns = input("Entrez les noms des colonnes pour l'ACP (séparées par une virgule) : ").strip().split(',')
selected_columns = [col.strip() for col in selected_columns]
if not all(col in data.columns for col in selected_columns):
print("Erreur : certaines colonnes n'existent pas. Réessayez.")
return select_columns(data)
return selected_columns
# Étape 1 : Sélection des colonnes pour l'ACP
selected_columns = select_columns(data_original)
df = data_original[selected_columns]
# Étape 2 : Normalisation des données
scaler = StandardScaler()
data_scaled = scaler.fit_transform(df)
# Étape 3 : Test KMO et Bartlett
kmo_all, kmo_model = calculate_kmo(df)
chi_square_value, p_value = calculate_bartlett_sphericity(df)
print(f"\nKMO global : {kmo_model:.3f}")
print(f"Test de Bartlett : Chi² = {chi_square_value:.3f}, p = {p_value:.3f}")
# Étape 4 : Communalités
# Affichage des communalités
fa_temp = FactorAnalyzer(rotation=None, method='principal', is_corr_matrix=False)
fa_temp.fit(data_scaled)
eigenvalues, _ = fa_temp.get_eigenvalues()
n_factors = sum(eigenvalues > 1)
print(f"Nombre de composantes retenues (valeurs propres > 1) : {n_factors}")
fa_temp = FactorAnalyzer(rotation=None, method='principal', n_factors=n_factors,is_corr_matrix=False)
fa_temp.fit(data_scaled)
communalities = pd.DataFrame({
'Variable': df.columns,
'Initial': [1.000] * len(df.columns), # Les valeurs initiales sont toujours 1
'Communalité': fa_temp.get_communalities()
}).round(3)
print("\nCommunalités des variables:")
print(communalities)
# Étape 5 : Détermination du nombre de facteurs
eigenvalues, _ = fa_temp.get_eigenvalues()
n_factors = sum(eigenvalues > 1)
print(f"Nombre de composantes retenues (valeurs propres > 1) : {n_factors}")
# Tableau des variances expliquées
explained_variance_ratio = eigenvalues / np.sum(eigenvalues)
cumulative_variance = np.cumsum(explained_variance_ratio)
variance_table = pd.DataFrame({
'Composante': [f"Composante {i+1}" for i in range(len(eigenvalues))],
'Valeurs propres': eigenvalues,
'Variance expliquée (%)': explained_variance_ratio * 100,
'Variance expliquée cumulée (%)': cumulative_variance * 100
}).round(3)
display(variance_table)
# Graphique Scree Plot
plt.figure(figsize=(8, 6))
plt.plot(range(1, len(eigenvalues) + 1), eigenvalues, marker='o')
plt.title("Graphique des valeurs propres (Scree Plot)")
plt.xlabel("Composantes")
plt.ylabel("Valeurs propres")
plt.grid(True)
plt.show()
# Étape 6 : Choix du nombre de facteurs par l'utilisateur
# Demander à l'utilisateur le nombre de composantes à retenir au moment de la sauvegarde
n_factors = int(input("Entrez le nombre de composantes à retenir pour les scores factoriels : "))
# Étape 7 : Analyse factorielle avec le nombre de facteurs sélectionné
fa = FactorAnalyzer(rotation=None, method='principal', n_factors=n_factors)
fa.fit(data_scaled)
# Matrice des charges factorielles
loadings = fa.loadings_
components_matrix = pd.DataFrame(loadings, index=df.columns).round(3)
display(components_matrix)
# Étape 8 : Cercle des corrélations
if n_factors > 1:
fig, ax = plt.subplots(figsize=(6, 6))
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.axhline(0, color='black', linestyle='-', linewidth=0.8)
ax.axvline(0, color='black', linestyle='-', linewidth=0.8)
ax.grid(True, linestyle='--', linewidth=0.5, alpha=0.7)
for i in range(loadings.shape[0]):
ax.scatter(loadings[i, 0], loadings[i, 1], color='b', alpha=0.5, s=50)
ax.text(loadings[i, 0], loadings[i, 1], df.columns[i], color='r', fontsize=8, ha='center')
ax.set_title("Cercle des corrélations", fontsize=10)
ax.set_xlabel("Composante 1")
ax.set_ylabel("Composante 2")
plt.show()
# Demander à l'utilisateur s'il souhaite une rotation
rotation_choice = input("Souhaitez-vous procéder à une rotation des variables ? (oui/non) : ").strip().lower()
if rotation_choice == "non":
fa = FactorAnalyzer(n_factors=n_factors, rotation=None, method='principal')
fa.fit(data_scaled)
factor_scores = fa.transform(data_scaled)
# Demander à l'utilisateur le nom des composantes
component_names = []
for i in range(n_factors):
name = input(f"Entrez le nom pour la composante {i+1} : ")
component_names.append(name)
components_matrix.columns = component_names
factor_scores_df = pd.DataFrame(factor_scores, columns=component_names)
# Affichage des scores factoriels
display(factor_scores_df)
# Calcul de l'alpha de cronbach
global_alpha = cronbach_alpha(df)
print(f"Alpha de Cronbach global : {global_alpha:.3f}")
alpha_sans_item = {col: cronbach_alpha(df.drop(columns=[col])) for col in selected_columns}
df_alpha = pd.DataFrame.from_dict(alpha_sans_item, orient='index', columns=['Alpha sans item']).round(3)
display(df_alpha)
############# ROTATION ##################@@
else:
rotation_types = ["varimax", "promax", "oblimin", "quartimax"]
print("Types de rotation disponibles :", rotation_types)
rotation_type = input("Veuillez entrer le type de rotation souhaité : ").strip().lower()
if rotation_type not in rotation_types:
print("Type de rotation non valide. Par défaut, 'varimax' sera utilisé.")
rotation_type = "varimax"
fa = FactorAnalyzer(n_factors=n_factors, rotation=rotation_type, method='principal')
fa.fit(data_scaled)
loadings = fa.loadings_
components_matrix = pd.DataFrame(loadings, index=df.columns).round(3)
# Affichage des scores factoriels
# display(factor_scores_df)
# Étape 8 : Cercle des corrélations
if n_factors > 1:
fig, ax = plt.subplots(figsize=(6, 6))
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
ax.axhline(0, color='black', linestyle='-', linewidth=0.8)
ax.axvline(0, color='black', linestyle='-', linewidth=0.8)
ax.grid(True, linestyle='--', linewidth=0.5, alpha=0.7)
for i in range(loadings.shape[0]):
ax.scatter(loadings[i, 0], loadings[i, 1], color='b', alpha=0.5, s=50)
ax.text(loadings[i, 0], loadings[i, 1], df.columns[i], color='r', fontsize=8, ha='center')
ax.set_title("Cercle des corrélations", fontsize=10)
ax.set_xlabel("Composante 1")
ax.set_ylabel("Composante 2")
plt.show()
# Demander à l'utilisateur le nom des composantes
component_names = []
for i in range(n_factors):
name = input(f"Entrez le nom pour la composante {i+1} : ")
component_names.append(name)
components_matrix.columns = component_names
factor_scores = fa.transform(data_scaled)
factor_scores_df = pd.DataFrame(factor_scores, columns=component_names)
# Affichage des scores factoriels
display(factor_scores_df)
global_alpha = cronbach_alpha(df)
print(f"Alpha de Cronbach global : {global_alpha:.3f}")
alpha_sans_item = {col: cronbach_alpha(df.drop(columns=[col])) for col in selected_columns}
df_alpha = pd.DataFrame.from_dict(alpha_sans_item, orient='index', columns=['Alpha sans item']).round(3)
display(df_alpha)
# Demander à l'utilisateur s'il souhaite enregistrer les résultats
def save_results():
global data_original
data_original = pd.concat([data_original, factor_scores_df], axis=1)
output_file = "Analyse_Factorielle_Resultats.xlsx"
with pd.ExcelWriter(output_file) as writer:
factor_scores_df.to_excel(writer, sheet_name="Scores_Factoriels", index=False)
df_alpha.to_excel(writer, sheet_name="Alpha_Cronbach", index=True)
print(f"\nLes résultats ont été sauvegardés dans {output_file}.")
save_btn = widgets.Button(description="Enregistrer les résultats")
save_btn.on_click(lambda b: save_results())
display(save_btn)
Procéder à la régression
Copiez le code ci-dessous et collez-le sous Google Colab :
import pandas as pd
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from statsmodels.stats.outliers_influence import variance_inflation_factor
# Sélectionner les variables explicatives (X) et la variable dépendante (y)
y_var = input("Entrez le nom de la variable dépendante : ").strip()
X_vars = input("Entrez les noms des variables explicatives (séparés par une virgule) : ").strip().split(",")
# Vérification des variables
if y_var not in data_original.columns or any(var not in data_original.columns for var in X_vars):
raise ValueError("Erreur : Assurez-vous que toutes les variables existent dans le DataFrame.")
# Définir X et y
X = data_original[X_vars] # Suppression de l'ajout de la constante
y = data_original[y_var]
# Vérifier si X contient au moins une variable
if X.shape[1] == 0:
raise ValueError("Erreur : Aucune variable explicative valide sélectionnée.")
# Ajustement du modèle OLS
model = sm.OLS(y, X).fit()
print(model.summary())
# Vérification de la normalité des résidus avec un QQ-plot
residuals = model.resid
fig, ax = plt.subplots(figsize=(6, 6))
sm.qqplot(residuals, line="s", ax=ax)
ax.set_title("QQ-Plot des résidus")
plt.show()
# Vérification de l'hétéroscédasticité avec un scatter plot
plt.figure(figsize=(8, 5))
sns.scatterplot(x=model.fittedvalues, y=residuals)
plt.axhline(0, linestyle="dashed", color="red")
plt.xlabel("Valeurs ajustées")
plt.ylabel("Résidus")
plt.title("Graphique des résidus")
plt.show()
# Calcul du VIF pour détecter la multicolinéarité
if X.shape[1] > 1: # Vérifier que le VIF peut être calculé
vif_data = pd.DataFrame({
"Variable": X.columns,
"VIF": [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
})
print("\n📊 Facteur d'inflation de la variance (VIF) :")
display(vif_data)
# Interprétation du VIF
high_vif = vif_data[vif_data["VIF"] > 10]
if not high_vif.empty:
print("\n⚠️ Attention : Certaines variables présentent une forte multicolinéarité (VIF > 10). Cela peut affecter la fiabilité des coefficients estimés.")
print(high_vif)
else:
print("✅ Aucune multicolinéarité préoccupante détectée (VIF < 10).")
else:
print("\n⚠️ Pas assez de variables pour calculer le VIF.")
# Test de normalité des résidus (Jarque-Bera)
jb_stat, jb_pvalue, skew, kurtosis = sm.stats.jarque_bera(residuals)
print("\n📊 Résultats du Test de normalité de Jarque-Bera :")
print(f" - Statistique JB : {jb_stat:.3f}")
print(f" - p-value : {jb_pvalue:.5f}")
print(f" - Asymétrie (Skewness) : {skew:.3f}")
print(f" - Aplatissement (Kurtosis) : {kurtosis:.3f}")
# Interprétation automatique
test_result = "✅ Les résidus suivent une loi normale (p > 0.05)." if jb_pvalue > 0.05 else "❌ Les résidus ne suivent PAS une loi normale (p ≤ 0.05)."
print(f"\n{test_result}")
if jb_pvalue <= 0.05:
if abs(skew) > 1:
print("🔍 Problème détecté : **Asymétrie élevée** (skewness).")
print("✅ Solution : Essayez une transformation logarithmique ou une normalisation.")
if kurtosis < 2 or kurtosis > 4:
print("🔍 Problème détecté : **Aplatissement anormal (kurtosis).**")
print("✅ Solution : Vérifiez s'il y a des valeurs aberrantes (outliers).")
print("\n📌 Recommandations supplémentaires :")
print(" - Vérifiez la présence de valeurs aberrantes avec un boxplot.")
print(" - Testez une transformation (log, carré, racine) sur la variable dépendante.")
print(" - Ajoutez éventuellement d'autres variables explicatives.")
# Conclusion générale
print("\n📌 **Conclusion** :")
print(" - L'ajustement du modèle est évalué avec le R² et le R² ajusté.")
print(" - Un R² élevé (>0.7) indique une bonne capacité explicative du modèle, tandis qu'un R² faible suggère un ajustement limité.")
print(" - Les coefficients et leurs p-values indiquent la significativité des variables explicatives : une p-value < 0.05 signifie que la variable a un impact significatif.")
print(" - Le VIF aide à détecter la multicolinéarité, qui peut biaiser les estimations.")
print(" - Le test de Jarque-Bera vérifie la normalité des résidus, influençant la validité des tests de significativité.")