2012-04-08 21 views
1

Ich habe einige Daten wie folgt, wobei das zweite Feld die Wahrscheinlichkeit des ersten Feldes ist, also "0: 0.017" bedeutet 0.017 Chance von 0. Die Summe aller Wahrscheinlichkeit ist 1.Was ist eine gute Möglichkeit, Bereiche auf einer Nummernleitung einzurichten?

Meine Frage ist: Wie gehe ich von den Wahrscheinlichkeiten aus, so dass ich die untere Grenze und die obere Grenze jedes Zeichens finden kann? also wäre 0 [0, 0,017), [0,017, 0,022) und so weiter.

Ich versuche, die arithmetische Codierung zu implementieren.

(0: 0.017, 
1: 0.022, 
2: 0.033, 
3: 0.033, 
4: 0.029, 
5: 0.028, 
6: 0.035, 
7: 0.032, 
8: 0.028, 
9: 0.027, 
a: 0.019, 
b: 0.022, 
c: 0.029, 
d: 0.03, 
e: 0.028, 
f: 0.035, 
g: 0.026, 
h: 0.037, 
i: 0.029, 
j: 0.025, 
k: 0.025, 
l: 0.037, 
m: 0.025, 
n: 0.023, 
o: 0.026, 
p: 0.035, 
q: 0.033, 
r: 0.031, 
s: 0.023, 
t: 0.022, 
u: 0.038, 
v: 0.022, 
w: 0.016, 
x: 0.026, 
y: 0.021, 
z: 0.033,) 

edit *

NVM ich es herausgefunden, nur auf der dummen Mathe vermasselt ... Danke für alle Eingänge !!!

+0

Ihre Daten in einer Textdatei?Oder ist das eine Art Datenstruktur? – George

+0

@George brauchen eine Datenstruktur, ich bekomme die Wahrscheinlichkeiten aus einer Textdatei von zufälligen Zeichen/Zahlen – iCodeLikeImDrunk

+3

* "0 wäre [0, 0,017), [0,017, 0,022)" * - Meinst du nicht "0 wäre [ 0, 0.017), 1 wäre [0.017, 0.017 + 0.022), 2 wäre [0.017 + 0.022, 0.017 + 0.022 + 0.033) " – ninjagecko

Antwort

2
# The data is input as '1: 0.022,' format 
def process_data(line): 
    # for returning the new string that is cleaned up 
    result_line = '' 
    for character in line: 
     # check if it is either a number or a letter 
     if character.isdigit() or character.isalpha(): 
      result_line += character 
     # we want the decimal point 
     elif character == '.': 
      result_line += character 
     # else we replace it with space ' ' 
     else: 
      result_line += ' ' 
    return result_line 

my_list = [] 

with open('input.txt') as file: 
    for lines in file: 
     processed_line = process_data(lines) 
     # temp_list has ['letter', 'frequency'] 
     temp_list = (processed_line.split()) 
     value = temp_list[0] 
     # Require to cast it to a float, since it is a string 
     frequency = float(temp_list[1]) 
     my_list.append([value, frequency]) 

print(my_list)   

Von diesem Zeitpunkt an können Sie herausfinden, was mit Ihren Werten zu tun. Ich habe den Code dokumentiert (eine wirklich einfache naive Möglichkeit, die Eingabedatei zu verarbeiten). Aber die my_list ist jetzt sauber und schön formatiert, mit string (Wert) und float (Häufigkeit). Ich hoffe das hilft.

Ausgabe des Codes von oben:

[['0', 0.017], ['1', 0.022], ['2', 0.033], ['3', 0.033], 
['4', 0.029], ['5', 0.028], ['6', 0.035], ['7', 0.032], 
['8', 0.028], ['9', 0.027], ['a', 0.019], ['b', 0.022], 
['c', 0.029], ['d', 0.03], ['e', 0.028], ['f', 0.035], 
['g', 0.026], ['h', 0.037], ['i', 0.029], ['j', 0.025], 
['k', 0.025], ['l', 0.037], ['m', 0.025], ['n', 0.023], 
['o', 0.026], ['p', 0.035], ['q', 0.033], ['r', 0.031], 
['s', 0.023], ['t', 0.022], ['u', 0.038], ['v', 0.022], 
['w', 0.016], ['x', 0.026], ['y', 0.021], ['z', 0.033]] 

Und dann ...

# Took a page out of TokenMacGuy, credit to him 
distribution = [] 
distribution.append(0.00) 
total = 0.0 # Create a float here 

for entry in my_list: 
    distribution.append(entry[1]) 
    total += frequency 
    total = round(total, 3) # Rounding to 2 decimal points 

distribution.append(1.00) # Missing the 1.00 value 
print(distribution) # Print to check 

