日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入對比數(shù)據(jù)科學(xué)工具箱:Python和R的C/C++實(shí)現(xiàn)

概述

成都創(chuàng)新互聯(lián)公司是專業(yè)的惠濟(jì)網(wǎng)站建設(shè)公司,惠濟(jì)接單;提供做網(wǎng)站、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行惠濟(jì)網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

幾周前,我有幸在 Scipy 大會上發(fā)表了 Civis如何使用Python和R的演講。為什么要在一個Python大會上大談R呢?這是要挑起一個Python和R語言的一場戰(zhàn)爭嗎?不是的!討論哪個語言比較好簡直是浪費(fèi)時間。在 Civis,我們很愉快地同時使用這兩種語言,不僅僅是在我們?nèi)粘9ぷ髦薪鉀Q數(shù)據(jù)科學(xué)問題,也用它們來寫一些其他工具。下面是我在SciPy 大會上的一些討論。

問題現(xiàn)狀

我們 Civis 的同事有著十分不同的學(xué)術(shù)背景。我效力的研發(fā)團(tuán)隊(duì)有一個物理學(xué)家、一個經(jīng)濟(jì)學(xué)家、兩個統(tǒng)計學(xué)家以及一位土木工程師組成。在 Civis,每個人在數(shù)據(jù)科學(xué)上都會做一些不同內(nèi)容的工作,有的領(lǐng)域是R比較流行,有的領(lǐng)域是Python比較流行,還有的一些是Matlab。在這種場景下只支持一種語言并不是一個明智的選擇。遷移到一門新語言上會花費(fèi)許多時間,拋開在學(xué)院或者業(yè)界多年的技能回報,允許人們使用它們所熟悉的工具可以確保大家有更高的生成效率。

另外一個我們同時使用兩種語言的原因是已有的統(tǒng)計學(xué)工具與包。在解決數(shù)據(jù)科學(xué)問題上,我們經(jīng)常遇到在某些特定管道上需要某一種特定語言。我們的調(diào)研管道是一個很好的例子。確保隨機(jī)樣本具有全集代表性是需要一個被稱為 raking 的過程的,傳統(tǒng)上,Python 在社會科學(xué)上并不流行,因此我們只會用R來完成這件事情。當(dāng)然調(diào)查也包括了QA的全文檢索,在某種程度上來說R在NLP社區(qū)上并不是很流行,因此這個部分將會由Python來完成。而分析調(diào)查數(shù)據(jù)只是我們在Civis解決問題的一個小步驟。

結(jié)合許多不同的語言來實(shí)現(xiàn)工作流是具有挑戰(zhàn)性的。數(shù)據(jù)科學(xué)平臺幫助我們可以提交一連串任務(wù)節(jié)點(diǎn),然后交由基礎(chǔ)設(shè)施負(fù)責(zé)獨(dú)立調(diào)用每個任務(wù)節(jié)點(diǎn),且前后不依賴。但是這并不是一個十分理想的情況。原因有二,其一,這樣做整個任務(wù)就顯得破碎化,稍有修改某個任務(wù),往往會導(dǎo)致全局失敗,而且任何人在這個分布式系統(tǒng)中所做的工作都只了解局部情況,而不知道全局情況。第二,這樣做并不高效。在兩個語言中切換通常需要將數(shù)據(jù)以特定格式加載到磁盤上(通常最壞的情況是csv格式)。這樣不僅僅是解析成本比較高,而且還會丟失一些類型信息。

解決方案

我概述了在Civis遇到的種種問題,但是到底什么是理想的狀態(tài)呢?最***的解決方案是我們可以無縫切換工具和語言。許多熟悉Python的人喜歡用Python做數(shù)據(jù)分析,R也是類似的。事實(shí)證明這是完全有可能實(shí)現(xiàn),有相當(dāng)數(shù)量的項(xiàng)目已經(jīng)開始作為跨語言工具:TensorFlow, XGBoost, 和 Stan 都在Civis被廣泛運(yùn)用。移植或安利一個已有的工具也是可能的,我們已經(jīng)成功地完成了glmnetR包的安利。

對另一些為讀者寫數(shù)據(jù)科學(xué)工具的人來說,他們從一開始就考慮了這些跨語言。有一些方法可以做到這一點(diǎn),但我個人最喜歡的是用C語言來寫底層,然后使用各自的Python和R C api做一些綁定/封裝。Python和R實(shí)際上是用C實(shí)現(xiàn)的,這是條阻力最小的路徑。C是一門古老語言,C語言社區(qū)已經(jīng)演進(jìn)出了一些強(qiáng)大的工具鏈?;逎木幾g器錯誤消息已經(jīng)成為了過去時,GCC和Clang(***的編譯器)給友善的消息反饋(Clang網(wǎng)站可以看到栗子)?,F(xiàn)在還有各種各樣的“消毒液”來輔助捕獲內(nèi)存泄漏等常見錯誤或未定義的行為(llvm文檔)。

案例

下面我們通過一個小例子,用C編寫一個函數(shù),使這可調(diào)用的Python和R。代碼以及幻燈片從我的GitHub上可以找到。

Python

我們將下面的Python函數(shù)轉(zhuǎn)換為C:

 
 
  1. def tally(s): 
  2.     total = 0 
  3.     for elm in s: 
  4.         total += elm 
  5.     return total  

C

