2017-02-26 94 views
-5

我想建立一個分類模型。我在本地文件夾中有1000個文本文檔。我想把他們分成訓練集和測試集,分流比爲70:30(70->訓練和30->測試)這樣做的更好方法是什麼?我正在使用python。如何將文檔分割爲訓練集和測試集?

注意: - 爲了更好的理解,請提供解釋爲什麼應該遵循該方法。

謝謝

更新: -幾downvotes這個問題後。儘管我得到了近乎完美的答案,但我仍想簡要回答這個問題。

我想通過編程的方式來分割訓練集和測試集。首先閱讀本地目錄中的文件。其次,建立這些文件的清單並對其進行洗牌。第三,將它們分成訓練集和測試集。

作爲python的初學者和新手,我嘗試了幾種使用內置python關鍵字和函數的方法來失敗。最後,我得到了接近它的想法。對於建築物的一般分類模型,交叉驗證也是一個很好的選擇。感謝您的答案。

+0

Scikit學習有許多可用的功能做你想要什麼樣的例子。搜索網絡,並在這裏發帖,如果你發現在應用它們時遇到任何困難 –

+0

這個問題有什麼問題?爲什麼會員貶低這個問題? –

+1

Stackoverflow不適用於收集意見。這是編程。你只是問而不顯示任何努力。 –

回答

3

不確定究竟是你在追求什麼,所以我會盡量全面。會有幾個步驟:

  1. 獲取文件的列表
  2. 隨機化文件
  3. 分割文件到訓練和測試設置
  4. 做的事

1.使用文件列表

讓我們假設你的文件都有擴展名.data,它們都在文件夾/ml/data/。我們想要做的是獲得所有這些文件的列表。這隻需要使用os模塊即可完成。我假設你沒有子目錄;如果有的話,這將會改變。

import os 

def get_file_list_from_dir(datadir): 
    all_files = os.listdir(os.path.abspath(datadir)) 
    data_files = list(filter(lambda file: file.endswith('.data'), all_files)) 
    return data_files 

所以,如果我們要調用get_file_list_from_dir('/ml/data'),我們還是會回到所有在該目錄中.data文件列表(相當於在外殼的水珠/ml/data/*.data)。

2.隨機化的文件

我們不想採樣是可預測的,因爲這被認爲是一個貧窮的方式來訓練的ML分類。

from random import shuffle 

def randomize_files(file_list): 
    shuffle(file_list) 

注意random.shuffle執行就地互換,以便它修改現有的列表。 (當然,這個功能是相當愚蠢的,因爲你可以只調用shuffle而不是randomize_files;你可以寫到另一個函數這使它更有意義。)

3.拆分文件到訓練和測試設置

我會假設一個70:30的比率,而不是任何特定數量的文件。所以:

from math import floor 

def get_training_and_testing_sets(file_list): 
    split = 0.7 
    split_index = floor(len(file_list) * split) 
    training = file_list[:split_index] 
    testing = file_list[split_index:] 
    return training, testing 

4.做的事

這是你打開每個文件,做你的訓練和測試步驟。我會留給你的!


交叉驗證

出於好奇,你有沒有考慮過使用cross-validation?這是一種分割數據的方法,以便您可以使用每個文檔進行培訓和測試。您可以自定義在每次「摺疊」中使用多少文檔進行培訓。如果你喜歡,我可以更深入地瞭解這一點,但如果你不想這樣做,我不會這樣做。

編輯:好的,因爲你要求我會多解釋一下。

所以我們有一個1000個文檔的數據集。交叉驗證的想法是,您可以使用所有進行培訓和測試 - 只是不要一次。我們將數據集分解成我們稱之爲「摺疊」的東西。摺疊次數決定了在任何給定時間點訓練和測試集的大小。

比方說,我們想要一個10倍的交叉驗證系統。這意味着訓練和測試算法將運行十次。第一次將在文件1-100上進行訓練並在101-1000上進行測試。第二輪將在101-200上進行訓練,並在1-100和201-1000進行測試。

如果我們做了一個40倍的CV系統,第一次將在文檔1-25上進行訓練並在26-1000上進行測試,第二次將在26-40上進行訓練並在1-25上進行測試, 51-1000,和。爲了實現這樣一個系統,我們仍然需要從上面進行步驟(1)和(2),但步驟(3)會有所不同。我們可以將函數變成一個generator - 我們可以像列表一樣遍歷一個函數,而不是分成兩組(一個用於訓練,一個用於測試)。

def cross_validate(data_files, folds): 
    if len(data_files) % folds != 0: 
     raise ValueError(
      "invalid number of folds ({}) for the number of " 
      "documents ({})".format(folds, len(data_files)) 
     ) 
    fold_size = len(data_files) // folds 
    for split_index in range(0, len(data_files), fold_size): 
     training = data_files[split_index:split_index + fold_size] 
     testing = data_files[:split_index] + data_files[split_index + fold_size:] 
     yield training, testing 

yieldyield關鍵字是什麼使這個發電機。要使用它,你可以這樣使用它:

def ml_function(datadir, num_folds): 
    data_files = get_file_list_from_dir(datadir) 
    randomize_files(data_files) 
    for train_set, test_set in cross_validate(data_files, num_folds): 
     do_ml_training(train_set) 
     do_ml_testing(test_set) 

再次,這取決於你實現你的ML系統的實際功能。

作爲一個免責聲明,我不是專家的任何手段,哈哈。但是,如果您對我在這裏寫的任何內容有任何疑問,請告訴我!

+0

我想將1000個文本文檔(.txt)分解爲用於實現tf-idf的訓練和測試集,並應用算法來構建分類模型。根據我的目標,將文檔分爲兩個獨立的類。 –

+0

是的,我考慮過交叉驗證。但作爲一名初學者,我認爲不要去追求它。我也請你解釋一下。請。 –

+0

@BhabaniMohapatra我已經更新了底部,以解釋您可能如何進行一些交叉驗證。細節取決於你,但我寫的應該可以幫助你正確加載數據。如果您有任何問題,請告訴我! –

0

只需使用os.listdir()製作一個文件名列表。使用collections.shuffle()洗牌的列表,然後training_files = filenames[:700]testing_files = filenames[700:]

1

如果使用numpy的,首先加載文件,並使其實現numpy的數組,然後這是相當簡單:

import numpy as np 

docs = np.array([ 
    'one', 'two', 'three', 'four', 'five', 
    'six', 'seven', 'eight', 'nine', 'ten', 
    ]) 

idx = np.hstack((np.ones(7), np.zeros(3))) # generate indexes 
np.random.shuffle(idx) # shuffle to make training data and test data random 

train = docs[idx == 1] 
test = docs[idx == 0] 

print(train) 
print(test) 

結果:

['one' 'two' 'three' 'six' 'eight' 'nine' 'ten'] 
['four' 'five' 'seven'] 
相關問題