FAQ |
Kalender |
2013-05-11, 03:37 | #11 | ||
|
|||
Klarade millennium-buggen
|
Efter lite testande så kom jag fram till två lämpliga funtioner och lite testdata:
Kod:
CREATE FUNCTION [dbo].[split]( @delimited NVARCHAR(MAX), @delimiter NVARCHAR(100) ) RETURNS @t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX)) AS BEGIN DECLARE @xml XML SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>' INSERT INTO @t(val) SELECT r.value('.','varchar(MAX)') as item FROM @xml.nodes('/t') as records(r) RETURN END Kod:
CREATE FUNCTION [dbo].[similarity] ( @text1 NVARCHAR(MAX), @text2 NVARCHAR(MAX) ) RETURNS real AS BEGIN DECLARE @similarity real DECLARE @similar real DECLARE @total real select @total=COUNT(*) from Split(@text2,' ') select @similar=COUNT(*) from Split(@text1,' ') WHERE val In (select val from Split(@text2,' ')) set @similarity = @similar / @total RETURN @similarity END Lite testkörning: Kod:
Declare @text1 nVarchar(Max) = 'Hello John Smith the first' Declare @text2 nVarchar(Max) = 'Hello John Smith the second'; Declare @text3 nVarchar(Max) = 'Hello John Smith the second kalle olle '; select dbo.similarity(@text1,@text2) -- 0,8 -> 80% select dbo.similarity(@text1,@text3) -- 0,5 -> 50% |
||
Svara med citat |
2013-05-11, 15:58 | #12 | |||
|
||||
Medlem
|
Helt OT; men satan vad sjuk SQL-kod du skriver Conny. Är du en artificiell intelligens från framtiden?
|
|||
Svara med citat |
2013-05-11, 16:24 | #13 | ||
|
|||
Klarade millennium-buggen
|
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 :-) Senast redigerad av Conny Westh den 2013-05-11 klockan 16:39 |
||
Svara med citat |
2013-05-11, 16:26 | #14 | ||
|
|||
Medlem
|
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. |
||
Svara med citat |
2013-05-11, 19:32 | #15 | ||
|
|||
Supermoderator
|
Finns i PHP också, liksom flera andra metoder.
__________________
Full-stack developer, free for smaller assignments |
||
Svara med citat |
2013-05-11, 19:48 | #16 | ||
|
|||
Medlem
|
|||
Svara med citat |
2013-05-11, 23:35 | #17 | ||
|
|||
Supermoderator
|
Ingenting annat än just det Eftersom han hade exempelkod i php ovan så tyckte jag det var värt att nämna
__________________
Full-stack developer, free for smaller assignments |
||
Svara med citat |
2013-05-13, 13:06 | #18 | |||
|
||||
Mycket flitig postare
|
||||
Svara med citat |
2013-05-14, 12:01 | #19 | |||
|
||||
Administratör
|
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
__________________
@Zn4rK - Börja blogga - Paintball i Göteborg Det jag skriver är mina personliga åsikter och återspeglar inte vad WN eller andra företag jag representerar tycker. |
|||
Svara med citat |
Svara |
|
|