【问题标题】:Train test split without using scikit learn在不使用 scikit learn 的情况下训练测试拆分
【发布时间】:2018-04-22 11:12:16
【问题描述】:

我有一个房价预测数据集。我必须将数据集拆分为traintest
我想知道是否可以使用numpyscipy 来做到这一点?
我现在不能使用scikit学习。

【问题讨论】:

    标签: python numpy scikit-learn scipy


    【解决方案1】:

    我知道你的问题只是用 numpyscipy 做一个 train_test_split 但实际上有一个非常简单的方法可以用 Pandas 来做:

    import pandas as pd 
    
    # Shuffle your dataset 
    shuffle_df = df.sample(frac=1)
    
    # Define a size for your train set 
    train_size = int(0.7 * len(df))
    
    # Split your dataset 
    train_set = shuffle_df[:train_size]
    test_set = shuffle_df[train_size:]
    

    适合那些想要快速简便的解决方案的人。

    【讨论】:

      【解决方案2】:

      虽然这是个老问题,但这个答案可能会有所帮助。

      这就是 sklearn 实现 train_test_split 的方式,下面给出的这个方法,采用与 sklearn 类似的参数。

      import numpy as np
      from itertools import chain
      
      def _indexing(x, indices):
          """
          :param x: array from which indices has to be fetched
          :param indices: indices to be fetched
          :return: sub-array from given array and indices
          """
          # np array indexing
          if hasattr(x, 'shape'):
              return x[indices]
      
          # list indexing
          return [x[idx] for idx in indices]
      
      def train_test_split(*arrays, test_size=0.25, shufffle=True, random_seed=1):
          """
          splits array into train and test data.
          :param arrays: arrays to split in train and test
          :param test_size: size of test set in range (0,1)
          :param shufffle: whether to shuffle arrays or not
          :param random_seed: random seed value
          :return: return 2*len(arrays) divided into train ans test
          """
          # checks
          assert 0 < test_size < 1
          assert len(arrays) > 0
          length = len(arrays[0])
          for i in arrays:
              assert len(i) == length
      
          n_test = int(np.ceil(length*test_size))
          n_train = length - n_test
      
          if shufffle:
              perm = np.random.RandomState(random_seed).permutation(length)
              test_indices = perm[:n_test]
              train_indices = perm[n_test:]
          else:
              train_indices = np.arange(n_train)
              test_indices = np.arange(n_train, length)
      
          return list(chain.from_iterable((_indexing(x, train_indices), _indexing(x, test_indices)) for x in arrays))
      

      当然 sklearn 的实现支持分层 k 折叠、拆分 pandas 系列等。这个只适用于拆分列表和 numpy 数组,我认为这对你的情况有用。

      【讨论】:

        【解决方案3】:
        import numpy as np
        import pandas as pd
        
        X_data = pd.read_csv('house.csv')
        Y_data = X_data["prices"]
        X_data.drop(["offers", "brick", "bathrooms", "prices"], 
                    axis=1, inplace=True) # important to drop prices as well
        
        # create random train/test split
        indices = range(X_data.shape[0])
        num_training_instances = int(0.8 * X_data.shape[0])
        np.random.shuffle(indices)
        train_indices = indices[:num_training_indices]
        test_indices = indices[num_training_indices:]
        
        # split the actual data
        X_data_train, X_data_test = X_data.iloc[train_indices], X_data.iloc[test_indices]
        Y_data_train, Y_data_test = Y_data.iloc[train_indices], Y_data.iloc[test_indices]
        

        这假设您想要随机拆分。发生的情况是,我们正在创建一个索引列表,只要您拥有的数据点数量,即 X_data(或 Y_data)的第一个轴。然后我们将它们按随机顺序排列,并将这些随机指标的前 80% 作为训练数据,其余的用于测试。 [:num_training_indices] 只是从列表中选择第一个 num_training_indices。之后,您只需使用随机索引列表从数据中提取行,然后拆分数据。如果您希望拆分可重现,请记住从您的 X_data 中删除价格并设置种子(开头为np.random.seed(some_integer))。

        【讨论】:

        • 我想把它分成 80% 的训练和 20% 的测试。那么代码是什么?
        • 如果您希望将其拆分为 80% 到 20%,请将 num_train_examples 变量的值设置为数据集中行数的 80%。如果您有 100 行,则将其设置为 80。
        • @jaguar 你能解释一下all_data[ :num_train_examples] 吗?我们在切片吗?还有其他我可以阅读的来源吗?
        • @CODE_DIY 我相信 all_data 是您的数据集并且您正在对其进行切片,但是您不能使用这样的简单切片来切片 Pandas DataFrames。我会发布一个答案,希望对您有所帮助。
        • @CODE_DIY 请检查我的回答,我认为这可能会有所帮助。
        【解决方案4】:

        此解决方案仅使用 pandas 和 numpy

        def split_train_valid_test(data,valid_ratio,test_ratio):
            shuffled_indcies=np.random.permutation(len(data))
            valid_set_size= int(len(data)*valid_ratio)
            valid_indcies=shuffled_indcies[:valid_set_size]
            test_set_size= int(len(data)*test_ratio)
            test_indcies=shuffled_indcies[valid_set_size:test_set_size+valid_set_size]
            train_indices=shuffled_indcies[test_set_size:]
            return data.iloc[train_indices],data.iloc[valid_indcies],data.iloc[test_indcies]
        
        train_set,valid_set,test_set=split_train_valid_test(dataset,valid_ratio=0.2,test_ratio=0.2)
        print(len(train_set),len(valid_set),len(test_set))
        ##out: (16512, 4128, 4128)
        

        【讨论】:

          【解决方案5】:

          这段代码应该可以工作(假设 X_data 是 pandas DataFrame):

          import numpy as np
          num_of_rows = len(X_data) * 0.8
          values = X_data.values
          np.random_shuffle(values) #shuffles data to make it random
          train_data = values[:num_of_rows] #indexes rows for training data
          test_data = values[num_of_rows:] #indexes rows for test data
          

          希望这会有所帮助!

          【讨论】:

          • 谢谢。还有一个问题。在第一行,我有列标签。我想我需要删除它们。对吗?
          • @CODE_DIY 是的,您应该删除列标签。我建议您保存列标签并说:df.columns = [(在此处插入列标签)]。
          • 最后的排序是不必要的。只是让它洗牌。我还将使用 numpy 随机模块中的排列方法,并索引到您的数据帧中。 stackoverflow.com/a/29576803/3250829
          猜你喜欢
          • 2019-04-10
          • 2015-06-08
          • 2017-04-11
          • 2021-06-20
          • 2021-07-26
          • 2020-06-22
          • 1970-01-01
          • 2018-12-07
          • 2015-10-09
          相关资源
          最近更新 更多