【问题标题】:efficiently passing dataframes as y and X to scikit-learn fits有效地将数据帧作为 y 和 X 传递给 scikit-learn 拟合
【发布时间】:2018-04-23 09:03:18
【问题描述】:

我从read_sql_query 生成一个熊猫数据框。它有三列,“结果、速度、重量”

我想使用 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 warning 和一个ValueError

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)

【问题讨论】:

  • df['result'].values 有时你需要df.iloc[:, :-1]

标签: python pandas scikit-learn


【解决方案1】:

使用下面的代码:

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】:

您以错误的顺序发送值。所有实现 fit() 的 scikit-learn 估计器都接受输入 X, y 而不是 y, X 。

试试这个:

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

【讨论】:

    【解决方案3】:

    首先,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() 这将为您提供正确的形状,并希望程序能够运行!

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2020-01-30
        • 2016-01-11
        • 1970-01-01
        • 2015-05-24
        • 2020-02-21
        • 2015-10-25
        • 2018-09-30
        • 2016-04-22
        • 2018-05-26
        相关资源
        最近更新 更多