Ausgabe ist hier:

[0.0, 0.017, 0.022, 0.033, 0.033, 0.029, 0.028, 0.035, 0.032, 
0.028, 0.027, 0.019, 0.022, 0.029, 0.03, 0.028, 0.035, 0.026, 
0.037, 0.029, 0.025, 0.025, 0.037, 0.025, 0.023, 0.026, 0.035, 
0.033, 0.031, 0.023, 0.022, 0.038, 0.022, 0.016, 0.026, 0.021, 
0.033, 1.0] 

Und schließlich zu gib das Endergebnis aus: Dort ist nichts besonderes, ich habe die pattern und format verwendet, um sie schöner aussehen zu lassen. Und es ist ziemlich genau nach Ninjageckos Methode, es zu berechnen. Ich musste die 0,00 und 1,00 in die Verteilung auffüllen, da die Berechnung es nicht zeigte. Ziemlich einfache Implementierung nach wir herausfinden, wie die Wahrscheinlichkeit zu tun.

pattern = '{0}: [{1:1.3f}, {2:1.3f})' 
count = 1 # a counter to keep track of the index 

pre_p = distribution[0] 
p = distribution[1] 

# Here we will print it out at the end in the format you said in the question 
for entry in my_list: 
    print(pattern.format(entry[0], pre_p, p)) 
    pre_p += distribution[count] 
    p += distribution[count+1] 
    count = count + 1 

Ausgang:

0: [0.000, 0.017) 
1: [0.017, 0.039) 
2: [0.039, 0.072) 
3: [0.072, 0.105) 
4: [0.105, 0.134) 
5: [0.134, 0.162) 
6: [0.162, 0.197) 
7: [0.197, 0.229) 
8: [0.229, 0.257) 
9: [0.257, 0.284) 
a: [0.284, 0.303) 
b: [0.303, 0.325) 
c: [0.325, 0.354) 
d: [0.354, 0.384) 
e: [0.384, 0.412) 
f: [0.412, 0.447) 
g: [0.447, 0.473) 
h: [0.473, 0.510) 
i: [0.510, 0.539) 
j: [0.539, 0.564) 
k: [0.564, 0.589) 
l: [0.589, 0.626) 
m: [0.626, 0.651) 
n: [0.651, 0.674) 
o: [0.674, 0.700) 
p: [0.700, 0.735) 
q: [0.735, 0.768) 
r: [0.768, 0.799) 
s: [0.799, 0.822) 
t: [0.822, 0.844) 
u: [0.844, 0.882) 
v: [0.882, 0.904) 
w: [0.904, 0.920) 
x: [0.920, 0.946) 
y: [0.946, 0.967) 
z: [0.967, 1.000) 

Volle Quelle ist hier: http://codepad.org/a6YkHhed

1

Erstellen Sie ein Wörterbuch, bei dem die Schlüssel die Zeichen sind und die Werte ein Paar sind, das die untere und obere Grenze definiert.

prev_p = 0 
bounds = {} 
for line in open(a_file): 
    character, p = parse_the_line(line) 
    bounds[character] = (prev_p, p) 
    prev_p = p 
2

Ihre Daten zu Python konvertieren wird als Übung:

>>> corpus = [('0', 0.017), ('1', 0.022), ('2', 0.033), ('3', 0.033), ('4', 0.029), 
...   ('5', 0.028), ('6', 0.035), ('7', 0.032), ('8', 0.028), ('9', 0.027), 
...   ('a', 0.019), ('b', 0.022), ('c', 0.029), ('d', 0.030), ('e', 0.028), 
...   ('f', 0.035), ('g', 0.026), ('h', 0.037), ('i', 0.029), ('j', 0.025), 
...   ('k', 0.025), ('l', 0.037), ('m', 0.025), ('n', 0.023), ('o', 0.026), 
...   ('p', 0.035), ('q', 0.033), ('r', 0.031), ('s', 0.023), ('t', 0.022), 
...   ('u', 0.038), ('v', 0.022), ('w', 0.016), ('x', 0.026), ('y', 0.021), 
...   ('z', 0.033)] 

eine kumulative Summe erstellen:

>>> distribution = [] 
>>> total = 0.0 
>>> for letter, frequency in corpus: 
...  distribution.append(total) 
...  total += frequency 
... 

Eigentlich diese Art von Daten ist das Brot und Butter von der bisect Modul.

>>> import bisect, random 
>>> def random_letter(): 
...  value = random.random() 
...  index = bisect.bisect(distribution, value) - 1 
...  return corpus[index][0] 
... 
>>> [random_letter() for n in range(10)] # doctest: +SKIP 
['d', '6', 'p', 'c', '8', 'f', '7', 'm', 'z', '7'] 
Verwandte Themen