J'exécute une régression avec mon observation au niveau de l'entreprise. Je veux contrôler le type d'entreprise [que produit-elle]. J'ai ces informations dans une variable d'objet que je transforme en catégorielle et en retire les mannequins.
reg = sm.OLS(endog=df['Y'], exog= df[['X1', 'Number of workers', 'X2', "Product Type_Jewellery", "Product_Type_Apparel", (all the other product dummies) ]], missing='drop')
Mon échantillon est assez volumineux et je finis par avoir beaucoup de variables factices. C'est pas mal de travail de les introduire dans mon modèle un par un (il peut y en avoir 10 à 15).
df['Product Type'] = df['Product Type'].astype('category') df = pd.get_dummies(df, columns=['Product Type']).head()
Existe-t-il un moyen plus efficace de le faire? Dans les stata, j'ai utilisé le préfixe i.Product_Type qui signalerait au logiciel que la variable String devait être considérée comme une variable catégorielle ... quelque chose de similaire?
3 Réponses :
Utilisez str.contains
pour trouver les colonnes qui contiennent "Product_ *", et y accéder devient facile.
subset = df[['X1', 'Number of workers', 'X2', *c]] reg = sm.OLS(endog=df['Y'], exog=subset, missing='drop')
Si regex n'est pas nécessaire, vous pouvez initialiser c
comme
c = [c_ for c_ in df if c_.startswith('Product')]
Ou, en utilisant str.startswith
:
c = df.columns[df.columns.str.startswith('Product')]
Même idée que celle fournie à froid en utilisant filter
sm.OLS(endog=df['Y'], exog=df.filter(regex=r'X1|X2|Number|Product'), missing='drop')
En utilisant statsmodels.formula.api
, vous n'avez pas besoin de générer les mannequins vous-même. Supprimez les espaces de vos noms de colonne et référencez la colonne catégorielle avec C(col_name)
======================================================================================== coef std err t P>|t| [0.025 0.975] ---------------------------------------------------------------------------------------- Intercept 69.2836 23.105 2.999 0.003 23.711 114.856 C(Product_Type)[T.b] 11.3334 6.941 1.633 0.104 -2.356 25.023 C(Product_Type)[T.c] 1.3745 6.943 0.198 0.843 -12.321 15.070 C(Product_Type)[T.d] 2.0430 6.258 0.326 0.744 -10.300 14.386 C(Product_Type)[T.e] 3.8445 6.273 0.613 0.541 -8.528 16.217 X1 0.0207 0.113 0.184 0.854 -0.202 0.243 X2 1.4677 2.177 0.674 0.501 -2.825 5.761 Number_of_workers -0.5803 0.369 -1.573 0.117 -1.308 0.147 ==============================================================================
Exemple de données
import pandas as pd import numpy as np np.random.seed(123) df = pd.DataFrame({'Y': np.random.randint(1,100,200), 'X1': np.random.normal(1,20,200), 'X2': np.random.normal(-10,1,200), 'Number of workers': np.arange(1,201,1)/10, 'Product Type': np.random.choice(list('abcde'), 200)})
Puisque vous mentionnez les stata, vous devez être très explicite avec
statsmodels
. Avec votre fonctionOLS
actuelle, vous n'avez pas de terme d'interception et vous utiliserez l'ensemble complet des catégories. Stata inclurait généralement l'interception et abandonnerait à la place l'une des catégories comme catégorie de référence.merci beaucoup, je n'en étais pas au courant, comment puis-je laisser statsmodel calculer l'interception?
Le moyen le plus simple est d'ajouter une colonne de tous les
1
appelés'intercept'
à exog, quelque chose commesubset.assign (intercept = 1)
va travailler dans la solution de coldspeed. Mais vous rencontrez ensuite un problème de colinéarité, vous devez donc supprimer manuellement l'une des catégories de produits vous-même.