2016-04-30 51 views
1

我正在計算單詞的相對頻率(單詞數/單詞總數)。這導致了很多非常小的數字(例如,1.2551539760140076e-05)。我已經閱讀了關於在這種情況下使用浮動的一些問題,例如在此article浮點數與Python中的記錄值

浮子具有精度大約7個十進制數字...

一些建議使用記錄值來代替。我將乘以這些數字,並想知道

  • 一般來說,是七位數規則的東西在Python中去?
  • 在我的情況下,我應該使用日誌值嗎?
  • 如果我不這麼做會發生什麼不好的事情 - 只是一個不太準確的值或直接的錯誤,例如,在乘法?
  • 如果是這樣,我只是將float與math.log() - 我覺得在那一點上信息已經丟失了?

任何幫助非常感謝!

+0

只需使用'Decimal'(從十進制導入Decimal')來獲得精度。 – Bahrom

回答

1

那篇文章談到了類型float在C,這是一個32位數量。 Python類型float是64位數字,與C的double一樣,因此可以存儲大約17位十進制數字(53個小數位,而不是C,其中的C爲float)。雖然這對於某些應用來說可能精度太低,但與32位浮點數相比,它的可靠性要低得多。

此外,由於它是浮點數格式,所以小數字(如1.2551539760140076e-05(實際上並不那麼小))本身並不處於劣勢。雖然只能表示約17位十進制數字,但這17位數字不一定是小數點後的前17位。他們可以轉移,所以可以說。實際上,當您將一個數字作爲一串十進制數字乘以十的冪(e-5)時,您使用的浮點(小數)點的概念與相同。得到極端的例子,1 -300可以表示就好,如可以10 —只有當這兩個號碼符合,問題發生(1e300 + 1e-300 == 1e300)。

至於日誌表示,您應儘早記錄所有值,並在日誌空間中儘可能多地執行計算。在你的例子中,你可以計算一個詞的相對頻率爲log(word_count) - log(total_words),這與log(word_count/total_words)相同,但可能更準確。

如果我不這樣做會發生什麼壞事 - 只是一個不太準確的值或直接的錯誤,例如,在乘法?

我不確定區別是什麼。數值計算可以具有幾乎完美的準確度(相對舍入誤差,範圍爲2 -50或更高),但在某些情況下,不穩定的算法也可能帶來令人難以忍受的不良結果。每個單獨操作的舍入誤差都有相當嚴格的界限,但在較長的計算中,它們以驚人的方式相互作用以導致非常大的誤差。例如,即使只是總結一大堆漂浮物,也會帶來嚴重的錯誤,特別是如果它們的幅度和標誌大不相同。可靠的數字算法的正確分析和設計是它自己的,我不能做到公正這裏的一門藝術,但由於IEEE-754的良好的設計,算法通常工作了。不要太擔心,但也不要忽視它。


在現實中,我們是在談論53 二進制位被轉移左右,但這是不重要的這個概念。存在十進制浮點格式。

小於2 -54相對舍入誤差,其發生用於其分母不爲二的冪,包括這樣平凡那些如1/3或0.1任何部分。

對於基本的算術運算,舍入誤差應該是最後一位的一半,即結果必須精確計算,然後進行正確舍入。對於超越函數來說,錯誤很少超過最後一個或兩個單位,但可以更大。

+0

這是一個美麗的答案,謝謝!我有一個真正的短期跟進,出於好奇:你寫道:「總結一大堆漂浮物可能會導致嚴重的錯誤」。一份清單需要足夠多的物品才能發生? – patrick

+1

@patrick這取決於列表中的值。一個病態的例子可以用三個值來構造:'[1e300,1e200,-1e300]'應該是1e200,但sum(...)'返回0.實際數據很少像極端一樣,需要更大的列表。當然,許多大型列表根本不會出現這樣的問題(仍然有四捨五入的錯誤,但是非常合理)。有更聰明的求和算法可以避免這些問題,例如Python中存在的[Kahan求和](https://en.wikipedia.org/wiki/Kahan_summation_algorithm)爲'math.fsum'(對於上例,返回1e200) 。 – delnan