8

440 मिलियन गैर-शून्य बिंदुओं और एक स्पैस सीएससी वेक्टर "वी" (170k x 1) के साथ आयामों (170k x 170k) के साथ एक सिसी सीएससी स्पैर्स मैट्रिक्स "एसएम" को देखते हुए कुछScipy Sparse Matrices के गुणा के प्रदर्शन में सुधार

resul = sm.dot(v) 

: गैर-शून्य अंक, वहाँ कुछ भी है कि आपरेशन के प्रदर्शन में सुधार करने के लिए किया जा सकता है?

वर्तमान में यह लगभग 1 सेकंड ले रहा है। सीएसआर के रूप में मैट्रिस को शुरू करने में समय 3 सेकंड तक बढ़ गया, इसलिए सीएससी ने बेहतर प्रदर्शन किया।

एसएम उत्पादों के बीच समानता का एक मैट्रिक्स है और वी वेक्टर है जो दर्शाता है कि उपयोगकर्ता किस उत्पाद को खरीदा या क्लिक किया। तो हर उपयोगकर्ता के लिए एसएम एक ही है।

मैं उबंटू 13.04, इंटेल i3 @ 3.4GHz, 4 कोर का उपयोग कर रहा हूं।

एसओ पर शोध करने से मैं एब्लास पैकेज के बारे में पढ़ता हूं।

~$ ldd /usr/lib/python2.7/dist-packages/numpy/core/_dotblas.so 

कौन सा में हुई:

linux-vdso.so.1 => (0x00007fff56a88000) 
    libblas.so.3 => /usr/lib/libblas.so.3 (0x00007f888137f000) 
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8880fb7000) 
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8880cb1000) 
    /lib64/ld-linux-x86-64.so.2 (0x00007f888183c000) 

और के लिए मैं क्या समझ में आ इसका मतलब है कि मैं पहले से ही Ablas से एक उच्च प्रदर्शन पैकेज का उपयोग कर रहा मैं टर्मिनल में टाइप। मुझे अभी भी यकीन नहीं है कि यद्यपि यह पैकेज पहले से ही समानांतर कंप्यूटिंग लागू करता है लेकिन ऐसा लगता है कि ऐसा नहीं है।

बहु-कोर प्रोसेसिंग प्रदर्शन को बढ़ावा देने में मदद कर सकता है? यदि हां, तो क्या कोई लाइब्रेरी है जो अजगर में सहायक हो सकती है?

मैं साइथन में इसे लागू करने के विचार पर भी विचार कर रहा था लेकिन मुझे नहीं पता कि इससे अच्छे नतीजे आएंगे या नहीं।

अग्रिम धन्यवाद।

+0

वर्तमान में प्रक्रिया कितनी देर तक चल रही है? कुछ समांतर प्रसंस्करण मॉड्यूल का विवरण यहां शामिल किया गया है: https://wiki.python.org/moin/ParallelProcessing – ChrisProsser

+0

@ChrisProsser यह निर्भर करता है। यदि उपयोगकर्ता ने 15 से अधिक तक की तुलना में कई आइटम खरीदे हैं, लेकिन औसत पर यह केवल गुणात्मक संचालन में 1.34 ले रहा है। लिंक के लिए धन्यवाद, मैं इसे पहले ही पढ़ रहा हूं =) –

+1

जबकि np.dot ब्लैस का उपयोग करता है, और विभिन्न समांतर और मल्टीकोर एन्हांसमेंट्स, स्पैस डॉट नहीं हो सकता है। एसएम का घना संस्करण बहुत बड़ा हो सकता है। लेकिन यह छोटे मैट्रिक्स के साथ स्पैस और घने गति की तुलना करने के लिए निर्देशक हो सकता है। – hpaulj

उत्तर

10

स्पैर मैट्रिक्स गुणा दिनचर्या सीधे सी ++ में कोडित होती हैं, और जहां तक ​​स्रोत पर त्वरित रूप से प्रकट होता है, वहां किसी भी अनुकूलित लाइब्रेरी के लिए कोई हुक प्रतीत नहीं होता है। इसके अलावा, ऐसा लगता है कि दूसरी मैट्रिक्स गणना को कम करने के लिए एक वेक्टर है। तो आप शायद स्पैर मैट्रिक्स की गड़बड़ी तक पहुंचने और गुणा एल्गोरिदम को अनुकूलित करके चीजों को थोड़ा सा गति दे सकते हैं। निम्नलिखित कोड शुद्ध अजगर/Numpy में करता है, और अगर वेक्टर वास्तव में है "में कुछ गैर-शून्य अंक" यह scipy के सी ++ कोड की गति से मेल खाता है: यदि आप इसे Cython में लागू, गति वृद्धि ध्यान देने योग्य होना चाहिए:

