![]() |
Matchning av texter, STORT antal
Hej,
Jag har cirka 80 000 texter där det KAN finnas dubletter, inte precis exakt men det skiljer väl sig på något ord/punkt/tecken. Då jag inte har ork eller tid för att gå igenom 1 och 1 så kanske det finns någon smart teknik som kan leta fram ganska stora likheter i texter? Jag har allting sparat i en databas och i textfiler. Någon som vet vilken teknik jag ska använda? |
Om du förutsätter att t.ex det första och det sista ordet är samma för dubbletterna borde du kunna få ner 80 000 olika texter till ett betydligt minde antal där det kan finnas dubbletter.
Om det bara skiljer något tecken bör ju dubbletterna också ha ungefär samma längd, du skulle ju kunna kolla hur många som diffar på mindre än 10-tecken i längd. Du skulle också kunna jämföra filstorlek på textfilerna och kolla vilka som diffar mindre än x-bytes i storlek. Att implementera dessa två borde inte ta lång tid om du behärskar programmering. |
Jag tycker man kan ta texterna och tokenisera de enskilda orden. sen räknar man hur många ord som är lika och hur många ord det finns totalt.
Sen delar man antalet lika ord med totala antalet ord och får då en procentsiffra som kan ge en hyfsad uppfattning hur lika texterna är. Sen är det bara att sortera på de med störst likhet och gå in och kika manuellt hur väl det stämmer. Man kan även göra en ordanalys så man räknar antalet lika tecken i ett enskilt ord för att se om det finns många ord som är snarlika (skiljer 1-2 tecken så kan det vara en felstavning). |
Har du hittat något eller ska jag slänga ihop ett program?
|
om du vill slänga ihop vore det schysst.
försöker göra ngn sak på det formulär som jag sparar data i som kollar om det redan finns men failar. xD |
http://www.speedyshare.com/jReHE/DublettFinder.rar
Går efter första/sista ord samt storlek. Inte den mest pålitliga men ska nog ge en bra fingervisning. Skulle kunna använda LINQ's Except men för mycket data skulle laddas in i minnet, detta verkar fungera hyffsat. Säg gärna till hur det fungerade mot större textfiler. |
Det funkade bra tyckte jag men nu när jag tänkte efter vill jag ha det som serverkod. jag har gjort ett litet exempel här.
Men problemet är att jag tar hela texter och kopierar in det och då kollar den ju denna kod om hela texten är lika med någon annan. Men jag vill ha detta som Conny beskrev: kolla alla ord som stämmer genom alla ord som finns i strängen man söker med. Hur kan jag trimma denna så det passar? PHP-kod:
|
Det finns ett flertal olika färdiga funktioner i PHP för att jämföra strängar. Hur bra de fungerar beror helt på vilka behov man har men de kan ju enkelt kombineras med diverse egna kontroller.
|
Här hittade jag en funktion som splittar upp en textsträng i sql så man får varje ord som en egen rad (MS SQL-Server):
Kod:
Create function dbo.SplitString Kod:
select * Kod:
select * |
Här hittade jag en ännu elegantare lösning:
Kod:
CREATE FUNCTION [dbo].[split]( För att testa: Kod:
select * From split('Hello**John**Smith','**') |
Efter lite testande så kom jag fram till två lämpliga funtioner och lite testdata:
Kod:
CREATE FUNCTION [dbo].[split]( Kod:
CREATE FUNCTION [dbo].[similarity] Lite testkörning: Kod:
Declare @text1 nVarchar(Max) = 'Hello John Smith the first' |
Helt OT; men satan vad sjuk SQL-kod du skriver Conny. Är du en artificiell intelligens från framtiden? :D
|
SplitString() och Split()-funktionerna hittade jag på någon internetsida men funktionen similarity() har jag knackat ihop, jag har bara testat med några få exempel men den ser ut att funka.
"Articifiell intelligens från framtiden" var ett nytt epitet, He, he :-) |
Det va väldigt va svårt ni gör de för er själva.
Använd levenshtein-algoritmen för att räkna ut ett normaliserad avstånd mellan två texter. Är värdet mindre än te.x 0.1: lika, annars olika. 7 rader kod i te.x Python eller Ruby. |
Citat:
|
Citat:
|
Citat:
|
|
Hur många ord är varje text på? Levenshtein och smiliar_text drar ruskigt mycket resurser och det kommer ta otroligt lång tid om det är mer än 20 ord per text. Däremot borde MySQL klara av det med fulltext-index.
Utan att ha testat och bara genom att spekulera tror jag att du hade kunnat få det gjort rätt snabbt genom att loopa igenom dina texter, fråga databasen efter texten, och där id != iterationsID. Får du ett svar som har någon relevans över säg, 50% (justera efter behov), så kan du vara ganska säker på att den är snarlik eller en dublett. Markera upp den tillsammans med iterationsID och kör en manuell koll efteråt. Detta är nog den mest eleganta och snabbaste lösningen. Funkar inte den så finns det en del vettiga implementationer av Levenshtein för MySQL ute på nätet som är snabbare än PHP's implementation tillsammans med fulltext-index. http://dev.mysql.com/doc/refman/5.1/...-language.html |
Alla tider är GMT +2. Klockan är nu 14:36. |
Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson