web-dev-qa-db-fra.com

Analyse de régression linéaire avec des caractéristiques de chaîne / catégoriques (variables)?

Les algorithmes de régression semblent fonctionner sur des entités représentées par des nombres. Par exemple:

enter image description here

Cet ensemble de données ne contient pas de caractéristiques/variables catégoriques. Il est assez clair comment faire une régression sur ces données et prédire le prix.


Mais maintenant, je veux faire une analyse de régression sur des données contenant des caractéristiques catégorielles:

enter image description here

Il y a 5 fonctionnalités: District, Condition, Material, Security , Type


Comment puis-je faire une régression sur ces données? Dois-je transformer toutes ces données chaîne/catégoriques en nombres manuellement? Je veux dire si je dois créer des règles de codage et transformer celles-ci en données numériques. Existe-t-il un moyen simple de transformer des données de chaîne en nombres sans avoir à créer manuellement leurs propres règles de codage? Peut-être y a-t-il des bibliothèques en Python qui peuvent être utilisées pour cela? Existe-t-il des risques que le modèle de régression soit en quelque sorte incorrect en raison d'un "mauvais codage"?

33
Erba Aitbayev

Oui, vous devrez tout convertir en chiffres. Cela nécessite de réfléchir à ce que représentent ces attributs.

Il y a généralement trois possibilités:

  1. One-Hot encoding pour les données catégorielles
  2. Nombres arbitraires pour les données ordinales
  3. Utilisez quelque chose comme la moyenne des groupes pour les données catégorielles (par exemple, les prix moyens des quartiers urbains).

Vous devez faire attention à ne pas infuser des informations que vous ne possédez pas dans le dossier d'inscription.

Un encodage à chaud

Si vous avez des données catégorielles, vous pouvez créer des variables factices avec des valeurs 0/1 pour chaque valeur possible.

Par exemple.

idx color
0   blue
1   green
2   green
3   red

à

idx blue green red
0   1    0     0
1   0    1     0
2   0    1     0
3   0    0     1

Cela peut facilement être fait avec des pandas:

import pandas as pd

data = pd.DataFrame({'color': ['blue', 'green', 'green', 'red']})
print(pd.get_dummies(data))

aura pour résultat:

   color_blue  color_green  color_red
0           1            0          0
1           0            1          0
2           0            1          0
3           0            0          1

Nombres pour les données ordinales

Créez un mappage de vos catégories triables, e. g. ancien <rénové <nouveau → 0, 1, 2

C'est également possible avec les pandas:

data = pd.DataFrame({'q': ['old', 'new', 'new', 'ren']})
data['q'] = data['q'].astype('category')
data['q'] = data['q'].cat.reorder_categories(['old', 'ren', 'new'], ordered=True)
data['q'] = data['q'].cat.codes
print(data['q'])

Résultat:

0    0
1    2
2    2
3    1
Name: q, dtype: int8

Utilisation de données catégoriques pour les opérations groupby

Vous pouvez utiliser la moyenne de chaque catégorie par rapport aux événements passés.

Supposons que vous ayez un DataFrame avec les derniers prix moyens connus pour les villes:

prices = pd.DataFrame({
    'city': ['A', 'A', 'A', 'B', 'B', 'C'],
    'price': [1, 1, 1, 2, 2, 3],
})
mean_price = prices.groupby('city').mean()
data = pd.DataFrame({'city': ['A', 'B', 'C', 'A', 'B', 'A']})

print(data.merge(mean_price, on='city', how='left'))

Résultat:

  city  price
0    A      1
1    B      2
2    C      3
3    A      1
4    B      2
5    A      1
62
MaxNoe

Vous pouvez utiliser "Codage factice" dans ce cas. Il existe des Python pour coder des données factices, vous avez quelques options.

Vous pouvez utiliser la bibliothèque scikit-learn. Jetez un oeil à ici .

Ou, si vous travaillez avec des pandas, il a une fonction intégrée pour créer des variables factices. Vérifiez this .

Un exemple avec pandas est ci-dessous:

import pandas as pd

sample_data = [[1,2,'a'],[3,4,'b'],[5,6,'c'],[7,8,'b']]
df = pd.DataFrame(sample_data, columns=['numeric1','numeric2','categorical'])
dummies = pd.get_dummies(df.categorical)
df.join(dummies)
8
burhan

En régression linéaire avec des variables catégorielles, vous devez faire attention au piège des variables factices. Le piège des variables nominales est un scénario dans lequel les variables indépendantes sont multicolinéaires - un scénario dans lequel deux variables ou plus sont fortement corrélées; en termes simples, une variable peut être prédite à partir des autres. Cela peut produire la singularité d'un modèle, ce qui signifie que votre modèle ne fonctionnera tout simplement pas. Lisez à ce sujet ici

L'idée est d'utiliser l'encodage de variable factice avec drop_first=True, cette option omettra une colonne de chaque catégorie après la conversion de la variable catégorielle en variables indicatrices/factices. VOUS NE FAUT PAS perdre toute information pertinente en le faisant simplement parce que tous vos points dans le jeu de données peuvent être entièrement expliqués par le reste des entités.

Voici un code complet expliquant comment vous pouvez le faire pour votre jeu de données de logement

Donc, vous avez des caractéristiques catégoriques:

District, Condition, Material, Security, Type

Et une des caractéristiques numériques que vous essayez de prédire:

Price

Tout d’abord, vous devez fractionner votre jeu de données initial sur les variables d’entrée et la prédiction, en supposant que son dataframe pandas) ressemblerait à ceci:

Variables d'entrée:

X = housing[['District','Condition','Material','Security','Type']]

Prédiction:

Y = housing['Price']

Convertissez une variable catégorielle en variable factice/indicatrice et en en supprimez une dans chaque catégorie:

X = pd.get_dummies(data=X, drop_first=True)

Alors maintenant, si vous vérifiez la forme de X avec drop_first=True vous verrez qu'il a 4 colonnes de moins - une pour chacune de vos variables catégorielles.

Vous pouvez maintenant continuer à les utiliser dans votre modèle linéaire. Pour l'implémentation de scikit-learn, cela pourrait ressembler à ceci:

from sklearn import linear_model
from sklearn.model_selection import train_test_split
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = .20, random_state = 40)
        regr = linear_model.LinearRegression() # Do not use fit_intercept = False if you have removed 1 column after dummy encoding
        regr.fit(X_train, Y_train)
    predicted = regr.predict(X_test)
5
Harvey

Une façon de réaliser une régression avec des variables catégorielles en tant que variables indépendantes est comme mentionné ci-dessus - Utilisation du codage. Une autre façon de faire consiste à utiliser R comme une formule statistique utilisant la bibliothèque de modèles de statistiques. Voici un extrait de code

from statsmodels.formula.api import ols
tips = sns.load_dataset("tips")

model = ols('tip ~ total_bill + C(sex) + C(day) + C(day) + size', data=tips)
fitted_model = model.fit()
fitted_model.summary()

Ensemble de données

total_bill  tip     sex  smoker day  time  size
0   16.99   1.01    Female  No  Sun Dinner  2
1   10.34   1.66    Male    No  Sun Dinner  3
2   21.01   3.50    Male    No  Sun Dinner  3
3   23.68   3.31    Male    No  Sun Dinner  2
4   24.59   3.61    Female  No  Sun Dinner  4

Résumé de la régression

enter image description here

1
ShikharDua