Laden...

bayessche Analyse

Erstellt von edsplash vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.908 Views
edsplash Themenstarter:in
390 Beiträge seit 2008
vor 15 Jahren
bayessche Analyse

Beschreibung:

Ich habe mir kurz zwei Klassen geschrieben, mit denen ich eine einfache bayessche Analyse durchführen kann. Grundsätzlich habe benutze ich die Klassen BayesChance um eine Art White/Blacklist zu erstellen. In diese Listen kann man ganze Zeichenfolgen hinzufügen. Weiter werden die beiden Listen zur Auswertung neuer Zeichenfolgen benutzt.


/// <summary>
	/// Stellt eine Sammlung von Wörtern und Daten dar, aufgrund welcher die Wahrscheinlichkeit für ein Vorhandensein errechnet wird
	/// </summary>
	class BayesChance {
		/// <summary>
		/// Enthält die totale Anzahl Vorkommnisse der Wörter
		/// </summary>
		private Dictionary<string, int> MetaWords;

		/// <summary>
		/// Anzahl der "Datensätze" die hinzugefügt wurden
		/// </summary>
		private int _dataCount;

		/// <summary>
		/// Gibt die Wahrscheinlichkeit zurück, dass das Wort dieser Liste zugeordnet werden kann P(Wort kommt vor|Spam)
		/// </summary>
		/// <param name="word">Das zu prüfende Wort</param>
		/// <returns>Prozentwert</returns>
		public double getChance(string word) {
			try {
				//gibt das Verhältnis der Vorkomnisse von word zur Anzahl Datensätze in Prozent zurück
				return MetaWords[word] * 100 / _dataCount;
			}
			catch (KeyNotFoundException) {
				//Wenn Wort nicht in Liste, Wahrscheinlichkeit 50%
				return 0.5;
			}
		}

		/// <summary>
		/// Konstruktor
		/// </summary>
		public BayesChance() {
			MetaWords = new Dictionary<string, int>();
			_dataCount = 0;
		}

		/// <summary>
		/// Fügt ein Element zur Liste hinzu oder vergrössert die Anzahl der Vorkommnisse dieses Wortes
		/// </summary>
		public string MetaWord {
			private set {
				try {
					//Anzahl erhöhen
					MetaWords[value]++;
				}
				catch (KeyNotFoundException) {
					MetaWords.Add(value, 1);
				}
			}
			get {
				throw new AccessViolationException();
			}
		}

		/// <summary>
		/// Fügt eine neue Zeichenfolge der Liste hinzu
		/// </summary>
		/// <param name="data"></param>
		public void AddData(string data) {
			_dataCount++;

			string[] words = data.Split(new string[]{" "}, StringSplitOptions.None);

			foreach (string word in words) {
				MetaWord = word;
			}
		}
	}

	/// <summary>
	/// Berechnet die Wahrscheinlichkeit der Analyse
	/// </summary>
	class BayesCalc {
		private BayesChance _whitelist;
		private BayesChance _blacklist;

		/// <summary>
		/// Konstruktor
		/// </summary>
		/// <param name="whitelist">Objekt mit positiven Inhalten</param>
		/// <param name="blacklist">Objekt mit negativen Inhalten</param>
		public BayesCalc(BayesChance whitelist, BayesChance blacklist) {
			_whitelist = whitelist;
			_blacklist = blacklist;
		}

		/// <summary>
		/// Berechnet nach dem Satz von Bayes die Wahrscheinlichkeit, dass ein Wort der Whitelist zuzuordnen ist
		/// </summary>
		/// <seealso cref="http://de.wikipedia.org/wiki/Bayestheorem"/>
		/// <seealso cref="http://de.wikipedia.org/wiki/Bayesscher_Filter"/>
		/// <param name="word">Wort</param>
		/// <returns>Wahrscheinlichkeit in Prozent</returns>
		private double CalculateChance(string word) {
			return (_whitelist.getChance(word)/*P(Wort kommt vor|Spam)*/ * 0.5/*P(Spam)*/)/(_whitelist.getChance(word) * 0.5 + _blacklist.getChance(word) * 0.5)/*P(Wort kommt vor)*/;
		}

		/// <summary>
		/// Berechnet die Wahrscheinlichkeit, dass eine Zeichenfolge der Whitelist zugeordnet werden kann
		/// </summary>
		/// <param name="data">Zu prüfende Zeichenfolge</param>
		/// <returns>Gesamte Wahrscheinlichkeit</returns>
		public double Analyse(string data) {
			string[] words = data.Split(new string[]{" "},StringSplitOptions.None);
			double percentage=0;

			foreach (string word in words) {
				percentage += CalculateChance(word);
			}

			//Gibt die Gesamtwahrscheinlichkeit zurück!
			return percentage / words.Length;
		}
	}

Schlagwörter: Satz von Bayes, bayessche Analyse, Bayesscher Filter, Bayessche Filter

Wenn man nun einen Text auf Unhöflichkeiten untersuchen will, fügt man der Whitelist Texte hinzu, die keine Fluchwörter enthalten und der Blacklist solche, die eben Fluchwörter enthalten (je mehr Beispiele man übergibt, desto genauer wird es). Nun kann man einen neuen Text darauf analysieren, ob er wohl zu der Whitelist gehören würde.

Hier noch ein kleines Beispiel:


static void Main(string[] args) {
			BayesChance korrekt = new BayesChance();
			BayesChance falsch = new BayesChance();	

			korrekt.AddData("Ein Text der absolut höflich ist!");
			korrekt.AddData("Ein weiterer Text der keine Fluchwörter enthält.");

			falsch.AddData("Ein Text der sehr unhöflich ist!");
			falsch.AddData("Ein Text der Scheisse ist und nur verdammte Fluchwörter enthält.");

			BayesCalc calc = new BayesCalc(korrekt, falsch);

			double value = calc.Analyse("das ist doch verdammte Scheisse!");

			Console.WriteLine("Die Wahrscheinlichkeit beträgt {0}, dass der Text auf die Whitelist gehört", value.ToString("P"));
			Console.ReadLine();
		}

Der Grund dafür, das die Analyse so knapp ausfällt liegt darin, dass einige Wörter des neuen Textes noch nicht auf der White- oder Blacklist sind und darum neutral bewertet werden. Allerdings ist es so, dass man die Whitelist am besten möglichst leer behält und nur die schlechten Inhalte auf die Blacklist setzt. Das bewirkt dann, dass alle normalen Wörter als neutral bewertet werden.

P.S. Ich bin froh um Feedback aller Art!

Für Interessierte:
http://de.wikipedia.org/wiki/Bayestheorem
http://de.wikipedia.org/wiki/Bayesscher_Filter

using Skill