2012-07-18 25 views
2

假設我們有這樣一個數據庫:獲取在MySQL數據庫中重複最多的類似領域

Actions_tbl:

 
-------------------------------------------------------- 
id | Action_name        | user_id| 
-------------------------------------------------------- 
1 | John reads one book      | 1  
2 | reading the book by john    | 1 
3 | Joe is jumping over fire    | 2 
4 | reading another book     | 2 
5 | John reads the book in library   | 1 
6 | Joe read a book      | 2 
7 | read a book        | 3 
8 | jumping with no reason is Ronald's habit| 3 

Users_tbl:

 
----------------------- 
user_id | user_name | 
----------------------- 
1  |  John 
2  |  Joe 
3  |  Ronald 
4  |  Araz 
----------------------- 

想知道我可以選擇最重複的類似行動章程無用的用戶,並用其當前用戶替換我自己的user_name!

閱讀一本書,讀這本書,讀另一本書,在圖書館讀書,讀一本書,讀一本書是最常用的單詞,所以與閱讀本書有關的工作人員重複6次,我的系統應顯示這六個句子的一個隨機與USER_NAME取代阿拉茲

像:阿拉茲讀的書

我的想法是

select replace(a.action_name , b.user_name) from actions_tbl a, user_tble b where a.user_id = b.user_id group_by 

,然後在PHP檢查由一個相似之處一個使用

levenshtein() 

但是這個根本沒有表現!

假設我想爲大分貝和少數不同的表做同樣的事情。 這將摧毀我的服務器!

還有什麼更好的IDEA?

in http://www.artfulsoftware.com/infotree/queries.php#552 the levenshtein()函數是作爲一個MySQL函數實現的,但首先你認爲它有足夠的性能嗎?然後,如何在我的情況下使用它? 也許自聯接面包車解決這個問題,但我不與SQL好!

*類似的行動,是具有行動超過X%的常用詞


**更多信息和注意事項:**

  1. 我m僅限於PHP和MySQL。

  2. 這只是一個例子,在我的實際項目的行動很長的段落。這就是爲什麼表現是一個問題。真實的情況是:用戶輸入其項目的描述了幾個項目,這些數據可能是太相似(用戶必須在同一工作區域),我想,以填補自動(以前的餡料基地)的下一個項目的描述,爲了省時間。

  3. 我將不勝感激,如果你能有任何務實解決方案。我檢查了NLP相關的解決方案,雖然它們很有趣,但我認爲其中很多都不是很準確,並且可以使用PHP實現。

  4. 輸出應該是有意義的,並像所有其他項目一樣成爲一個適當的段落。這就是爲什麼我想從以前的選擇。


感謝您的知識產權的答案,它真的很感激,如果你能在情況

+0

這裏是一個例子:http://stackoverflow.com/questions/4671378/levenshtein-mysql-php – mdo 2012-07-18 09:39:28

+0

檢查mysql中的soundex函數。這可以幫助你imo。 – 2012-07-18 09:44:34

+0

@mdo,謝謝,我之前檢查過,它的一個術語和字段之間的相似性是我想要的所有行之間的相似性 – 2012-07-18 09:49:16

回答

2

你所談論的是一個文本聚類過程提供一些線索。您正在嘗試查找類似的文本片段,並隨意選擇其中一個文本。我不熟悉任何採用這種形式的文本挖掘的數據庫。

對於你所描述的,一個非常基本的文本挖掘技術可能會起作用。用除用戶名外的所有單詞創建一個術語文檔矩陣。然後使用奇異值分解來獲得最大的奇異值和向量(這是相關矩陣的第一主分量)。類似的活動應該沿着這條線聚集。

如果您的詞彙量有限,並且在表格中包含詞彙,您可以通過重疊單詞的比例來衡量兩個操作之間的距離。你有行動中所有單詞的清單嗎?

+0

感謝您的建議,這張表只是一個樣本,其實在現實中,我有一個包含長段的表格,每個段落可以超過10行,表格會有很多這樣的!你認爲它的實用性列出所有的單詞,並做你的話嗎?有什麼樣的PHP? – 2012-07-18 15:46:55

