[爆卦]pickle檔案是什麼?優點缺點精華區懶人包

為什麼這篇pickle檔案鄉民發文收入到精華區:因為在pickle檔案這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者magines (magines)看板Python標題[問題] pickle 無法 serial...


首先先感謝看本文的人,文章可能有點長。

然後我是python 超新手,某些詞彙表達不是很精確..造成困擾的話,先說聲抱歉。

基本上問題就是:
OverflowError: cannot serialize a bytes object larger than 4 GiB


*************來自github作者,聲明發生這個問題的原因*****************
Hi, this is a common problem and stems from some of the patents
having a crazily large amount of text in them.
Reduce the size of the sample on which you're running inference.
E.g., instead of 20% (0.2), reduce it to 0.05 to start with and
try ratcheting it up slowly.

*********結論:patent檔案太大了
參考
https://github.com/google/patents-public-data/issues/16


*****請問要怎麼切檔案?
他把所有的檔案,存進一個叫td的東西(在python 上面打 td,他只會出現
<train_data.LandscapeTrainingDataUtil at 0x1369595c0>

完全沒有想法要怎麼切,也不知道他長怎樣....




-----------------以下文章長--------------

我在github 下載了一個透過machine learning方法,找某個領域相關專利的專案。

https://github.com/google/patents-public-data/blob/master/models/landscaping/README.md

遵照LandscapeNotebook.ipynb 文件的指示,整個流程跑得非常順利。

然後,問題來了,這是一個相對樣本較小的範例,

如下所示:

subset_l1_pub_nums, l1_texts, padded_abstract_embeddings,
refs_one_hot, cpc_one_hot = \ expander.sample_for_inference(td, 0.02)

在參數設為0.02(隨機抽取td 2% 資料量)是成功的。

但是我想要的是整個資料為1(100%)下去跑測試完的結果(其實設20%它就不行了)。

當參數設太大的時候,會出現

OverflowError: cannot serialize a bytes object larger than 4 GiB” 的問題。

Google 後查(or想)到幾個解決方案:

1.)把pickle 模組換成 sklearn (失敗)

from
sklearn.externals import joblib joblib.dump(clf, 'filename.pkl')

參考:
https://stackoverflow.com/questions/48074419/how-to-pickle-files-2-gib-by-splitting-them-into-smaller-fragments

2.) 在pickle.dump ()裡面放protocol =4 (失敗-還是我放錯位置了?)

在expansion.py 檔案裡,有下面這個code:

pickle.dump( (training_data_full_df, seed_patents_df, l1_patents_df,
l2_patents_df, anti_seed_patents), outfile)

我放的protocol =4 位置如下(但都失敗)

pickle.dump((training_data_full_df, seed_patents_df, l1_patents_df,
l2_patents_df, anti_seed_patents, protocol =4), outfile)

or

pickle.dump( (training_data_full_df, seed_patents_df, l1_patents_df,
l2_patents_df, anti_seed_patents), outfile, protocol =4)

參考:
https://github.com/stan-dev/pystan/issues/197

3.) multiprocessing (沒試過,但我對於這個code有兩個問題)

我的理解是,就是做一個pickle4reducer 模組,模組如下:
from
multiprocessing.reduction import ForkingPickler, AbstractReducer

class ForkingPickler4(ForkingPickler):

def __init__(self, *args):
if len(args) > 1:
args[1] = 2
else:
args.append(2)
super().__init__(*args)
@classmethod

def dumps(cls, obj, protocol=4):
return ForkingPickler.dumps(obj, protocol)

def dump(obj, file, protocol=4):
ForkingPickler4(file, protocol).dump(obj)

class Pickle4Reducer(AbstractReducer):
ForkingPickler = ForkingPickler4
register = ForkingPickler4.register
dump = dump

在“主程式”的地方 放下面這個code

import pickle4reducer import multiprocessing as mp
ctx = mp.get_context()
ctx.reducer = pickle4reducer.Pickle4Reducer()
with mp.Pool(4) as p:
# do something

我的問題是,

a.我想這個主程式以專案來說,應該是expansion. py 這裡。
但是具體位置要放哪裡?

b. p:後面的do something是要寫什麼???
with mp.Pool(4) as p: # do something

參考:
https://stackoverflow.com/questions/51562221/python-multiprocessing-overflowerrorcannot-serialize-a-bytes-object-larger-t

4. 把檔案限制在4GB以下,然後循環下載 (沒試過)

import pickle import os.path
file_path = "pkl.pkl"
n_bytes = 2**31
max_bytes = 2**31 - 1
data = bytearray(n_bytes)
## write bytes_out = pickle.dumps(data) with open(file_path, 'wb') as f_out:
for idx in range(0, len(bytes_out), max_bytes):
f_out.write(bytes_out[idx:idx+max_bytes])
## read bytes_in = bytearray(0)
input_size = os.path.getsize(file_path) with open(file_path, 'rb') as f_in:
for _ in range(0, input_size, max_bytes):
bytes_in += f_in.read(max_bytes)
data2 = pickle.loads(bytes_in)
assert(data == data2)

請問要貼在哪裡啊?我要改什麼嗎?
參考
https://stackoverflow.com/questions/31468117/python-3-can-pickle-handle-byte-objects-larger-than-4gb

5. 上google cloud platform 開一個遠端電腦,CPU 和ram 能加多大,就加多大==
暴力解決?

但我感覺應該不是這個問題。 因為我看了issue 24658

上面po的問題,看起來是不知道哪來的bug~= =?

還是這個bug就是因為電腦運算能力本身會產生的問題?
Ps 我的電腦 mac pro /ram 8G /processor i5

參考:https://bugs.python.org/issue24658

6. 其他???

謝謝大家,文章真的有點長....

--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 141.23.163.194
※ 文章網址: https://www.ptt.cc/bbs/Python/M.1547743809.A.053.html
Neisseria: 未看先猜檔案系統問題 01/18 08:58
magines: 雖然不懂,不過還是謝謝你^^ 01/18 09:39
acer1832a: 你的Python是裝32bit還是64bit? 01/18 17:06

acer大,你好:我上網查了一下,透過下面這個code
>>> import struct >>> print(struct.calcsize("P") * 8) 出來數字是64
所以是64 bit
python 版本是3.5.6
processor 是core i5

謝謝acer大大

acer大大,你好
在文章的開始,我放了作者聲明這個問題的原因,要下載(訓練)的檔案td太大了
可是打td, python 出現<train_data.LandscapeTrainingDataUtil at 0x1369595c0>

這跟我認識的dataframe好像不一樣?請問要怎麼看檔案內容?要怎麼切?

謝謝
※ 編輯: magines (109.41.192.113), 01/18/2019 17:51:14
※ 編輯: magines (109.41.192.113), 01/18/2019 18:09:50
benson415: LandscapeTrainingDataUtil is a class :) 01/18 20:28
benson415: 問題不只是protocol,你dump的時候還要by batch 01/18 20:29
benson415: 你可以用buffer去接每個batch,再去讀或寫 01/18 20:31
Benson大大,你好:
我再按照你給的關鍵字查看看,謝謝!
※ 編輯: magines (109.41.192.113), 01/18/2019 20:44:33
alen84204: 原始檔案切割呢(訓練樣) 切成10分 分開跑 01/20 01:50

alen大你好:
後來的解決方案是參考了
https://stackoverflow.com/questions/31468117/python-3-can-pickle-handle-byte-objects-larger-than-4gb
這一篇,基本上是綜合了前面幾位大大的線索。

謝謝
※ 編輯: magines (109.41.3.215), 01/24/2019 01:02:23

你可能也想看看

搜尋相關網站