這是相同的功能用C實(shí)現(xiàn):

 
 
  1. #include  
  2.  
  3. double tally(double *s, size_t n) { 
  4.     double total = 0; 
  5.     for (size_t i = 0; i < n; i++) { 
  6.         total += s[i]; 
  7.     } 
  8.     return total; 
  9. }  

注意到它看起來并不是都不同的Python函數(shù)。當(dāng)然,除了有一些類型注解和額外的語法噪音大括號外,我們還必須跟蹤數(shù)組的長度,但整體邏輯是一樣的。

接下來,我們需要實(shí)現(xiàn)一個Python綁定,允許用戶調(diào)用這個函數(shù)就像任何其他Python函數(shù)。

Cython 

 
 
  1. #include  
  2. #include "Python.h" 
  3. #include "tally.h" 
  4.  
  5. static PyObject *tally_(PyObject *self, PyObject *args) { 
  6.     PyObject *buf; 
  7.     if (!PyArg_ParseTuple(args, "O", &buf)) { 
  8.         return NULL; 
  9.     } 
  10.  
  11.     Py_buffer view; 
  12.     int buf_flags = PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT; 
  13.     if (PyObject_GetBuffer(buf, &view, buf_flags) == -1) { 
  14.         return NULL; 
  15.     } 
  16.      
  17.     if (strcmp(view.format,"d") != 0) { 
  18.         PyErr_SetString(PyExc_TypeError, "we only take floats :("); 
  19.         PyBuffer_Release(&view); 
  20.         return NULL; 
  21.     } 
  22.  
  23.     double result = tally(view.buf, view.shape[0]); 
  24.     PyBuffer_Release(&view); 
  25.     return Py_BuildValue("d", result); 
  26.  
  27. static PyMethodDef MethodTable[] = { 
  28.     {"tally", &tally_, METH_VARARGS, "Compute the sum of an array"},  
  29.     { NULL, NULL, 0, NULL} 
  30. }; 
  31.  
  32. static struct PyModuleDef tally_module = { 
  33.     .m_base = PyModuleDef_HEAD_INIT, 
  34.     .m_name = "tally_", 
  35.     .m_size = -1, 
  36.     .m_methods = MethodTable 
  37. }; 
  38.  
  39.  
  40. PyMODINIT_FUNC PyInit_tally_(void) { 
  41.     return PyModule_Create(&tally_module); 
  42. }  

這里有很多實(shí)現(xiàn)的方法,但大多數(shù)只是Python模塊的一部分樣板代碼。

在最上面,我們定義了一個函數(shù),它接受一個Python對象,并且檢查這是一個適當(dāng)類型的數(shù)組,再調(diào)用我們的計數(shù)功能,然后返回結(jié)果。其余的代碼模塊定義,告訴Python解釋器我們計數(shù)功能的名稱和它的參數(shù)類型。

R

R的過程非常相似,但是更加簡潔:

 
 
  1. #include  
  2. #include  
  3. #include  
  4. #include "tally.h" 
  5.  
  6. SEXP tally_(SEXP x_) { 
  7.   double *x = REAL(x_); 
  8.   int n = length(x_); 
  9.    
  10.   SEXP out = PROTECT(allocVector(REALSXP, 1)); 
  11.   REAL(out)[0] = tally(x, n); 
  12.   UNPROTECT(1); 
  13.    
  14.   return out; 
  15.  
  16. static R_CallMethodDef callMethods[] = { 
  17.   {"tally_", (DL_FUNC)&tally_, 1}, 
  18.   {NULL, NULL, 0} 
  19. }; 
  20.  
  21. void R_init_tallyR(DllInfo *info) { 
  22.   R_registerRoutines(info, NULL, callMethods, NULL, NULL); 

 這里需要的代碼量顯著減少,因?yàn)镽和Python類型系統(tǒng)有所不同,沒有真正標(biāo)量類型,所以我們不需要做相同級別的檢驗(yàn)/驗(yàn)證用戶輸入我們在上面的Python示例。剩下的代碼大致相同,我們定義一個組函數(shù)可在R編譯。

總結(jié)

一個真實(shí)世界的例子一定會更加復(fù)雜,但整個過程并不是那么困難。在編寫跨語言工具時有幾件事要記住:

  • 如果你打算在兩者之間共享函數(shù)就不要依賴宿主語言的api(R或Python)代碼。
  • 使用錯誤碼來傳遞異常提示,不要直接調(diào)用退出或者在宿主語言里面才處理異常。
  • ***用宿主語言負(fù)責(zé)內(nèi)存分配和重分配,這意味著你的C/C++代碼應(yīng)該要略過預(yù)先分配的內(nèi)存和輸出過程。
  • 相信編譯器,你也應(yīng)該重視編譯器的錯誤和警告。如果代碼在編譯時有警告那代碼就不算寫完。

無論是哪個“贏得”這場語言戰(zhàn)爭,Python和R都將保持在數(shù)據(jù)科學(xué)屆的地位。這意味著為工具開發(fā)者不能忽視的另外一門語言,構(gòu)建有用的工具就得保證這兩種語言都可以使用。一個簡單的方式是用C或c++編寫大量代碼,然后用 C 的 API的為兩種語言提供封裝。


網(wǎng)頁題目:深入對比數(shù)據(jù)科學(xué)工具箱:Python和R的C/C++實(shí)現(xiàn)
標(biāo)題URL:http://www.5511xx.com/article/dhphgjd.html