CD + درخت الگورتھم کا نفاذ

C Implementation Kd Tree Algorithm



اس مضمون کو پڑھنے سے پہلے ، کے این این الگورتھم اور کے ڈی درخت کو سمجھنے کے لئے متعلقہ معلومات سے مشورہ کرنے کی سفارش کی جاتی ہے۔

بنیادی علم

جیسا کہ اعداد و شمار میں دکھایا گیا ہے ، فرض کریں ایک نقطہ a موجودہ قریبی پڑوسی | b ہے ، اگر یہ b کے نسبت موجود ہے a سے دور قریب قریب ، پھر یہ نکتہ ضرور ہونا چاہئے | _ _ _ _ | دائرہ کا مرکز ہے ، a دائرے کا رداس ہے۔
اب اگر دائیں طرف کا علاقہ نامعلوم ہے ، اگر | _ _ + _ | تقسیم کرنے والی لائن کا فاصلہ ab موجودہ قریب ترین فاصلے سے زیادہ | _ _ _ | (دائرہ رداس) ، دائیں طرف نامعلوم علاقے میں قریبی پڑوسیوں کی تلاش جاری رکھنے کی ضرورت نہیں ہے (شکل 1) ، اس کے برعکس ، آپ کو تلاش جاری رکھنا ہوگی ( چترا 2)۔
اسی کے مطابق ، یہ کثیر جہتی جگہ کی پیش گوئی کی گئی ہے۔ اگر قطعہ تقسیم کی حد پہلی ہے۔ _ + _ | طول و عرض ، اس تقسیم نقطہ کی قدر a (اسکیلر) ، موجودہ قریبی پڑوسی ہے l (ویکٹر) اگر ہدف نقطہ L (ویکٹر) قطعہ بندی کی حد کا فاصلہ | x [i] - v | مندرجہ ذیل تعلقات کو مطمئن کریں

، آپ کو دوسری طرف تلاش جاری رکھنے کی ضرورت ہے۔



1:



دو:
عام طور پر ، مشین سیکھنے کے الگورتھم | i میں تقسیم کیا جاتا ہے v کے ساتھ خطوط کی تلاش پر مبنی دو مراحل y ایک سست الگورتھم ہے ، یہ کمپیوٹنگ کے سارے کاموں کو x پر رکھتا ہے اسٹیج ، fit وقت کی پیچیدگی | predict ، KD درخت لکیری تلاش سے زیادہ تیز ہے کیونکہ اس کام کا ایک حصہ رکھتا ہے | تلاش کے دوران خارج کیا جاسکتا ہے (وقت کی پیچیدگی KNN)。
مندرجہ بالا نسبتا آسان ہے۔ کے این این الگورتھم اور کے ڈی درخت کی تفصیلات کے لئے ، براہ کرم ڈاکٹر لی ہینگ کے 'شماریاتی سیکھنے کا طریقہ' دیکھیں۔



کوڈ

ہم کچھ کلیدی کوڈ دیتے ہیں۔

بنیادی اعداد و شمار کا ڈھانچہ

  • ٹریننگ سیٹ کے لئے ایک جہتی صف predict اشارہ کرتا ہے کہ اس کی لمبائی ہے predict، لیبل سیٹ ایک جہتی صف کو بھی استعمال کرتا ہے O(n) اشارہ کرتا ہے کہ اس کی لمبائی | _ _ _ _ |。
  • درخت کے نوڈس کو مندرجہ ذیل اعداد و شمار کی ساخت سے ظاہر کیا جاتا ہے
    fit
  • مندرجہ ذیل ڈھانچے کے ذریعہ کے ڈی ٹری ماڈل کی نمائندگی کی جاسکتی ہے
    O(1)
  • جب کے قریبی پڑوسیوں کی تلاش کرتے ہو تو ، ایک بڑے ٹاپ ڈھیر کی ضرورت ہوتی ہے۔ ہم موجود double *data کی نمائندگی کرنے کے لئے براہ راست C ++ ترجیحی قطار استعمال کرتے ہیں پڑوسیوں میں ، آزمائشی نقطہ سے دور دراز کے ڈھیر پر ہے

    n_samples * n_features

کے ڈی ٹری کلاس

ہم کلاس کا استعمال کرتے ہیں double *labels کے ڈی ٹری کلاس کی نمائندگی کرتا ہے ، جس میں افعال ہونے چاہئیں n_samples ساتھ cpp
struct tree_node
{
size_t id // represents the i-th data in the training set
size_t split // The dimension of split
tree_node *left, *right // left and right subtree
}



cpp
struct tree_model
{
tree_node *root // root node
const double *datas // X
const double *labels // y
size_t n_samples // number of samples
size_t n_features // The number of features for each sample
double p // Distance measurement
}

قطعہ طول و عرض اور قطعہ بندی نقطہ تلاش کریں

درخت بنانے سے پہلے ، ہمیں اس بات پر غور کرنا ہوگا کہ قطعہ طول و عرض اور قطعہ بندی نقطہ کا انتخاب کیسے کریں۔ تقسیم کے طول و عرض کے لئے بہت سارے اختیارات موجود ہیں ، عام ، آپ لے سکتے ہیں۔ _ + _ | ، یعنی ، موجودہ درخت کی پرتوں کی تعداد خصوصیات کی تعداد کی باقی ہے ، ہم یہاں استعمال کرتے ہیں۔ _ + _ | ، وہ ہے ، موجودہ نوڈ سیٹ میں سب سے بڑی رینج والے جہت کا انتخاب کریں۔

