Análisis de regresión lineal con cadenas / características categóricas (variables)?

Los algoritmos de regresión parecen estar funcionando en características representadas como números. Por ejemplo:

introduzca la descripción de la imagen aquí

Este conjunto de datos no contiene características / variables categóricas. Es bastante claro cómo hacer una regresión en estos datos y predecir el precio.


Pero ahora quiero hacer un análisis de regresión en los datos que contienen características categóricas:

introduzca la descripción de la imagen aquí

Hay 5 características: District , Condition , Material , Security , Type


¿Cómo puedo hacer regresión sobre estos datos? ¿Tengo que transformar todos estos datos de cadena / categóricos a números manualmente? Quiero decir, si tengo que crear algunas reglas de encoding y de acuerdo con esas reglas, todos los datos se convierten en valores numéricos. ¿Existe alguna forma sencilla de transformar los datos de cadena en números sin tener que crear manualmente sus propias reglas de encoding? ¿Puede haber algunas bibliotecas en Python que puedan usarse para eso? ¿Existen algunos riesgos de que el modelo de regresión sea incorrecto debido a una “encoding incorrecta”?

Sí, tendrás que convertir todo a números. Eso requiere pensar en lo que representan estos atributos.

Normalmente hay tres posibilidades:

  1. Codificación One-Hot para datos categóricos
  2. Números arbitrarios para datos ordinales
  3. Utilice algo similar a los medios grupales para datos categóricos (por ejemplo, precios medios para distritos de la ciudad)

Debe tener cuidado de no infundir información que no tenga en el caso de solicitud.

Una codificacion en caliente

Si tiene datos categóricos, puede crear variables ficticias con valores de 0/1 para cada valor posible.

P.ej.

 idx color 0 blue 1 green 2 green 3 red 

a

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

Esto se puede hacer fácilmente con pandas:

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

resultará en:

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

Números para datos ordinales

Cree un mapeo de sus categorías clasificables, por ejemplo, antiguo

Esto también es posible con 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']) 

Resultado:

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

Uso de datos categóricos para operaciones grupales.

Podría usar la media para cada categoría en el pasado (eventos conocidos).

Supongamos que tiene un DataFrame con los últimos precios medios conocidos para las ciudades:

 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')) 

Resultado:

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

Puede utilizar la “encoding ficticia” en este caso. Hay bibliotecas de Python para hacer encoding ficticia, tienes algunas opciones.

Puedes usar la biblioteca scikit-learn. Echa un vistazo aquí .

O, si trabajas con pandas, tiene una función incorporada para crear variables ficticias. Mira esto

Un ejemplo con pandas está abajo:

 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) 

En la regresión lineal con variables categóricas, debe tener cuidado con la trampa de variables ficticias. La trampa de variables ficticias es un escenario en el que las variables independientes son multicolineales, un escenario en el que dos o más variables están altamente correlacionadas; en términos simples, una variable puede predecirse a partir de las otras. Esto puede producir la singularidad de un modelo, lo que significa que su modelo simplemente no funcionará. Lea sobre esto aquí

La idea es utilizar la encoding de variable ficticia con drop_first=True , esto omitirá una columna de cada categoría después de convertir la variable categórica en variables ficticias / indicadoras. NO perderá información relevante al hacerlo simplemente porque su rest de puntos en el conjunto de datos se puede explicar completamente con el rest de las características.

Aquí está el código completo sobre cómo puede hacerlo para su conjunto de datos de vivienda

Así que tienes características categóricas:

 District, Condition, Material, Security, Type 

Y una de las características numéricas que estás tratando de predecir:

 Price 

Primero debe dividir su conjunto de datos inicial en las variables de entrada y la predicción, asumiendo que su dataframe de pandas se vería así:

Variables de entrada:

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

Predicción:

 Y = housing['Price'] 

Convierta la variable categórica en variables ficticias / indicadoras y suelte una en cada categoría:

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

Entonces, si verifica la forma de X con drop_first=True , verá que tiene 4 columnas menos, una para cada una de sus variables categóricas.

Ahora puede continuar usándolos en su modelo lineal. Para la implementación de scikit-learn podría verse así:

 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)