Bigramme

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
desperation63

EyDu hat geschrieben:
desperation63 hat geschrieben:ich habe jetzt bspw. aus 2 Texten alle Bi und Trigramme rausgefiltert und diese gezählt und sortiert als Dictionary. Kann ich mit diesen beiden Dictionaries das Skalarprodukt berechnen?
Ja, du musst einfach nur die Schnittmenge der Schlüssel bestimmen. Ich nehme mal an, dass du als Schlüssel den Term/das Bigram hast. Nur deren Gewichte musst du beachten.
desperation63 hat geschrieben:Und wie soll ich das Skalarprodukt in python mit zwei verschieden langen vektoren berechnen?
Die sind doch nicht verschieden lang. Du kennst doch alle möglichen Terme.

Erstell dir doch einfach mal zwei Dokumentenvektoren und gehe das von Hand durch.

Schnittmenge:

Code: Alles auswählen

 Schnittmenge = set(vorhandenes_profil_final.keys()) & set(neues_profil_final.keys())
wäre das so richtig mit der Schnittmenge? Wie genau beachte ich die Gewichte?
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

desperation63 hat geschrieben: Des Weiteren entspricht dein Vorschlag genau meiner Idee, die ich im Kopf rumschwirren habe, wie das Programm funktionieren soll.

Wäre wirklich super, wenn du mal einen Ansatz zu deiner Idee geben könntest
Ich kenne mich da nicht so gut aus, habe aber ebenfalls den Eindruck, dass das von EyDu beschriebene Vorgehen einfacher ist. Was ich meinte wird in einer "klassischen" Variante zum Beispiel hier beschrieben, ist m.M.n. aber weniger generell auf verschiedene Dinge anwendbar, als das angesprochene Vektormodell; es dient eben primär der Kategorisierung nach Dokumentensprachen unter Rückgriff auf das Zipf'sche Gesetz, auch wenn man damit thematische Klassifizierungen vornehmen kann. Ich weiß auch nicht, inwiefern dieser Ansatz von 1994 heute noch zeitgemäß ist...
desperation63

nezzcarth hat geschrieben:
desperation63 hat geschrieben: Des Weiteren entspricht dein Vorschlag genau meiner Idee, die ich im Kopf rumschwirren habe, wie das Programm funktionieren soll.

Wäre wirklich super, wenn du mal einen Ansatz zu deiner Idee geben könntest
Ich kenne mich da nicht so gut aus, habe aber ebenfalls den Eindruck, dass das von EyDu beschriebene Vorgehen einfacher ist. Was ich meinte wird in einer "klassischen" Variante zum Beispiel hier beschrieben, ist m.M.n. aber weniger generell auf verschiedene Dinge anwendbar, als das angesprochene Vektormodell; es dient eben primär der Kategorisierung nach Dokumentensprachen unter Rückgriff auf das Zipf'sche Gesetz, auch wenn man damit thematische Klassifizierungen vornehmen kann. Ich weiß auch nicht, inwiefern dieser Ansatz von 1994 heute noch zeitgemäß ist...
Das ist genau der Text den ich auch gelesen habe. Dieses Verfahren meine ich. Hast du eine Idee wie man das umsetzen könnte?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

desperation63 hat geschrieben:wäre das so richtig mit der Schnittmenge? Wie genau beachte ich die Gewichte?
Ja, so bekommst du die Schnittmenge. Die Gewichte kannst du dir nun "beliebig" ausdenken. Die Einfachste Möglichkeit wäre es, wenn du die Länge der Schnittmenge nimmst. Das ignoriert natürlich die Anzahl der Vorkommnisse der Terme.

Alternativ kannst du die Anzahl der Werte aus Dokument 1 und Dokument 2 für den selben Term multiplizieren oder aber deren Differenz bilden. Hier musst du aber vorsichtig sein, denn du musst unbedingt normieren!