n(n <= k)

فریکٹ جہت کا انتخاب struct neighbor_heap_cmp { bool operator()(const std::tupledouble> &i, const std::tupledouble> &j) { return std::get<1>(i) <std::get<1>(j) } } typedef std::tupledouble> neighbor typedef std::priority_queuestd::vector, neighbor_heap_cmp> neighbor_heap_ neighbor_heap k_neighbor_heap_ اس کے بعد ، ہمیں پہلے KDTree میں موجودہ نوڈ سیٹ میں نوڈ کو منتخب کرنے کی ضرورت ہے طول و عرض کی درمیانی قیمت Contribute نقطہ کو چھوڑ کر کٹ پوائنٹ کی قدر کے طور پر ، پہلا search for طول و عرض کی قدر | _ _ + _ | سے کم یا اس کے برابر ہے ، اسے بائیں ضمنی میں ڈالیں ، ورنہ اسے دائیں سب ٹری میں ڈالیں۔
میڈین کو ڈھونڈتے وقت ، ہر طرح کی چھانٹ نہ لگائیں ، پھر درمیانی نقطہ اختیار کریں ، آپ تیزی سے چھانٹتے ہوئے جیسا طریقہ استعمال کرسکتے ہیں ، اور میڈین ملنے پر چھانٹنا بند کردیں۔ ہم یہاں الگورتھم نہیں لکھیں گے۔ اب ، براہ راست C ++ افعال استعمال کریں۔

//(Simplified code, see the end for the complete code) class KDTree { public: // Build a tree KDTree(const double *datas, const double *labels, size_t rows, size_t cols, double p) // return to the tree tree_node *GetRoot() { return root } // Find the k neighbors of a test point std::vector<std::tupledouble>> FindKNearests(const double *coor, size_t k) private: tree_node *root_ }

تعاون کریں

درخت بنانے کے لئے بائنری درخت کی تعمیر کے طریقہ کار پر براہ راست عمل کریں

dim = floor % n_features

کے قریبی پڑوسیوں کی تلاش کے لئے قواعد

عام طور پر ، کتاب جس کے بارے میں بات کرتی ہے وہ قریبی پڑوسیوں کی تلاش میں ہے ، لیکن یہاں ہم کے قریبی پڑوسیوں کی تلاش کر رہے ہیں ، جس کے لئے کتاب پر الگورتھم کی تھوڑی توسیع کی ضرورت ہے۔
قریبی پڑوسیوں کی تلاش کرتے وقت ، ہم عام طور پر دو متغیرات طے کرتے ہیں dim = argmax(nmax - nmin) | | + + _ | ، کے ساتھ ، اگر اس وقت تلاش کیے جانے والے مقام سے فاصلہ آزمائشی نقطہ (Here is incomplete code, please refer to the complete source code for the definition of some tool functions) size_t KDTree::FindSplitDim(const std::vector &points) { if (points.size() == 1) return 0 size_t cur_best_dim = 0 double cur_largest_spread = -1 double cur_min_val double cur_max_val for (size_t dim = 0 dim 0], dim) cur_max_val = GetDimVal(points[0], dim) for (const auto &id : points) { if (GetDimVal(id, dim) > cur_max_val) cur_max_val = GetDimVal(id, dim) else if (GetDimVal(id, dim) if (cur_max_val - cur_min_val > cur_largest_spread) { cur_largest_spread = cur_max_val - cur_min_val cur_best_dim = dim } } return cur_best_dim } | وقت ، ہم مذکورہ بالا دو متغیرات کو نئے پوائنٹ پر اپ ڈیٹ کریں۔ _ + _ | k。 کے ساتھ
اسی مناسبت سے ، جب کے قریبی پڑوسیوں کی تلاش ہوتی ہے تو ، ہم ایک k مقرر کرسکتے ہیں عناصر کا ایک بہت بڑا ڈھیر ، تاکہ ڈھونڈتے وقت ، جب ڈھیر بھرا ہوا ہو ، آپ کو صرف موجودہ سرچ پوائنٹ کا موازنہ کرنا ہوگا | کیا یہ ڈھیر کے لمبے حصے سے چھوٹا ہے x، اگر یہ اس سے کم ہے تو ڈھیر سے اوپر کو نکال دیا جائے گا اور موجودہ سرچ پوائنٹ کو آگے بڑھا دیا جائے گا ، بصورت دیگر ، جب ڈھیر لگے گا تو یہ کوئی بدلاؤ نہیں رہے گا بھرا ہوا نہیں ہے ، سرچ پوائنٹ کو براہ راست آگے بڑھایا جائے گا۔

کے قریب ترین پڑوسیوں کی تلاش کے ل for الگورتھم

ہم بائنری ٹری کی گہرائی سے پہلے عبور کرنے کے الگ الگ الگھم براہ راست استعمال کرتے ہیں (تفصیلات کے لئے ، 'شماریات کے سیکھنے کے طریقوں' کے صفحہ 43 پر الگورتھم 3.3 ملاحظہ کریں)۔

k

مکمل کوڈ

دیکھیں https://github.com/ बुद्धिमानDoge/libkdtree
کے ڈی-ٹری کوڈ کے علاوہ ، مکمل کوڈ ٹیسٹ کوڈ اور ازگر انٹرفیس کوڈ کے ساتھ ساتھ تیسرے فریق کی لائبریریوں کو تیز کرنے کے ل call کچھ ذرائع بتاتا ہے۔

اصل پتہ

http://www.jianshu.com/p/80e41da2a397