有效地将数据帧作为y和X传递给scikit-learn拟合

时间:2017-11-10 07:22:19

标签: python pandas scikit-learn

我从read_sql_query生成一个pandas数据帧。它有三列,“结果,速度,重量”

我想使用scikit-learn LinearRegression来适应results = f(speed, weight)

我无法找到允许我将此数据框或其列切片传递给LinearRegression.fit(y, X)的正确语法。

print df['result'].shape
print df[['speed', 'weight']].shape
(8L,)
(8, 2)

但我无法将其传递给fit

lm.fit(df['result'], df[['speed', 'weight']])

它会抛出deprecation warningValueError

DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. 
ValueError: Found arrays with inconsistent numbers of samples: [1 8]

获取目标和功能的数据框架并将其传递给fit操作的有效,干净的方法是什么?

这是我生成示例的方式:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(7), freq='D')

np.random.seed(seed=1111)
data = np.random.randint(1, high=100, size=len(days))
data2 = np.random.randint(1, high=100, size=len(days))
data3 = np.random.randint(1, high=100, size=len(days))
df = pd.DataFrame({'test': days, 'result': data,'speed': data2,'weight': data3})
df = df.set_index('test')
print(df)

4 个答案:

答案 0 :(得分:4)

您发送的值不正确。实现fit()的所有scikit-learn估算器都接受输入X,y而不是y,正如您所做的那样。

试试这个:

lm.fit(df[['speed', 'weight']], df['result'])

答案 1 :(得分:0)

使用以下代码:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from sklearn.linear_model import LinearRegression

lm = LinearRegression() 
predefinedFeatureList = ["speed","weight"]
target = "result"

date_today = datetime.now()
days = pd.date_range(date_today, date_today + timedelta(7), freq='D')

np.random.seed(seed=1111)
data = np.random.randint(1, high=100, size=len(days))
data2 = np.random.randint(1, high=100, size=len(days))
data3 = np.random.randint(1, high=100, size=len(days))
df = pd.DataFrame({'test': days, 'result': data,'speed': data2,'weight': data3})
df = df.set_index('test')
print(df)
#results = df['result']
#df.drop(['result'],axis= 1,inplace = True)
lm.fit(df[predefinedFeatureList],df[target]) #LM Fit takes arguments as (X,Y,sample_weights(optional))

答案 2 :(得分:0)

首先,fit()接受X,y而不是y,X。

其次,重要的是要记住Scikit-Learn专门用于类似数组的对象。它期望X具有形状(n_samples,n_features)和y具有形状(n_samples,)

当你使用fit时会检查这些形状,所以如果你的X,y不遵守这些规则,它就会崩溃。好消息,X已经有形状(5,2),但是y会有形状(5,1),这与(5,)不同,所以你的程序可能会崩溃。

为了安全起见,我只是从一开始就将我的X和y转换为numpy数组。

X = pd.DataFrame(np.ones((5, 2)))
y = pd.DataFrame(np.ones((5,)))

X = np.array(X)
y = np.array(y).squeeze()

要使y从形状(5,1)变为形状(5,),您需要使用.squeeze() 这将为您提供正确的形状,并希望程序能够运行!

答案 3 :(得分:0)

可能有更好的方法来集成 Pandas 和 sklearn,但有一件事情可能会阻止您按照您的方式进行操作,那就是结果列 y 的形状。它是一维的,但必须是二维的。

@Valentin Calomme 提到了这一点,但我喜欢这种使它比 squeeze() 更好的 2D 方式:只需添加一个额外的括号维度。

df['results'] 是一维的,而 df[['results']] 是二维的。但是,相同的数据。

df['results'].shape
# Out: (8,)
### 1D array

df[['results']].shape
# Out: (8, 1)
### 2D array

至于参数的顺序,仅当您不使用参数名称时才重要。我养成了查阅文档并始终明确使用参数名称的习惯,以避免在对参数进行排序时出现错误,并在我再次使用它时更好地了解我现在和以后在做什么,并且因为我偏执开发人员会乱搞参数顺序哈哈。

lm.fit(y=df[['result']], X=df[['speed', 'weight']])

### works just as well as

lm.fit(X=df[['speed', 'weight']], y=df[['result']])