def sparse_col_vec_dot(csc_mat, csc_vec): 
    # row numbers of vector non-zero entries 
    v_rows = csc_vec.indices 
    v_data = csc_vec.data 
    # matrix description arrays 
    m_dat = csc_mat.data 
    m_ind = csc_mat.indices 
    m_ptr = csc_mat.indptr 
    # output arrays 
    sizes = m_ptr.take(v_rows+1) - m_ptr.take(v_rows) 
    sizes = np.concatenate(([0], np.cumsum(sizes))) 
    data = np.empty((sizes[-1],), dtype=csc_mat.dtype) 
    indices = np.empty((sizes[-1],), dtype=np.intp) 
    indptr = np.zeros((2,), dtype=np.intp) 

    for j in range(len(sizes)-1): 
     slice_ = slice(*m_ptr[[v_rows[j] ,v_rows[j]+1]]) 
     np.multiply(m_dat[slice_], v_data[j], out=data[sizes[j]:sizes[j+1]]) 
     indices[sizes[j]:sizes[j+1]] = m_ind[slice_] 
    indptr[-1] = len(data) 
    ret = sps.csc_matrix((data, indices, indptr), 
         shape=csc_vec.shape) 
    ret.sum_duplicates() 

    return ret 

क्या चल रहा है की एक त्वरित विवरण: एक सीएससी मैट्रिक्स तीन रैखिक सरणियों में परिभाषित किया गया है:

  • data गैर शून्य प्रविष्टियों, स्तंभ प्रमुख क्रम में संग्रहित किया होता है।
  • indices गैर-शून्य प्रविष्टियों की पंक्तियां शामिल हैं।
  • indptr में मैट्रिक्स के कॉलम की संख्या से अधिक एक प्रविष्टि है, और कॉलम j में आइटम data[indptr[j]:indptr[j+1]] में पाए जाते हैं और indices[indptr[j]:indptr[j+1]] पंक्तियों में हैं।

तो एक विरल स्तंभ वेक्टर से गुणा करने के लिए, आप data और स्तंभ वेक्टर की indices से अधिक पुनरावृति कर सकते हैं, और प्रत्येक (d, r) जोड़ी के लिए, मैट्रिक्स के संगत स्तंभ निकालने और, d से गुणा यानी data[indptr[r]:indptr[r+1]] * d और indices[indptr[r]:indptr[r+1]]

+0

यह समाधान सुंदर था! मुझे समझ में नहीं आता कि यह "डॉट" ऑपरेशन से तेज़ क्यों है लेकिन यह निश्चित रूप से बहुत अच्छी तरह से काम करता है। समय 1s से लगभग 6ms तक गिर गया ...! सिफारिश सूची को छंटनी अब नई बाधा बन गई! बहुत धन्यवाद जैम, अद्भुत समाधान! –

+0

आपको साइथन में किसी भी सामान को फिर से लिखने के बिना कोड के साथ उस गति में वृद्धि हुई है? यह आश्चर्यजनक है, और मैंने अपने परीक्षणों पर जो देखा वह नहीं। या तो आपके मैट्रिक्स और वेक्टर आपके प्रश्न के मुकाबले ज्यादा स्पैस हैं, या आप दो बार जांचना चाहेंगे कि कोई टाइपो नहीं है, और आपको '.dot' के समान परिणाम मिल रहे हैं। – Jaime

+0

मैंने परिणाम की दोबारा जांच की और यह सही है। यदि आपने एक ही समय में गिरावट नहीं देखी है तो मुझे आश्चर्य है कि मेरे पिछले कोड में कुछ गड़बड़ है ... अब यह बहुत अच्छी तरह से काम कर रहा है। –

1

हाल ही में मुझे एक ही समस्या थी। मैंने इसे इस तरह हल किया।

def sparse_col_vec_dot(csc_mat, csc_vec): 
    curr_mat = csc_mat.tocsr() 
    ret curr_mat* csc_vec 

चाल यहाँ हम पंक्ति प्रतिनिधित्व और स्तंभ प्रतिनिधित्व के रूप में अन्य संस्करण के रूप में मैट्रिक्स का एक संस्करण बनाने के लिए है।

संबंधित मुद्दे