2015-07-14 5 views
5

क्या आप Haskell में इस एल्गोरिदम को लिखने के लिए उपयोग करेंगे? क्या उनके बिना इसे व्यक्त करने का कोई तरीका है? मध्य में से कार्यों को निकालना मुश्किल है जिसका मतलब है। यह सिर्फ मशीन लर्निंग सिस्टम का आउटपुट है।हास्केल में आप इसे कैसे व्यक्त करेंगे?

मैं एचटीएमएल सामग्री के खंडों को वर्गीकृत करने के लिए एल्गोरिदम लागू कर रहा हूं क्योंकि सामग्री या बॉयलरप्लेट ने here का वर्णन किया है। इस वजन में पहले से ही कड़ी मेहनत की गई है।

curr_linkDensity <= 0.333333 
| prev_linkDensity <= 0.555556 
| | curr_numWords <= 16 
| | | next_numWords <= 15 
| | | | prev_numWords <= 4: BOILERPLATE 
| | | | prev_numWords > 4: CONTENT 
| | | next_numWords > 15: CONTENT 
| | curr_numWords > 16: CONTENT 
| prev_linkDensity > 0.555556 
| | curr_numWords <= 40 
| | | next_numWords <= 17: BOILERPLATE 
| | | next_numWords > 17: CONTENT 
| | curr_numWords > 40: CONTENT 
curr_linkDensity > 0.333333: BOILERPLATE 

उत्तर

6

चूंकि इस निर्णय वृक्ष है कि एक बॉयलरप्लेट राज्य की ओर जाता है में सिर्फ तीन रास्ते हैं, मैं सिर्फ पुनरावृति और उन्हें सरल बनाने चाहते हैं:

isBoilerplate = 
    prev_linkDensity <= 0.555556 && curr_numWords <= 16 && prev_numWords <= 4 
    || prev_linkDensity > 0.555556 && curr_numWords <= 40 && next_numWords <= 17 
    || curr_linkDensity > 0.333333 
+4

मुझे लगता है कि आप चाहते हैं 'or', नहीं' any'। इसके अलावा आप '||' का उपयोग कर सकते हैं, या '& '' के बजाय 'और' का उपयोग कर सकते हैं। –

11

मैन्युअल तर्क को सरल बनाने नहीं (यह मानते हुए आप उत्पन्न हो सकता है यह कोड स्वचालित रूप से), मुझे लगता है कि MultiWayIf का उपयोग करना बहुत साफ और सीधा है।

{-# LANGUAGE MultiWayIf #-} 

data Stats = Stats { 
    curr_linkDensity :: Double, 
    prev_linkDensity :: Double, 
    ... 
} 

data Classification = Content | Boilerplate 

classify :: Stats -> Classification 
classify s = if 
    | curr_linkDensity s <= 0.333333 -> if 
     | prev_linkDensity s <= 0.555556 -> if 
     | curr_numWords s <= 16 -> if 
      | next_numWords s <= 15 -> if 
      | prev_numWords s <= 4 -> Boilerplate 
      | prev_numWords s > 4 -> Content 
      | next_numWords s > 16 -> Content 
     ... 

और इसी तरह।

हालांकि, चूंकि यह इतना संरचित है - अगर तुलना के साथ/बस एक पेड़ भी है, तो निर्णय पेड़ डेटा संरचना बनाने और इसके लिए एक दुभाषिया लिखने पर भी विचार करें। यह आपको परिवर्तन, कुशलता, निरीक्षण करने की अनुमति देगा। शायद यह आपको कुछ खरीद लेगा; अपने विनिर्देशों के लिए लघु भाषाओं को परिभाषित करना आश्चर्यजनक रूप से फायदेमंद हो सकता है।

data DecisionTree i o 
    = Comparison (i -> Double) Double (DecisionTree i o) (DecisionTree i o) 
    | Leaf o 

runDecisionTree :: DecisionTree i o -> i -> o 
runDecisionTree (Comparison f v ifLess ifGreater) i 
    | f i <= v = runDecisionTree ifLess i 
    | otherwise = runDecisionTree ifGreater i 
runDecisionTree (Leaf o) = o 

-- DecisionTree is an encoding of a function, and you can write 
-- Functor, Applicative, and Monad instances! 

फिर

classifier :: DecisionTree Stats Classification 
classifier = 
    Comparison curr_linkDensity 0.333333 
     (Comparison prev_linkDensity 0.555556 
     (Comparison curr_numWords 16 
      (Comparison next_numWords 15 
      (Comparison prev_numWords 4 
       (Leaf Boilerplate) 
       (Leaf Content)) 
      (Leaf Content) 
      ... 
+2

पहली विधि के लिए, 'मल्टीवेइफ़' एक्सटेंशन आपको उस सुंदर को लिखने की अनुमति देता है, 'if'' के 'case() को बदलकर' if'। –

+0

@ ØrjanJohansen, यह अच्छा है, अद्यतन किया गया है। :-) – luqui

+3

मामूली टिप्पणी: मेरे पास गार्ड के लिए व्यक्तिगत विचलन है जो सभी मामलों को कवर करने के लिए है (यानी संपूर्ण हो) और अंतिम गार्ड के लिए 'अन्यथा' का उपयोग न करें। मैं 'अन्यथा 'का उपयोग करता हूं क्योंकि मुझे यह इरादा बेहतर तरीके से व्यक्त करने के लिए मिलता है, मुझे दो बार शर्त दोहराने की ज़रूरत नहीं है, और यह और भी अधिक कुशल है कि कुछ भी। साथ ही, जब एक आंतरिक 'if' में गैर-संपूर्ण शाखाएं होती हैं, तो यह बहुत आसान है (मेरे लिए, कम से कम) यह सोचने के लिए कि हास्केल अगली बाहरी' if' शाखा में वापस आ जाएगा। हालांकि यह मामला नहीं है, और एक गैर-संपूर्ण मैच रनटाइम त्रुटि उत्पन्न होती है। इन कारणों से मैं दृढ़ता से अंतिम विकल्प – chi

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