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 fonctionOLSactuelle, 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
1appelé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.