Ich würde tf-idf implementieren, das liefert häufig gute Ergebnisse. Am besten probierst du alle Varianten mal durch und schaust welches Verfahren für dich die besten Ergebnisse liefert. Wenn du das Verfahren einmal allgemein geschrieben hast, dann lässt sich ja schnell ein anderes Gewicht ausprobieren.
Das Leben ist wie ein Tennisball.
desperation63

EyDu hat geschrieben:
desperation63 hat geschrieben:wäre das so richtig mit der Schnittmenge? Wie genau beachte ich die Gewichte?
Ja, so bekommst du die Schnittmenge. Die Gewichte kannst du dir nun "beliebig" ausdenken. Die Einfachste Möglichkeit wäre es, wenn du die Länge der Schnittmenge nimmst. Das ignoriert natürlich die Anzahl der Vorkommnisse der Terme.

Alternativ kannst du die Anzahl der Werte aus Dokument 1 und Dokument 2 für den selben Term multiplizieren oder aber deren Differenz bilden. Hier musst du aber vorsichtig sein, denn du musst unbedingt normieren!

Ich würde tf-idf implementieren, das liefert häufig gute Ergebnisse. Am besten probierst du alle Varianten mal durch und schaust welches Verfahren für dich die besten Ergebnisse liefert. Wenn du das Verfahren einmal allgemein geschrieben hast, dann lässt sich ja schnell ein anderes Gewicht ausprobieren.
Das mit den Gewichten verstehe ich noch nicht so ganz. Könntest du mir das einmal genauer erklären?

Wie würde ich jetzt bei bspw. 3 verschiedenen Schnittmengen nur die längste ausgeben lassen? Hab irgendwie ne Blockade im Kopf gerade.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

desperation63 hat geschrieben:Das mit den Gewichten verstehe ich noch nicht so ganz. Könntest du mir das einmal genauer erklären?[/quotte]
Das steht doch alles genau im Wikipediaartikel zum VSM und den dort weiterführenden Links. Lies dich doch einfach mal in das Thema ein anstatt alle 10 Minuten zu fragen. Ich werde dir nicht persönlich erklären was in dutzenden von Artikeln bereits bestens beschrieben ist.
desperation63 hat geschrieben:Wie würde ich jetzt bei bspw. 3 verschiedenen Schnittmengen nur die längste ausgeben lassen? Hab irgendwie ne Blockade im Kopf gerade.
Wenn du es nicht schaffst aus drei Schnittmengen die mit den wenigsten Elementen zu finden, dann solltest du vielleicht noch einmal das Tutorial durcharbeiten. Das ist Grundlagenwissen.
Das Leben ist wie ein Tennisball.
desperation63

Nene, ich habs schon kurz danach direkt hinbekommen. Wie gesagt ich hatte einfach ne Blockade im Kopf. Hab grad ziemlich viel um die Ohren und da kam ich im ersten Moment einfach nicht drauf :K . Trotzdem danke.
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

desperation63 hat geschrieben:
nezzcarth hat geschrieben:
desperation63 hat geschrieben: Des Weiteren entspricht dein Vorschlag genau meiner Idee, die ich im Kopf rumschwirren habe, wie das Programm funktionieren soll.

