[轉貼].NET(C#)平台調用:使用EnumWindows和GetWindowText列舉窗口

2013年10月19日 星期六

[轉貼].NET(C#)平台調用:使用EnumWindows和GetWindowText列舉窗口

對於API的EnumWindows,第一個參數WNDENUMPROC是一個函數指針類型(EnumWindowsProc),HWND代表窗體的句柄。第二個LPARAM代表EnumWindows的第二個參數,即傳入回調函數的用戶自定義對象(參數)。

EnumWindows只能獲取一個窗體的句柄,因此用GetWindowText返回窗口的標題。

代碼:
//函數指針類型
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

[DllImport("user32.dll")]
static extern int EnumWindows(EnumWindowsProc hWnd, IntPtr lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpText, int nCount);

//回調函數
static bool PrintWindow(IntPtr hWnd, IntPtr lParam)
{
    //分配空間
    var sb = new StringBuilder(50);
    GetWindowText(hWnd, sb, sb.Capacity);
    //注意某些窗口沒有標題
    if (sb.ToString() != String.Empty)
        Console.WriteLine(sb.ToString());
    //回調函數有返回值
    return true;
}

static void Main()
{
    EnumWindows(PrintWindow, IntPtr.Zero);
}

[轉貼] TF-IDF (TF-IDF 最簡明的說明)

2013年10月2日 星期三

[轉貼] http://blog.xuite.net/jesselue/4664/20673385-IR(%E5%85%AD)--+TF-IDF%E3%80%81%E4%BA%8C%E4%B9%8B%E4%B8%80

根據維基百科對TF-IDF的解說:

TF-IDF(term frequency–inverse document frequency)是一種用於資訊檢索與資訊探勘的常用加權技術。TF-IDF是一種統計方法,用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。

先解釋一下以上這一段文字:

TF(term Frequency):

大家都常用搜尋引擎google、yahoo...等等唄!到底搜尋引擎是如何搜尋某一串字的呢?

在google中鍵入文字一串字,例如:"維基百科",會出現一堆包含"維基百科"四個字的網頁,試著想像一下,由網路上這麼多網頁中,如何排列出那些網頁最能代表"維基百科"這四個字?最直覺的作法,不外乎先把全世界所有的網頁掃瞄一次,然後一一計算"維基百科"這四個字在每一個網頁出現的次數,當然,出現愈多次,表示該網頁愈和"維基百科"這四個字愈有關係。接著,以某一個網頁來看,比較不同的字串,例如,"維基百科"這四個字在這個網頁出現100次,而另一字串"百度百科"在該網頁只出現10次,那麼是否表示,"維基百科"和這個網頁的關係愈深,對於這個網頁來說,這個字串"維基百科"就愈重要。也就是如維基百科對TF-IDF所說,

字詞的重要性隨著它在文件中出現的次數成正比增加。

如果,我們將全世界所有網頁都做個記錄,什麼記錄?就是該網頁最重要的十個字串的記錄,例如:

(公式一)

網頁A:"維基百科"出現70次,"百度百科"出現10次。

網頁B:"百度百科"出現30次,"維基百科"出現20次。

....

如此一來,我們可以依照某一個網頁中字串的重要性來列出網頁的排序,當我們鍵入"維基百科"時,網頁A自然會排在網頁B前面,當我們鍵入"百度百科"時,網頁B自然會排在網頁A前面,如此,就是一種搜尋方法,所以,

某一個字串在網頁出現的次數這件事情是很重要,"字串在網頁出現的次數"就是TF(term frequency)。所謂的"TF-IDF是一種統計方法"云云,想簡單一點,就是"計算出現的次數"唄,"統計方法"四字不過是"計算出現的次數"的一種抽象說法。

OK,那就"計算出現的次數"唄!把一個網頁中的字串統統拿來算一下"每個字串的出現次數",那個數字大就表示這個字串對這個網頁的重要性高!讀數學的人愛表現,想讓人看不懂,所以呢,就把這"每個字串的出現次數"除以"所有字串的出現次數的總和"稱為TF(term frequency),其實,這和"計算出現的次數"沒啥差異,所以:

(公式二)

TF(term frequency) = "每個字串的出現次數"除以"所有字串的出現次數的總和"。字串即是term。

tf(i,j) = n(i,j) / ( n(1,j)+n(2,j) + ... n(k,j) )

上式就是第i個字串t在j網頁的TF,n(i,j)就是i字串的出現次數,( n(1,j)+n(2,j) + ... n(k,j) )就是"所有字串的出現次數的總和"。由上式,也表示j網頁共有k個字串。

TF值愈大表示該Term愈重要。

以上面"維基百科"、"百度百科"為例:

(公式三)

網頁A:

"維基百科" TF = 70 / (70+30) = 0.7

"百度百科" TF = 30 / (70+30) = 0.3

網頁B:

"維基百科" TF = 20 / (30+20) = 0.4

"百度百科" TF = 30 / (30+20) = 0.6

所以,"維基百科"對網頁A比較重要,"百度百科"對網頁B比較重要,根據(公式二)的計算,得出0.7、0.3、0.4、0.6四個數字,和70、30、20、30四個數字比較一下,會發現0.7、0.3、0.4、0.6四個數字的表示方法比較好,因為,由此可以看出,"維基百科"對網頁A的TF是0.7居冠代表"維基百科"對網頁A的重要性最高,其次是"百度百科"對網頁B的TF是0.6。

(舉例一)

因此,用0.7、0.3、0.4、0.6四個數字的方式計算時,搜尋"維基百科"時會列出:

網頁A

網頁B

搜尋"百度百科"時:

網頁B

網頁A

如果用70、30、20、30四個數字的方式計算時,則搜尋"維基百科"時會列出:

網頁A

網頁B

搜尋"百度百科"時,因為,"百度百科"在網頁A出現30次,"百度百科"在網頁B也出現30次,就不知道該如何是好了。

因此, "每個字串的出現次數"除以"所有字串的出現次數的總和"的作法,除了"讀數學的人愛表現,想讓人看不懂"之外,事實上是表示出一串字在一個網頁中與其他字串的相對重要性,由以上(舉例一)就可以可出, "每個字串的出現次數"除以"所有字串的出現次數的總和"的作法可以讓"不同字串"在"不同文件"出現的比較更精準。"每個字串的出現次數"除以"所有字串的出現次數的總和"的作法一般稱為normalization(正規化)。

IDF(inverse document frequency):

從另一個角度,如果搜尋一串字,所有網頁都有這串字,而且這串字在每個網頁都出現很多次,是不是表示這個字串沒什麼重要性?舉個例子,用google搜尋a book這個英文字,照理第一個網頁,應該是某個含有a英文字英文網頁,因為a必定比book更易出現,實則不然,因為,每個英文網頁大概都有a這個字,如此,反而讓a這字沒啥重要性了。IDF的表示,是以某一字串出現在愈多網頁愈不重要,例如,有100個網頁:

(公式四)

a出現在所有100個網頁中,IDF是100,則其重要性一定最差。

book出現在10個網頁中,IDF是10,則其重要性比a好。

另外一個表示法,

(公式五) IDF = 所有的網頁數/ 字串出現的網頁數

a出現在所有100個網頁中,IDF是100/100 = 1,則其重要性一定最差。

book出現在10個網頁中,IDF是100/10 = 10,則book的重要性比a大。

因此,在搜尋"a book"這個字串時,應以"book"為主,因為,"book"的IDF值較大。

當然,"讀數學的人"不會放棄表現機會,所以,IDF就成了:

(公式六)

idf = LOG ( 所有的網頁數/ 字串出現的網頁數)

idf(i) =LOG( | D | / | { d: d 中有字串 t(i)} | )

以上| D | 表示所有的網頁數, | { d: d 中有字串 t(i)} | 表示 字串出現的網頁數。

用LOG的好處是將除法換成減法,因而:

idf(i) =LOG( | D | ) - LOG( | { d: d 中有字串 t(i)} | )

TF-IDF(term frequency, inverse document frequency):

tfidf(i,j) = tf(i,j) * idf (i)

這個公式的解讀有些意思,可以唸成,字串ti在網頁j的tfidf是 tf(i,j) * idf (i)。

以上就是TF-IDF最基本的解說。