Https://stackoverflow.com/users/1515832/generic-human द्वारा उत्तर महान है। लेकिन इसके सबसे अच्छे क्रियान्वयन को मैंने कभी अपनी पुस्तक 'ब्यूटीफुल डेटा' में खुद पीटर नोरविग को लिखा था।
इससे पहले कि मैं उसका कोड पेस्ट करूं, मुझे इस पर विस्तार करना चाहिए कि नॉरविग का तरीका अधिक सटीक क्यों है (हालांकि कोड के संदर्भ में थोड़ा धीमा और लंबा)।
1) डेटा थोड़ा बेहतर है - आकार के संदर्भ में और सटीकता के संदर्भ में (वह एक साधारण रैंकिंग के बजाय एक शब्द गणना का उपयोग करता है) 2) अधिक महत्वपूर्ण बात, यह n- ग्राम के पीछे तर्क है जो वास्तव में दृष्टिकोण को इतना सटीक बनाता है ।
अपनी पुस्तक में उन्होंने जो उदाहरण दिया है, वह एक स्ट्रिंग 'सिटडाउन' को विभाजित करने की समस्या है। अब स्ट्रिंग विभाजन की एक गैर-बिग्राम विधि पी () सिट ’) * पी (-डाउन’) पर विचार करेगी, और यदि यह पी (down सिटडाउन ’) से कम है - जो कि अक्सर होगा - तो यह विभाजित नहीं होगा यह है, लेकिन हम इसे (ज्यादातर समय) चाहते हैं।
हालाँकि जब आपके पास बिग्राम मॉडल होता है तो आप p ('बैठ जाओ') को एक bigram बनाम p ('सिटडाउन') और पूर्व जीत के रूप में मान सकते हैं। मूल रूप से, यदि आप bigrams का उपयोग नहीं करते हैं, तो यह उन शब्दों की संभावना का इलाज करता है जिन्हें आप स्वतंत्र रूप से विभाजित कर रहे हैं, जो कि मामला नहीं है, कुछ शब्द एक के बाद एक दिखाई देने की अधिक संभावना है। दुर्भाग्य से वे शब्द भी हैं जो अक्सर कई उदाहरणों में एक साथ अटक जाते हैं और अलग हो जाते हैं।
यहां डेटा का लिंक है (यह 3 अलग-अलग समस्याओं के डेटा है और विभाजन केवल एक है। कृपया विवरण के लिए अध्याय पढ़ें): http://norvig.com/ngrams/
और यहाँ कोड का लिंक है: http://norvig.com/ngrams/ngrams.py
इन लिंक को कुछ समय हो गया है, लेकिन मैं कोड के विभाजन भाग को वैसे भी कॉपी करूँगा
import re, string, random, glob, operator, heapq
from collections import defaultdict
from math import log10
def memo(f):
"Memoize function f."
table = {}
def fmemo(*args):
if args not in table:
table[args] = f(*args)
return table[args]
fmemo.memo = table
return fmemo
def test(verbose=None):
"""Run some tests, taken from the chapter.
Since the hillclimbing algorithm is randomized, some tests may fail."""
import doctest
print 'Running tests...'
doctest.testfile('ngrams-test.txt', verbose=verbose)
################ Word Segmentation (p. 223)
@memo
def segment(text):
"Return a list of words that is the best segmentation of text."
if not text: return []
candidates = ([first]+segment(rem) for first,rem in splits(text))
return max(candidates, key=Pwords)
def splits(text, L=20):
"Return a list of all possible (first, rem) pairs, len(first)<=L."
return [(text[:i+1], text[i+1:])
for i in range(min(len(text), L))]
def Pwords(words):
"The Naive Bayes probability of a sequence of words."
return product(Pw(w) for w in words)
#### Support functions (p. 224)
def product(nums):
"Return the product of a sequence of numbers."
return reduce(operator.mul, nums, 1)
class Pdist(dict):
"A probability distribution estimated from counts in datafile."
def __init__(self, data=[], N=None, missingfn=None):
for key,count in data:
self[key] = self.get(key, 0) + int(count)
self.N = float(N or sum(self.itervalues()))
self.missingfn = missingfn or (lambda k, N: 1./N)
def __call__(self, key):
if key in self: return self[key]/self.N
else: return self.missingfn(key, self.N)
def datafile(name, sep='\t'):
"Read key,value pairs from file."
for line in file(name):
yield line.split(sep)
def avoid_long_words(key, N):
"Estimate the probability of an unknown word."
return 10./(N * 10**len(key))
N = 1024908267229 ## Number of tokens
Pw = Pdist(datafile('count_1w.txt'), N, avoid_long_words)
#### segment2: second version, with bigram counts, (p. 226-227)
def cPw(word, prev):
"Conditional probability of word, given previous word."
try:
return P2w[prev + ' ' + word]/float(Pw[prev])
except KeyError:
return Pw(word)
P2w = Pdist(datafile('count_2w.txt'), N)
@memo
def segment2(text, prev='<S>'):
"Return (log P(words), words), where words is the best segmentation."
if not text: return 0.0, []
candidates = [combine(log10(cPw(first, prev)), first, segment2(rem, first))
for first,rem in splits(text)]
return max(candidates)
def combine(Pfirst, first, (Prem, rem)):
"Combine first and rem results into one (probability, words) pair."
return Pfirst+Prem, [first]+rem