Подтвердить что ты не робот

Линейный регрессионный анализ со строковыми/категориальными признаками (переменными)?

Похоже, что алгоритмы регрессии работают с функциями, представленными в виде чисел. Например:

enter image description here

Этот набор данных не содержит категориальных функций/переменных. Совершенно ясно, как сделать регрессию на этих данных и прогнозировать цену.


Но теперь я хочу сделать регрессионный анализ данных, которые содержат категориальные особенности:

enter image description here

Есть 5 функций: District, Condition, Material, Security, Type


Как я могу сделать регресс на этих данных? Нужно ли вручную преобразовывать все эти строковые/категориальные данные в числа? Я имею в виду, если мне нужно создать некоторые правила кодирования и в соответствии с этими правилами преобразовать все данные в числовые значения. Есть ли простой способ преобразовать строковые данные в числа без необходимости вручную создавать собственные правила кодирования? Может быть, в Python есть библиотеки, которые можно использовать для этого? Есть ли риск того, что регрессионная модель будет как-то неверной из-за "плохого кодирования"?

4b9b3361

Ответ 1

Да, вам нужно будет преобразовать все в числа. Это требует размышления о том, что представляют эти атрибуты.

Обычно есть три возможности:

  • Однострочное кодирование для категориальных данных
  • Произвольные номера для порядковых данных
  • Используйте что-то вроде групповых средств для категориальных данных (например, средних цен для городских районов).

Вы должны быть осторожны, чтобы не вводить информацию, которую вы не имеете в случае приложения.

Одно горячее кодирование

Если у вас есть категориальные данные, вы можете создать фиктивные переменные с значениями 0/1 для каждого возможного значения.

Е. г.

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

Это легко сделать с помощью pandas:

import pandas as pd

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

приведет к:

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

Числа для порядковых данных

Создайте сопоставление сортируемых категорий, например. г. старый < обновленный < new → 0, 1, 2

Это также возможно с помощью 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'])

Результат:

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

Использование категориальных данных для групповых операций

Вы можете использовать среднее значение для каждой категории за прошлые (известные события).

Скажем, у вас есть DataFrame с последними известными средними ценами для городов:

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

Результат:

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

Ответ 2

В этом случае вы можете использовать "Dummy Coding". Есть библиотеки Python для фиктивного кодирования, у вас есть несколько вариантов.

Вы можете использовать библиотеку scikit-learn. Посмотрите здесь.

Или, если вы работаете с пандами, у него есть встроенная функция для создания фиктивных переменных. Проверьте это.

Пример с пандами ниже:

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)

Ответ 3

При линейной регрессии с категориальными переменными вы должны быть осторожны с фиктивной переменной. Ловушка фиктивной переменной - это сценарий, в котором независимые переменные являются мультиколлинеарными - сценарий, в котором две или более переменных сильно коррелированы; Проще говоря, одну переменную можно предсказать из других. Это может привести к необычности модели, то есть ваша модель просто не будет работать. Читайте об этом здесь

Идея состоит в том, чтобы использовать фиктивную переменную с кодировкой drop_first=True, при этом будет исключен один столбец из каждой категории после преобразования категориальной переменной в фиктивные/индикаторные переменные. Делая это, вы НЕ БУДЕТЕ потерять какую-либо релевантную информацию просто потому, что весь ваш смысл в наборе данных может быть полностью объяснен остальными функциями.

Вот полный код того, как вы можете сделать это для своего набора данных жилья

Итак, у вас есть категорические особенности:

District, Condition, Material, Security, Type

И одна из числовых особенностей, которую вы пытаетесь предсказать:

Price

Сначала вам нужно разделить ваш начальный набор данных на входные переменные и прогнозирование, предполагая, что его кадр данных pandas будет выглядеть так:

Входные переменные:

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

Прогноз:

Y = housing['Price']

Преобразуйте категориальные переменные в фиктивные/индикаторные переменные и поместите по одной в каждую категорию:

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

Так что теперь, если вы проверите форму X с помощью drop_first=True вы увидите, что у него на 4 столбца меньше - по одному для каждой вашей категориальной переменной.

Теперь вы можете продолжать использовать их в вашей линейной модели. Для реализации scikit-learn это может выглядеть так:

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)

Ответ 4

Один из способов достижения регрессии с категориальными переменными в качестве независимых переменных, как указано выше - Использование кодирования. Другой способ сделать это - использовать R-подобную статистическую формулу с помощью библиотеки statmodels. Вот фрагмент кода

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

Dataset

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

Резюме регрессии

enter image description here