+0

此外,我正在實施某種自動填充,因此係統可以根據用戶以前提供的數據填寫表格。 – 2012-07-18 15:53:46

+0

您的問題比直接通過數據庫解決的問題要複雜得多。你需要一個應用程序。如果您正在使用SAS,則可以查看SAS Text Miner。如果你有表格的列表,並且希望找到最接近每個段落的表格,那麼你可以用一包字母的方法做到這一點。無論如何,你都有一個問題,即關係數據庫不是爲解決問題而設計的(儘管它們可以是解決方案的一部分)。 – 2012-07-18 15:57:57

1

首先,您必須決定是將某個給定輸入與所有現有文本進行比較,還是對所有文本進行兩兩比較。你的問題要求後者,但你勾勒的應用聽起來更像前者。

如果您只比較一個輸入與您的數據庫,然後我希望levenshtein距離計算速度足夠快到中等數據庫大小。除非存儲某種形式的關於文本庫的當前內容的中間數據結構,否則可能沒有辦法更快地完成任務。對每個新輸入重新計算任何東西可能同樣昂貴。

如果你想對每一對進行比較,那麼每個對的levenshtein計算將花費太多時間。你必須設計一些其他的相似概念。我想到的第一件事情,對某種詞的不同形式有一定的適應能力,那就是suffix tree。您可以將所有段落插入到該樹中。如果後綴樹通常存儲單個指針,則可能需要存儲一對索引,一個標識數據庫行,另一個指示該行文本中的位置。在構建樹之後,可以遍歷它以識別常見的子字符串,併爲相應的對增加一些相似度計數器。你將不得不試驗一下來調整這個措施。在增加計數器之前,您可能需要爲公共字符串添加最小長度。長文本即使在語義上不相關的情況下也具有較大的常用單詞的機會,您可能需要以某種方式補償長度。我懷疑有一種規範的方式來做到這一點。

term-document matrix方法suggested by Gordon聽起來很有趣,你也應該可以在PHP中實現它。即使根目錄是相同的,這種方法也會對詞形的變化敏感。另一方面,爲數據庫中存儲的矩陣保留一個合適的矩陣可能更容易,並且在更新主文本表時保持該結構同步。這兩種方法都與levenshtein距離有着根本的區別:他們不關心整體秩序。我相信這對你來說是件好事,因爲他們會考慮這樣的文字:「約翰在湖中游泳後讀了一本書」,更類似於「在湖中游泳後,喬讀了一本書」將。

你的例子表明你不僅要排列相似性,還要決定邊緣的邊界,即。說「這些形成一個羣體」和「那些屬於不同羣體」。這不會有一個乾淨的截斷點,所以你也必須嘗試啓發式算法。除非總是選擇最相似的文本或最相似的文本,否則對於您的應用程序就足夠了。在任何情況下,我都會先專注於相似性計算,然後添加諸如用戶名替換之類的內容。

+0

感謝您的評論,是的,我想比較我的表中的所有行以找到最常見的行,然後選擇其中一個作爲輸出 – 2012-07-26 09:46:10

+0

這裏,一個適當的排名是不需要的(不像http://stackoverflow.com/questions/11609348/advance-query-rank-most-related-fields-in-mysql)我們可以應用像你在那裏提到的相同的東西。檢查所有行(通過左連接)並通過運行一個過程來查找類似的行(如果行類似,則返回true)。問題是如何編寫該過程?我不能讓字典導致單詞不受限制,我無權訪問插入事件(我的應用程序是插件)使用其他應用程序輸入數據 – 2012-07-26 10:41:44

+0

關於選擇,從常見的相似行中隨機選擇就足夠了SELECT * FROM'table' ORDER BY RAND( )LIMIT 0,1;其中表是最常見的類似的行。 [閱讀一本書|讀書|讀另一本書|在圖書館閱讀這本書|讀一本書|在我們的例子中閱讀一本書]。 – 2012-07-26 10:54:52