ValueError:找到具有 0 个样本 (s) 的数组(形状 = (0, 1),而 MinMaxScaler 要求最小值为 1

Posted

技术标签:

【中文标题】ValueError:找到具有 0 个样本 (s) 的数组(形状 = (0, 1),而 MinMaxScaler 要求最小值为 1【英文标题】:ValueError: Found array with 0 sample (s) (shape= (0, 1) while a minimum of 1 is required by MinMaxScaler 【发布时间】:2019-04-24 14:05:00 【问题描述】:

这个学期我开始使用机器学习。我们只使用过微软的 Azure 和亚马逊的 AWS 等 API,但我们还没有深入了解这些服务的工作原理。我的好朋友是数学专业的大四学生,他让我帮助他根据他提供给我的文件.csv 使用 TensorFlow 创建一个股票预测器。

我有几个问题。第一个是他的.csv 文件。该文件只有日期和结束值,它们没有分开,因此我不得不手动分开日期和值。我已经设法做到了,现在我遇到了 MinMaxScaler() 的问题。有人告诉我,我几乎可以忽略日期,只测试结束值,将它们标准化,然后根据它们做出预测。

我不断收到此错误:

ValueError: 找到包含 0 个样本的数组 (shape=(0, 1)) 而一个 MinMaxScaler() 要求最小值为 1

老实说,我以前从未使用过SKLearning 和 TensorFlow,这是我第一次从事这样的项目。我在该主题上看到的所有指南都使用 pandas,但就我而言,.csv 文件一团糟,我不相信我可以使用 pandas。

我正在关注this 指南:

但不幸的是,由于我缺乏经验,有些事情并不适合我,如果我能更清楚地了解我应该如何处理我的案件,我将不胜感激。

下面附上我的(凌乱的)代码:

import pandas as pd
import numpy as np
import tensorflow as tf
import sklearn
from sklearn.model_selection import KFold
from sklearn.preprocessing import scale
from sklearn.preprocessing import MinMaxScaler
import matplotlib
import matplotlib.pyplot as plt
from dateutil.parser import parse
from datetime import datetime, timedelta
from collections import deque

stock_data = []
stock_date = []
stock_value = []
f = open("s&p500closing.csv","r")
data = f.read()
rows = data.split("\n")
rows_noheader = rows[1:len(rows)]

#Separating values from messy `.csv`, putting each value to it's list and also a combined list of both
for row in rows_noheader:
    [date, value] = row[1:len(row)-1].split('\t')
    stock_date.append(date)
    stock_value.append((value))
    stock_data.append((date, value))

#Numpy array of all closing values converted to floats and normalized against the maximum
stock_value = np.array(stock_value, dtype=np.float32)
normvalue = [i/max(stock_value) for i in stock_value]

#Number of closing values and days. Since there is one closing value for each, they both match and there are 4528 of them (each)
nclose_and_days = 0
for i in range(len(stock_data)):
    nclose_and_days+=1

train_data = stock_value[:2264]
test_data = stock_value[2264:]

scaler = MinMaxScaler()

train_data = train_data.reshape(-1,1)
test_data = test_data.reshape(-1,1)

# Train the Scaler with training data and smooth data
smoothing_window_size = 1100
for di in range(0,4400,smoothing_window_size):
    #error occurs here
    scaler.fit(train_data[di:di+smoothing_window_size,:])
    train_data[di:di+smoothing_window_size,:] = scaler.transform(train_data[di:di+smoothing_window_size,:])

# You normalize the last bit of remaining data
scaler.fit(train_data[di+smoothing_window_size:,:])
train_data[di+smoothing_window_size:,:] = scaler.transform(train_data[di+smoothing_window_size:,:])

# Reshape both train and test data
train_data = train_data.reshape(-1)

# Normalize test data
test_data = scaler.transform(test_data).reshape(-1)

# Now perform exponential moving average smoothing
# So the data will have a smoother curve than the original ragged data
EMA = 0.0
gamma = 0.1
for ti in range(1100):
    EMA = gamma*train_data[ti] + (1-gamma)*EMA
    train_data[ti] = EMA

# Used for visualization and test purposes
all_mid_data = np.concatenate([train_data,test_data],axis=0)

window_size = 100
N = train_data.size
std_avg_predictions = []
std_avg_x = []
mse_errors = []

for pred_idx in range(window_size,N):
    std_avg_predictions.append(np.mean(train_data[pred_idx-window_size:pred_idx]))
    mse_errors.append((std_avg_predictions[-1]-train_data[pred_idx])**2)
    std_avg_x.append(date)

print('MSE error for standard averaging: %.5f'%(0.5*np.mean(mse_errors)))

【问题讨论】:

请发布一些数据样本,以及错误的完整堆栈跟踪。 【参考方案1】:

我知道这篇文章很旧,但是当我在这里偶然发现时,其他人会...... 在遇到同样的问题并在谷歌上搜索了很多之后,我发现了一个帖子 https://github.com/llSourcell/Make_Money_with_Tensorflow_2.0/issues/7

因此,如果您下载的数据集太小,它似乎会引发该错误。 从 1962 年下载一个 .csv,它就足够大了;)。

现在,我只需要为我的数据集找到正确的参数..因为我正在调整它以适应另一种类型的预测.. 希望对你有帮助

【讨论】:

【参考方案2】:

train_data 变量的长度为 2264:

train_data = stock_value[:2264]

然后,当你去适应缩放器时,你在 for 循环的第三次迭代中超出了 train_data 的界限:

smoothing_window_size = 1100
for di in range(0, 4400, smoothing_window_size):

请注意教程中数据集的大小。训练和测试块的长度均为 11,000,smoothing_window_size 为 2500,因此它永远不会超过train_data 的边界。

【讨论】:

【参考方案3】:

您的数据中有一列全为 0。如果您尝试对其进行缩放,则 MinMaxScaler 无法分配比例并且它会跳闸。在缩放数据之前,您需要过滤掉空/0 列。试试看:

    stock_value=stock_value[:,~np.all(np.isnan(d), axis=0)]

过滤掉数据中的 nan 列

【讨论】:

欢迎来到 SO。这种回复应作为 cmets 而不是作为答案包含在内。用户已经暴露他有一个没有样本的数组,所以 MinMaxScaler 不能工作。因此,在这个广泛的部分中,尽可能多地提供帮助,而不仅仅是指出一个项目并考虑作为答案。很好的回答,但尽量专注于完整的问题【参考方案4】:

我不得不道歉,在你们试图找出解决我的问题的整个过程中,我最终找到了一个不错的指南并采用了一种不太复杂的方法(因为这是我第一次体验 AI和统计)。有趣的是,我为此头疼了好几个月,直到去年 11 月我去佛罗里达参加了一次会议,并在凌晨 3 点不到两个小时的时间内在我的酒店房间里完成了它。

这是我当时写的完成的代码,最后作为工作示例展示给我的同事

import tensorflow as tf
from keras import backend as K

from tensorflow.python.saved_model import builder as saved_model_builder
from tensorflow.python.saved_model import tag_constants, signature_constants, signature_def_utils_impl

from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD
import numpy as np

import matplotlib.pyplot as plt


stock_data = []
stock_date = []
stock_value = []
f = open("s&p500closing.csv","r")
data = f.read()
rows = data.split("\n")
rows_noheader = rows[1:len(rows)]

#Separating values from messy CSV, putting each value to it's list and also a combined list of both
for row in rows_noheader:
    [date, value] = row[1:len(row)-1].split('\t')
    stock_date.append(date)
    stock_value.append((value))
    stock_data.append((date, value))

#Making an array of arrays ready for use with TF,
#slicing array of data to smaller train data
#and normalizing the values against the max for training    
stock_value = np.array(stock_value, dtype=np.float32)
normvalue = [i/max(stock_value) for i in stock_value]
normvalue = np.array(normvalue)
train_data = [np.array(i) for i in normvalue[:500]]
train_data = np.array(train_data)
train_labels = train_data

#First plotting the actual values
plt.plot(normvalue)

#Creating TF session
sess = tf.Session()
K.set_session(sess)
K.set_learning_phase(0)

model_version = "2"
#Declaring the amount of epochs, the amount of periods the machine will learn
#(can play around with it) 
epoch = 20
#Building the model
####################
model = Sequential()
model.add(Dense(8, input_dim=1))
model.add(Activation('tanh'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
sgd = SGD(lr=0.1)

#Compiling and fitting our data to the model
model.compile(loss='binary_crossentropy', optimizer=sgd)
model.fit(train_data, train_labels, batch_size=1, nb_epoch=epoch)

#declaring varaibles for the models input and output to make sure they are all valid
x = model.input
y = model.output

prediction_signature = tf.saved_model.signature_def_utils.predict_signature_def("inputs": x, "prediction":y)

valid_prediction_signature = tf.saved_model.signature_def_utils.is_valid_signature(prediction_signature)
if(valid_prediction_signature == False):
    raise ValueError("Error: Prediction signature not valid!")

#Here the actual prediction of the real values occurs
predictions = model.predict(normvalue)

#Plotting the prediction values
plt.xlabel("Blue: Actual            Orange: Prediction")    
plt.plot(predictions)

请随意进行更改并在您认为合适的情况下进行试验。 我要感谢大家花时间检查我的问题并提供各种解决方案,并期待在未来了解更多:)

【讨论】:

【参考方案5】:

我第一次评论***,如果你发现我的回答有错误,或者如果你发现错误,请纠正我

所以对于上面的错误,让计算变得简单,如何避免上面的值错误。

mid_prices = (high_prices+low_prices)/2.0
print(len(mid_prices))#length 2024

train_data = mid_prices[:1012]
test_data = mid_prices[1012:]

scaler = MinMaxScaler()
train_data = train_data.reshape(-1,1)
test_data = test_data.reshape(-1,1)

smoothing_window_size = 200

for di in range (0,1000,smoothing_window_size):
    scaler.fit(train_data[di:di+smoothing_window_size,:])
    train_data[di:di+smoothing_window_size,:] = scaler.transform(train_data[di:di+smoothing_window_size,:])

上面的这段代码适用于我的 mid_prices 变量的 len 为 2024 所以我的

train_data = mid_prices[:1012]
test_data = mid_prices[1012:]

被分成两个 1012 大小的块

现在,如果您查看 tutorial 提供的代码

他的总大小是 22000,他将它们分成两个 11000 块用于测试和训练 然后对于缩放器,他在 for 循环中使用 0 到 10000 的范围和 2500 的 smothing 窗口大小,如果我错了,请纠正我在 10k 组中进行 5 次迭代。

使用作者使用的这个逻辑我做到了

smoothing_window_size = 200

    for di in range (0,1000,smoothing_window_size):
        scaler.fit(train_data[di:di+smoothing_window_size,:])
        train_data[di:di+smoothing_window_size,:] = scaler.transform(train_data[di:di+smoothing_window_size,:])

这与我的数据集和提供的示例完美配合。

我希望这个答案足以解决这个问题

【讨论】:

【参考方案6】:

您的问题不在于 CSV 或 pandas。实际上,您可以将带有 pandas 的 CSV 直接读取到我建议您执行的数据帧中。 df = pd.read_csv(path)

我在使用相同的代码时遇到了同样的问题。 发生了什么是Scaler = MinMaxScaler,然后在 for di in range 部分中,您正在将数据拟合到训练集中,然后对其进行转换并将其重新分配回自身。

问题是,它试图在您的训练集中找到更多数据以适应缩放器并且数据用完。这很奇怪,因为您遵循的教程呈现它的方式。

【讨论】:

如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review @Mayur 我只是想提供上下文并帮助该人了解问题所在,而我遇到了完全相同的问题。没有人回答它。所以我把它放在同一个线程中似乎很合适【参考方案7】:

我看到您的 Window 是 1100,在您的 for 循环中,您从 0 到 4400,间隔为 1100。有了这个,你有 0 作为余数,这反过来又留下 0 个项目来规范化,所以你的代码有

# You normalize the last bit of remaining data
scaler.fit(train_data[di+smoothing_window_size:,:])
train_data[di+smoothing_window_size:,:] = scaler.transform(train_data[di+smoothing_window_size:,:])

您不需要这些代码行,只需将它们注释掉即可。它应该在那之后工作

【讨论】:

我尝试将它们注释掉并给了我另一个错误【参考方案8】:

我在为基于逻辑回归的文本分类包编写单元测试时遇到了相同的错误消息,我意识到这是由于试图将模型应用于空 df。

在我的情况下,这可能会发生,因为我的模型实际上是一棵模型树,它反映了我的(巨大的)训练数据中的类别树,但只有少数子案例实际上发生在我的 unittest 中的微小测试 df 中.

长话短说:我认为错误可能发生在某个时候

train_data[di:di+smoothing_window_size,:]

最终在你的循环中长度为 0。

【讨论】:

以上是关于ValueError:找到具有 0 个样本 (s) 的数组(形状 = (0, 1),而 MinMaxScaler 要求最小值为 1的主要内容,如果未能解决你的问题,请参考以下文章

ValueError:找到的数组带有0个样本(形状=(0,35)),而StandardScaler至少需要1个]]

ValueError: 找到具有 0 个特征的数组 (shape=(2698, 0)),而 MinMaxScaler 要求最小值为 1

ValueError:X每个样本具有231个特征;期待1228

值错误:输入数组应具有与目标数组相同数量的样本。找到 1600 个输入样本和 6400 个目标样本

当我尝试为 scikit-learn 模型拟合另外 1 个功能时,出现此错误“ValueError:找到样本数量不一致的输入变量”

如何解决 Python 中的“ValueError:找到样本数量不一致的输入变量”问题