# Ähnlichkeitssuche



## Mork (10. Mrz 2008)

Hallo Zusammen,

ich bin auf der Suche nach Technologien und Frameworks (Java), die mir bei der Ähnlichkeitssuche behilflich sind. Angenommen ich habe 10 Texte und will wissen, welche der 10 Texte in einem gewissen Radius ähnlich zu Text 11 ähnlich sind. 

Super wäre es, wenn sowas mit Lucene (in welcher Form auch immer) zu bewerkstelligen wäre, denn diesen Volltextindex habe ich schon in meinen Anwendung.

Vielen Dank schonmal für eure Hilfe
Ciao


----------



## MiDniGG (10. Mrz 2008)

Hm. Hab sowas ähnliches vor einiger Zeit mal gemacht vielleicht hilft es ja....

Also is halt ne Suche nach Wörtern aba vllt. bringts was :-D

_Hinweis: War in meiner Anfangszeit. Sorry für den "schlechten" Code _


```
public class Suche extends JFrame implements ActionListener, Runnable
{
	private static final long serialVersionUID = 1L;
	
	JButton btSearch = new JButton("Suchen");
	JButton btStop = new JButton("Stop");
	JButton btReset = new JButton("Reset");
	JButton btExit = new JButton("Beenden");
	JButton btInput = new JButton("Text Laden");
	JButton btNext = new JButton("Weiter");
	
	//private static JSlider slide = null;
	
	JTextArea taText = new JTextArea(3, 60);
	
	JTextField tfSearch = new JTextField(30);
	
	JFileChooser mFile = new JFileChooser();
	
	JLabel lbAusgabe = new JLabel("Bitte Suchwort(e) eingeben.");
	JLabel lbAusgabe1 = new JLabel("");
	JLabel lbHallo = new JLabel("Willkommen!");
	
	JPanel master = new JPanel();
	JPanel zero = new JPanel();
	JPanel one = new JPanel();
	JPanel two = new JPanel();
	JPanel three = new JPanel();
	JPanel four = new JPanel();
	JPanel five = new JPanel();
	JPanel six = new JPanel();
	
	Thread thread = null;

	int mAnzahl = 0;
	int i = 0;
	int mNeu = 0;
	int mEnde = 0;
	int mEnd;
	
	public Suche()
	{
		super("Suche");
		
		Font type = new Font("monospaced", Font.BOLD, 14);
		Font type1 = new Font("serif", Font.BOLD, 14);
		Font type2 = new Font("Arial", Font.BOLD, 25);
		Font type3 = new Font("Arial", Font.BOLD, 16);
		
		//slide = new JSlider(5, 25);
		
		btReset.setFont(type);
		btInput.setFont(type);
		btStop.setFont(type);
		btExit.setFont(type);
		btNext.setFont(type);
		btSearch.setFont(type);
		tfSearch.setFont(type3);
		taText.setFont(type1);
		lbAusgabe.setFont(type1);
		lbAusgabe1.setFont(type1);
		lbHallo.setFont(type2);
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		master.setLayout(new GridLayout(7, 1));
		
		zero.add(lbHallo);
		one.add(tfSearch);
		one.add(btSearch);
		one.add(btStop);
		two.add(taText);
		three.add(lbAusgabe);
		four.add(btNext);
		five.add(btInput);
		five.add(btReset);
		six.add(btExit);
		
		master.add(zero);
		master.add(one);
		master.add(new JScrollPane(two));
		master.add(three);
		master.add(four);
		master.add(five);
		master.add(six);
		
		setContentPane(master);
		
		btSearch.addActionListener(this);
		btExit.addActionListener(this);
		btReset.addActionListener(this);
		btNext.addActionListener(this);
		btInput.addActionListener(this);
		tfSearch.addActionListener(this);
		btStop.addActionListener(this);
		btStop.setVisible(false);
		mFile.addActionListener(this);
		taText.setEditable(false);
		btNext.setVisible(false);
	}

	public static void main(String[] args)
	{
		Suche suchen = new Suche();
		suchen.setBounds(200, 200, 800,600);
		suchen.setVisible(true);
	}
	
	void close()
	{
		int mEnde = JOptionPane.showConfirmDialog(this, "Wollen Sie wirklich beenden?", "Beenden?", JOptionPane.YES_NO_OPTION);
		if (mEnde == JOptionPane.YES_OPTION)
		{
			System.exit(0);
		}
		else
		{
			JOptionPane.showMessageDialog(this, "Das ist aber schön!!!", "Juchu", JOptionPane.OK_OPTION);
		}
	}
	
	void pause(int t)
	{
		try
		{
			Thread.sleep(t);
		}
		catch(InterruptedException e)
		{
			e.getStackTrace();
		}
	}
	
	public void search()
	{
		thread = new Thread(this);
		thread.start();
	}
	
	public void run()
	{
		String mSearch1 = new String(tfSearch.getText());
		String mSearch = tfSearch.getText().toUpperCase();
		String mSearch2 = taText.getText().toUpperCase();

		if (mSearch.equals(""))
		{
			lbAusgabe.setText("Bitte geben Sie ein Suchwort ein.");
			tfSearch.requestFocus();
		}
		else
		{
			if (taText.getText().equals(""))
			{
				lbAusgabe.setText("Zuerst einen Text laden");
			}
			else
			{
				if (mSearch.contains(" "))
				{
					lbAusgabe.setText("Bitte nur ein Suchwort eingeben");
				}
				else
				{					
					tfSearch.setEditable(false);
					btStop.setVisible(true);
					btSearch.setVisible(false);
					
			/*		for (int i = 0; i < 1; i++)
					{
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								lbAusgabe.setText("Suche");
							}
						});
						pause(500);
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								lbAusgabe.setText("Suche.");
							}
						});
						pause(500);
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								lbAusgabe.setText("Suche..");
							}
						});
						pause(500);
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								lbAusgabe.setText("Suche...");
							}
						});
						pause(500);
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								lbAusgabe.setText("Suche..");
							}
						});
						pause(500);
						SwingUtilities.invokeLater(new Runnable()
						{
							public void run()
							{
								lbAusgabe.setText("Suche.");
							}
						});
						pause(500);
					} */
					
					for (int i = 0; i != -1;)
					{
						i = mSearch2.indexOf(mSearch, i);
						if (i != -1)
						{
							i++;
							mAnzahl++;
						}
					}

					if(mAnzahl == 1)
					{
						lbAusgabe.setText("Der Suchbegriff \"" + mSearch1 + "\" wurde " + mAnzahl + " mal gefunden.");
					}
					else if (mAnzahl > 1)
					{
						lbAusgabe.setText("Der Suchbegriff \"" + mSearch1 + "\" wurde " + mAnzahl + " mal gefunden.");
					}
					else if (mAnzahl == 0)
					{
						lbAusgabe.setText("Der Suchbegriff \"" + mSearch1 + "\" wurde leider nicht gefunden.");
					}

					btStop.setVisible(false);
					btSearch.setVisible(true);
					tfSearch.setEditable(true);
					
					int mSearch3 = mSearch2.indexOf(mSearch);
					taText.select(mSearch3, mSearch3 + mSearch.length());
					
					taText.requestFocus();
					
					btNext.setVisible(true);
					
					mEnd = taText.getSelectionEnd();
					
					mAnzahl = 0;
				}
			}
		}
	}
	
	public void stop()
	{
		btStop.setVisible(false);
		btSearch.setVisible(true);
		tfSearch.requestFocus();
		lbAusgabe.setText("Suche Abgebrochen");
		tfSearch.setEditable(true);
		
		thread.stop();
	}
	
//	*************************************************************
//	*  mSearch	=	Text aus Textfeld Search GROSS		string	*
//	*  mSearch1	=	Text aus Textfeld Search			string	*
//	*  mSearch2	=	Text aus Textarea Text GROSS		string	*
//	*************************************************************
	
	//indexOf(...) = startpunkt (erster Buchstabe)
	//indexOf(...,...) = startpunkt, endpunkt (Nach letztem buchstaben)
	
	public void next()
	{
		String mSearch = tfSearch.getText().toUpperCase();
		String mSearch2 = taText.getText().toUpperCase();
		mEnd = mSearch2.indexOf(mSearch, mEnd);
		
		taText.select(mEnd, mEnd + mSearch.length());
		
		mEnd++;
		
		taText.requestFocus();
	}
	
	void load()
	{
		mFile.setCurrentDirectory(new File("Z:\\"));
		mFile.showOpenDialog(new JFrame());
		
		try
		{
			FileReader file = new FileReader(mFile.getSelectedFile());
			try
			{
				try
				{
					BufferedReader buffy = new BufferedReader(file);
					try
					{
						taText.setText("");
						boolean eof = false;
						while (!eof)
						{
							String line = buffy.readLine();
							if(line == null)
							{
								eof = true;
							}
							else
							{
								String mSave = new String();
								mSave = mSave + line + "\n";
								taText.setText(taText.getText() + " " + mSave);
							}
						}
					}
					catch(EOFException eof)
					{
						buffy.close();
					}
				}
				catch (NullPointerException npe)
				{
					System.out.println("Nullpointer");
				}
			}
			catch (IOException e)
			{
				System.out.println("IO Error: " + e.getMessage());
			}
		}
		catch (FileNotFoundException e)
		{
			System.out.println("File not found " + e.getMessage());
		}
	}
	
	public void actionPerformed(ActionEvent evt)
	{
		Object src = evt.getSource();
		
		if(src == btSearch)
		{
			search();
		}
		else if(src == btExit)
		{
			close();
		}
		else if(src == tfSearch)
		{
			btSearch.doClick();
		}
		else if(src == btReset)
		{
			tfSearch.setText("");
			tfSearch.requestFocus();
			lbAusgabe.setText("Bitte Suchwort(e) eingeben.");
			tfSearch.setEditable(true);
			lbAusgabe1.setText("");
			btNext.setVisible(false);
		}
		else if(src == btStop)
		{
			stop();
		}
		else if (src == btInput)
		{
			load();
		}
		else if (src == btNext)
		{
			next();
		}
	}
}
```


