寒假老板給的任務,讓我重現這個實驗http://www.liuhaihua.cn/archives/15565.html。自己就隨便試了下,用的都是比較經典(lao)的算法和知識,記錄一下。
一、從網頁上爬取POI數據
找了一圈,感覺這個網站比較靠譜:http://www.poi86.com,因為這里只需要POI標簽,不需要其他類似地址啊什么的信息,所以這個網站足夠用了。
爬網站使用的scrapy這個開源庫,核心代碼如下:
1 import re 2 import json 3 4 from scrapy.spider import BaseSpider 5 6 class spider(BaseSpider): 7 name = "poi86" 8 allowed_domains = ["poi86.com"] 9 indexes = range(1,1000) 10 start_urls = [] 11 for i in indexes: 12 url = 'http://www.poi86.com/poi/category/43/%s.html' % i 13 start_urls.append(url); 14 15 def parse(self,response): 16 filename = response.url.split("/")[-1] 17 open(filename,'wb').write(response.body)
以上代碼只做了“下載網頁並保存”的工作,接下來的代碼從每個網頁中提取POI標簽信息。
1 import os 2 d = '/Users/sunshineatnoon/Documents/POI/train/' 3 article_number = [0,344,1143,1943,2572,3137] 4 names = ['finace','hotel','resturant','transport','amusment'] 5 for i in range(1,len(article_number)): 6 begin = article_number[i-1]+1 7 all_shops = [] 8 for k in range(begin,article_number[i]+1): 9 filename = str(k)+'.html'; 10 file_object = open(d+filename) 11 all_text = file_object.read() 12 all_text_split = all_text.split('<table class="table table-bordered table-hover">') 13 names_split = all_text_split[1].split('title="">') 14 for j in range(1,len(names_split)): 15 shop_name_list = names_split[j].split('</a></td>') 16 all_shops.append(shop_name_list[0]) 17 all_shops = list(set(all_shops)) 18 output = open('/Users/sunshineatnoon/Documents/POI/preprocess/'+names[i-1],'w') 19 for item in all_shops: 20 output.write(item+'\n') 21 output.close()
最后的數據量大概是這樣的:
類別 |
頁面數量 |
POI標簽數目 |
金融 |
344 |
9186 |
賓館 |
799 |
37985 |
餐飲 |
800 |
37248 |
交通 |
629 |
22012 |
休閑娛樂 |
565 |
25737 |
總計 |
3137 |
132168 |
二、分詞
下載到的POI標簽信息,都是短文本,這里利用向量空間來表征這些短文本的特征。那么首先要進行分詞,這里使用jieba分詞,該工具有三種分詞模式:精確模式,全模式,搜索引擎模式;這里使用的是精確模式。分詞的核心代碼如下:
1 seg_list = jieba.cut(line,cut_all=False) 2 word_list = " ".join(seg_list) 3 word_list = word_list.split(" ")
分詞完成后,選取詞頻大於等於5的詞作為初步處理得到的字典。
三、 根據信息增益選取特征詞
將POI信息中單詞的信息增益值作為衡量單詞對分類作用的大小,挑選出信息增益top10%(約1000個單詞)的單詞作為POI信息的特征。其中單詞的信息增益計算公式如下:
其中上式中第一項為訓練數據集中原始信息熵,對於所有的單詞是相同的,所以這里只計算上式中后兩項之和,即根據t分類后數據的信息熵,然后根據從小到大的順序選取1000個單詞作為特征詞。
熵值排名前20的單詞如下所示:百貨店,賓館,停車場,支行,酒店,加油站,中國,銀行,網吧,郵政儲蓄,中國農業銀行,KTV,所,會,分理處,網絡,客運站,旅館,財產保險,公寓;可以看出上述大部分單詞都是以上五個類別(金融,交通,休閑娛樂,賓館,餐飲)的典型代表詞。
四、多項式朴素貝葉斯模型
上述特征詞形成了一組“特征”,根據這組特征詞,可以將一個POI信息表示為0-1向量,該向量作為POI信息的向量空間表示,輸入到朴素貝葉斯模型進行分類。后續實驗中利用weka中得朴素貝葉斯模型,所以這里將向量整理為weka輸入格式,如下所示:
@RELATION POI @ATTRIBUTE 1 NUMERIC @ATTRIBUTE 2 NUMERIC …… @ATTRIBUTE 1006 NUMERIC @ATTRIBUTE class {1,2,3,4,5} @DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 ……
其中最后的1表示該樣本屬於第一類,即finance類.
這里借助weka分類工具,訓練多項式朴素貝葉斯分類模型,並通過十折交叉驗證得到模型准確率。結果如下:
模型准確率為88.6%。
參考資料:
【1】http://www.liuhaihua.cn/archives/15565.html
【2】http://www.cnblogs.com/wentingtu/archive/2012/03/24/2416235.html