#python #time-series #linear-regression
Вопрос:
У меня есть эти данные:
и я пытаюсь построить на нем простую модель линейной регрессии.
Вот мой код:
from sklearn.linear_model import LinearRegression
X = df[['Date']]
y = df['ACP Cleaning']
model = LinearRegression()
model.fit(X, y)
X_predict = [['2021-1-1']]
y_predict = model.predict(X_predict)
и в этом моя ошибка:
Ошибка значения: Не удается преобразовать массив байтов/строк в десятичные числа с помощью dtype=’числовой’
Комментарии:
1. Я говорю это с самыми добрыми намерениями: если вы ничего не знаете о простой базовой алгебре, лежащей в основе этой вещи, работа на Python не станет проще. Для начала все переменные в регрессии должны быть числовыми. Вам нужно будет сопоставить эти строки с числами.
Ответ №1:
Линейная регрессия работает с числами, а не со строками.
Вы должны предварительно обработать свои данные, чтобы они соответствовали входным данным модели.
Один из способов сделать это-проанализировать строку и преобразовать ее в метку времени:
import datetime
def process_date(date_str):
d = datetime.datetime.strptime(date_str, '%Y-%m-%d')
return d.timestamp()
X = df[['Date']].apply(process_date)
То же самое необходимо сделать с данными, которые вы хотите спрогнозировать.
Обновление: Если тип данных вашего набора данных правильный, то проблема в данных, которые вы пытаетесь использовать для прогнозирования (вы не можете предсказать строку).
Ниже приведен полный рабочий пример. Обратите пристальное внимание на обработку, выполняемую с X_predict
переменной.
import datetime
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
rng = pd.date_range('2015-02-24', periods=5, freq='3A')
df = pd.DataFrame({ 'Date': rng, 'Val' : np.random.randn(len(rng))})
print(df.head())
X = np.array(df['Date']).reshape(-1,1)
y = df['Val']
model = LinearRegression()
model.fit(X, y)
def process_date(date_str):
d = datetime.datetime.strptime(date_str, '%Y-%m-%d')
# return array
return [d.timestamp()]
X_predict = ['2021-1-1']
X_predict = list(map(process_date, X_predict))
y_predict = model.predict(X_predict)
y_predict
ВОЗВРАТ:
Date Val
0 2015-12-31 -0.110503
1 2018-12-31 -0.621394
2 2021-12-31 -1.030068
3 2024-12-31 1.221146
4 2027-12-31 -0.327685
array([-2.6149628])
Обновление: Я использовал ваши данные для создания csv-файла:
Date,Val
1-1-2020, 90404.71
2-1-2020, 69904.71
...
А потом я загрузился пандами. Мне все кажется хорошим:
def process_date(date_str):
# the date format is month-day-year
d = datetime.datetime.strptime(date_str, '%m-%d-%Y')
return d.timestamp()
df = pd.read_csv("test.csv")
df['Date'] = df['Date'].apply(process_date)
df.head()
Выход:
Date Val
0 1.577848e 09 90404.710
1 1.580526e 09 69904.710
2 1.583032e 09 98934.112
3 1.585710e 09 77084.430
4 1.588302e 09 35877.420
Извлечение функций:
# must reshape 'cause we have only one feature
X = df['Date'].to_numpy().reshape(-1,1)
y = df['Val'].to_numpy()
model = LinearRegression()
model.fit(X, y)
Предсказывающий:
X_predict = ['1-1-2021', '2-1-2021']
X_predict = np.array(list(map(process_date, X_predict)))
X_predict = X_predict.reshape(-1, 1)
y_predict = model.predict(X_predict)
y_predict
Выход:
array([55492.2660361 , 53516.12292932])
Это хороший прогноз. Вы можете использовать matplotlib для построения своих данных и убедить себя:
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(df['Date'], df['Val'])
plt.show()
Комментарии:
1. Я получаю эту ошибку при запуске кода: ошибка типа: strptime() аргумент 1 должен быть str, а не серия
2. @juge Я обновил свой ответ полным примером.
3. Спасибо тебе, Хуан! Это работает.
4. Я изменил свои x и y на столбцы моего фрейма данных, но прогноз выходит слишком большим, он должен быть около 9 тыс., это 1,2 миллиона, это агрегирование? 1.2 может быть цифрой за целый год? @JuanR
5. можете ли вы загрузить свой набор данных куда-нибудь, чтобы я мог взглянуть на него?
Ответ №2:
Линейная регрессия требует, чтобы ваши массивы были числового типа, поскольку у вас есть даты, которые хранятся в виде строк в вашем X
массиве, Линейная регрессия не будет работать так, как вы ожидаете.
Вы можете преобразовать X
массив в числовой тип, подсчитав количество дней с даты начала. Вы можете попробовать что-то подобное в своем фрейме данных:
df.Date = (df.Date - df.Date[0]).days
И тогда вы сможете продолжать делать то, что делали.
Я предположил, что даты в вашей Date
колонке указаны в datetime
формате, иначе вам нужно было бы сначала преобразовать их.