----------



## FenchelT (10. Mrz 2008)

Mork hat gesagt.:
			
		

> Hallo Zusammen,
> 
> ich bin auf der Suche nach Technologien und Frameworks (Java), die mir bei der Ähnlichkeitssuche behilflich sind. Angenommen ich habe 10 Texte und will wissen, welche der 10 Texte in einem gewissen Radius ähnlich zu Text 11 ähnlich sind.
> 
> ...



Hallo Mork vom Ork,

evtl findest Du ja hier etwas, was Dich weiterbringt?!
http://de.wikipedia.org/wiki/Kategorie:Phonetik

Ich habe irgendwann mal den Koelner Phonetik Algo benutztum gleichklingende deutsche Woerter zu finden.
Hat soweit auch ganz gut funktioniert nur denke ich dass dies bei ganzen Texten nicht so der bringer ist  :autsch: 

Wie gesagt, guck Dir mal den Link an, evtl findest DU da etwas brauchbares.


Gruesse


----------



## Tobias (10. Mrz 2008)

Term-Vectors könnten sein, was du suchst. Die werden seit 1.4 unterstützt.

Ansonsten mußt du "ähnlich" näher definieren.

mpG
Tobias

P.S.: Siehe auch "Lucene in Action" und http://de.wikipedia.org/wiki/Vektorraum-Retrieval


----------



## Mork (10. Mrz 2008)

Hallo,

also das Vector Space Model ist mir ein Begriff, wird ja auch von Lucene verwendet um Suchtreffer zu gewichten. Nur die Frage ob das eben auch für ganze Texte skaliert. Suchanfragen bestehen ja meist aus weit weniger Informationen.

Was "ähnlich" angeht, simples Beispiel. Ich habe 1000 Heise Artikel in einer DB und 3 Heise-Artikel "in der Hand". Nun will ich aus den 1000 Artikeln alle haben, die von menschlichem Ermessen her ähnlich sind. Beispiel: die drei die ich in der Hand habe, drehen sich um DSL, Java und Open Source. Nun möchte ich aus den 1000 Artikel eine gewissen Anzahl habe, die dem Inhalt der 3 genannten semantisch nahe kommen.


----------



## Tobias (10. Mrz 2008)

Mh, ich kann leider nichts dazu sagen, wie gut das ganze skaliert, weil ich es selbst noch nicht benutzt habe. Aber dazu müßte sich eigentlich im Netz was finden lassen.

mpG
Tobias


----------