Wäre wirklich super, wenn du mal einen Ansatz zu deiner Idee geben könntest
Ich kenne mich da nicht so gut aus, habe aber ebenfalls den Eindruck, dass das von EyDu beschriebene Vorgehen einfacher ist. Was ich meinte wird in einer "klassischen" Variante zum Beispiel hier beschrieben, ist m.M.n. aber weniger generell auf verschiedene Dinge anwendbar, als das angesprochene Vektormodell; es dient eben primär der Kategorisierung nach Dokumentensprachen unter Rückgriff auf das Zipf'sche Gesetz, auch wenn man damit thematische Klassifizierungen vornehmen kann. Ich weiß auch nicht, inwiefern dieser Ansatz von 1994 heute noch zeitgemäß ist...
Das ist genau der Text den ich auch gelesen habe. Dieses Verfahren meine ich. Hast du eine Idee wie man das umsetzen könnte?
Ja, meinen Versuch zeige ich aber eher ungern, weil der Code vielleicht nicht so gut ist und ich denke, dass die anderen das viel besser hinbekommen :) Aufbauend auf BlackJacks Code Vorschlägen ist das gut machbar. Der Ansatz, der mir vorschwebt, besteht im Kern aus einer Funktion, die die Elemente in eine Rangfolge bringt, basierend auf der Häufigkeit (gleichhäufige Elemente bekommen dengleichen Rang). Und einer weiteren, die darauf basierend dann einfach die Rangunterschiede aussrechnet. Und dann hast du's ja schon fast :)
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Da sonst keiner will, zeige ich vielleicht doch mal, was ich da zusammengefummelt habe; ich nehme an, dass
es an einigen Stellen etwas umständlich und unflexibel. Und: Was nimmt man am besten als "Strafwert" für
fehlende Indices?

(basierend auf BlackJacks Vorschlägen)

Code: Alles auswählen

#!/usr/bin/python3

import re
from collections import Counter, deque
from itertools import chain, tee, groupby
from operator import itemgetter

WORD_RE = re.compile(r'\w+')

class Text:
    def __init__(self, name, content, n_lower=2, n_upper=5):
        self.name = name
        self.content = content
        self.profile = Counter()
        for n in range(n_lower, n_upper+1):
            self.profile.update(Counter(iter_ngrams_from_text(self.content, n)))

def iter_words(text):
    return (m.group(0) for m in WORD_RE.finditer(text))

def iter_ngrams(word, n):
    ngram = deque('_' * n, n)
    for character in chain(word.upper(), '_' * (n - 1)):
        ngram.append(character)
        yield ''.join(ngram) 

def iter_ngrams_from_text(text, n):
    return chain.from_iterable(map(lambda x:iter_ngrams(x, n), iter_words(text)))

def count_different(iterable, start=1, key=None):
    for i, item in enumerate(groupby(iterable, key=key), start):
        for value in item[1]:
            yield value, i

def out_of_place_index(item, reference, missing=100):
    reference_tmp = {i[0]:j for i, j in count_different(reference, key=itemgetter(1))}
    index = 0
    for element in count_different(item, key=itemgetter(1)):
        key, rank = element[0][0], element[1]
        try:
            index += abs(rank - reference_tmp[key])
        except KeyError:
            index += missing
    return index

def get_best_category(item, categories):
    result = []
    for category in categories:
        result.append((out_of_place_index(item.profile.most_common(), category.profile.most_common()), category.name))
    return min(result)
 
def main():
    text = Text("Deutsch", "Alle Menschen sind frei und gleich an Würde und Rechten geboren Sie sind mit Vernunft und Gewissen begabt und sollen einander im Geist der Brüderlichkeit begegnen")
    categories = [ 
    Text("Englisch", "All human beings are born free and equal in dignity and rights They are endowed with reason and conscience and should act towards one another in a spirit of brotherhood"),
    Text("Dänisch", "Alle mennesker er født frie og lige i værdighed og rettigheder De er udstyret med fornuft og samvittighed, og de bør handle mod hverandre i en broderskabets ånd"),
    Text("Norwegisch", "Alle mennesker er født frie og med samme menneskeverd og menneskerettigheter De er utstyrt med fornuft og samvittighet og bør handle mot hverandre i brorskapets ånd")
    ]
    print(get_best_category(text, categories))
     
if __name__ == '__main__':
    main()
 
Letztendlich hängt es aber davon ab, wie du's in deine Software einbauen willst. Im Prinzip hält man ja verschiedene N-Gramm-Profile, die anhand von Testkorpora gewonnen wurden, für die Kategorie vor und vergleicht dann. So kurze Textausschnitte wie hier sind natürlich sehr unzureichend.
Antworten