背景介紹
由于項(xiàng)目需要,需要對(duì)旅游游記文本進(jìn)行聚類,為打標(biāo)簽做指導(dǎo),所以調(diào)研了主流的短文本聚類方法,文本聚類主要還是分成兩個(gè)方面。
1. 提取文本特征
在《數(shù)學(xué)之美》前幾章中,詳細(xì)講了為何要將文本這個(gè)自然語言領(lǐng)域的事物,轉(zhuǎn)換成數(shù)學(xué)領(lǐng)域能處理的向量、矩陣。為了分析一段文本,我們需要首先得到這段文本的表示向量,這個(gè)向量就可以作為文本的特征輸入決策器中進(jìn)行判決。
2. 聚類算法選擇
這里的聚類算法就是上面說的決策器。聚類算法主要分成兩大類,一類是基于距離的迭代算法,比如k-means,還有一類是基于密度的流式聚類算法,比如DBSCAN。他們各有優(yōu)劣,通常由于我們并不清楚聚類的簇?cái)?shù)量,并且由于海量文本迭代的效率比較低,真實(shí)應(yīng)用場(chǎng)景中,我們?cè)诰垲愃惴ǖ倪x擇上,更加傾向選DBSCAN這類的算法。
本文做了幾組對(duì)照實(shí)驗(yàn),分別使用tf-idf或word2vec作為文本的特征,采用k-means或者DBSCAN進(jìn)行聚類分析。實(shí)驗(yàn)流程如下:
實(shí)驗(yàn)流程
1. 中文文本預(yù)處理
將清洗過的數(shù)據(jù)進(jìn)行分詞、去停用詞。其中分詞的時(shí)候,載入預(yù)先設(shè)置好的自定義詞典,提高分詞精度。筆者自己寫了一個(gè)分詞的類,提高代碼復(fù)用率。
from tools.tokenizer.wordCut import WordCut
mydict = ["mysenicdict.txt", "myfooddict.txt"]
file_path = '/home/zcy/haiNan/texttravelgen/data/clean_comments.txt'
# 默認(rèn)是精確模式
test = WordCut()
test.addDictionary(mydict) # 加載自定義詞典
# 分詞,去停用詞(集成在類中了),不顯示在console,保存分詞后的文件到file_path目錄
test.seg_file(file_path, show=False, write=True)
2. 特征提取
- Tf-idf
# 詞頻矩陣:矩陣元素a[i][j] 表示j詞在i類文本下的詞頻
vectorizer = CountVectorizer()
# 統(tǒng)計(jì)每個(gè)詞語的tf-idf權(quán)值
transformer = TfidfTransformer()
freq_word_matrix = vectorizer.fit_transform(corpus)
#獲取詞袋模型中的所有詞語
word = vectorizer.get_feature_names()
tfidf = transformer.fit_transform(freq_word_matrix)
# 元素w[i][j]表示j詞在i類文本中的tf-idf權(quán)重
weight = tfidf.toarray()z
- word2vec
# doc2vec
#訓(xùn)練并保存模型
import gensim
sentences = gensim.models.doc2vec.TaggedLineDocument(token_path)
model = gensim.models.Doc2Vec(sentences, size=100, window=2, min_count=3)
model.train(sentences,total_examples=model.corpus_count, epochs=1000)
model.save('../model/demoDoc2Vec.pkl')
3. 聚類算法
- k-means
# K-means聚類
print 'Start K-means:'
from sklearn.cluster import KMeans
clf = KMeans(n_clusters=20)
s = clf.fit(model.docvecs)
print s
#20個(gè)中心點(diǎn)
print(clf.cluster_centers_)
#每個(gè)樣本所屬的簇
print(clf.labels_)
i = 1
while i <= len(clf.labels_):
print i, clf.labels_[i-1]
i = i + 1
#用來評(píng)估簇的個(gè)數(shù)是否合適,距離越小說明簇分的越好,選取臨界點(diǎn)的簇個(gè)數(shù)
print(clf.inertia_)
- DBSCAN
# dbscan 密度聚類
from sklearn.cluster import DBSCAN
# Compute DBSCAN
db = DBSCAN(eps=0.005, min_samples=10).fit(weight)
print db.core_sample_indices_
db.labels_
實(shí)驗(yàn)結(jié)果
為了將聚類后的類別信息與原文信對(duì)照起來,方便查看,筆者寫了一個(gè)類提高重用效率,將結(jié)果寫到ori_path的路徑下,并提供了排序的功能,代碼如下:
from tools.labelMap.labelText import LabelText
label = clf.labels_
ori_path = "../data/clean_comments.txt"
labelAndText = LabelText(label, ori_path)
labelAndText.sortByLabel(write=True)
- tf-idf + k-means聚類結(jié)果
只舉幾個(gè)label來看:
new file saved in /home/zhouchengyu/haiNan/texttravelgen/data/sortedLabelText.csv
0 一下機(jī)場(chǎng)攜程訂的專車很準(zhǔn)時(shí)的來接了我們,服務(wù)也很好,經(jīng)過大約40分鐘的車程,我們從鳳凰機(jī)場(chǎng)來到了亞龍灣。
0 下午18:35坐動(dòng)車返回美蘭,住在機(jī)場(chǎng)附近小旅館,老板人倒是挺好,挺便宜,裝修這些也算對(duì)得起這個(gè)價(jià)格了。
0 中午十二點(diǎn),飛機(jī)準(zhǔn)時(shí)到達(dá)??诿捞m國際機(jī)場(chǎng)。到達(dá)廳內(nèi),爺爺奶奶早已等待多時(shí)。
0 祥鵬航空8L9963,特價(jià)機(jī)票,加上機(jī)場(chǎng)建設(shè)費(fèi)及燃油費(fèi)等約300。我們老大火速搶完了27人的機(jī)票,帶著這個(gè)超級(jí)散團(tuán),出發(fā)!
0 到了海南一下飛機(jī),濕熱的空氣就迎面撲來。沒幾步路就出汗了。出了機(jī)場(chǎng)趕緊找訂好的住宿的地方。
0 作為一個(gè)北方人去過的最南端就是福州了,也是今年才去的,一般都在武漢止步。終于在北京等了個(gè)把星期,可以坐上飛機(jī)出發(fā)啦~~~
0 新加坡的過境簽相當(dāng)方便,填一張入境卡就可以了,而且居然不用排隊(duì)。興沖沖地通過海關(guān)后發(fā)現(xiàn)機(jī)場(chǎng)的兩小時(shí)的免費(fèi)觀光大巴居然是在轉(zhuǎn)機(jī)區(qū),而不是入境后,只好換了100人民幣的新幣開始自助公交游。從機(jī)場(chǎng)坐地鐵到Raffles Palace,去找魚尾獅公園(Merlion Park)。奇怪的是這么有名的地標(biāo)性景點(diǎn)一路上居然沒有任何指示……雕像附近合影的人超多,大家都是到此一游。
0 所有的機(jī)場(chǎng)大巴都繞來繞去從同一條線路開往機(jī)場(chǎng)了,40分鐘后到達(dá)機(jī)場(chǎng)
0 樟宜機(jī)場(chǎng)被多家機(jī)構(gòu)評(píng)為世界最佳機(jī)場(chǎng)是不無道理的。整個(gè)機(jī)場(chǎng)就像一個(gè)購物休閑中心,吃喝玩樂各項(xiàng)設(shè)施應(yīng)有盡有。在這里轉(zhuǎn)機(jī)絲毫不用擔(dān)心如何消磨時(shí)間。新加坡機(jī)場(chǎng)的登機(jī)一般提前一個(gè)小時(shí),因?yàn)榘矙z被安排在了各個(gè)登機(jī)口。這樣布局的好處是在機(jī)場(chǎng)里可以暢行無阻。加上新加坡機(jī)場(chǎng)實(shí)際上只有國際區(qū)沒有國內(nèi)區(qū)(全國就這一個(gè)機(jī)場(chǎng)嘛),因此除了邊檢,其他區(qū)域都是連成一片的。
0 上班之后,基本每次出門都是想要叫車。但是這次想來一次隨心所欲的旅行,從出發(fā)開始就不再走便捷的方法了,機(jī)場(chǎng)大巴走起。這才發(fā)現(xiàn),志誠麗柏那個(gè)酒店門口的大巴是半小時(shí)發(fā)一次,10分一次,40分一次。會(huì)先到西稍門,然后才出發(fā)。
0 用銀行貴賓卡享受了機(jī)場(chǎng)貴賓室
label0都與機(jī)場(chǎng)有關(guān),可以看出來聚類效果還是不錯(cuò)的。
3 在沙灘上玩了一會(huì)我就去附近泳池邊的WC換泳衣,回來和LILY撲向大海試圖游泳。其實(shí)浪還是挺大的,我們?cè)诳拷碁┑牡胤蕉疾惶芊€(wěn)住自己,遠(yuǎn)處幾個(gè)金發(fā)的外國姑娘卻能在浪里漂浮自如,也許人家從小在海灘玩到大的吧!羨慕啊。 我在水里玩的不亦樂乎,LILY時(shí)刻緊盯著我的皮膚怕我曬傷,我很驚訝他有著能看出我皮膚被曬黑程度的能力,我自己看不出來……在海里玩了半小時(shí)的樣子他果斷拖回樂不思蜀的我,說再曬我就要回去哭了。
3 南灣猴島其實(shí)是個(gè)半島,但這里的位置得天獨(dú)厚,三面環(huán)海,景色和離島一樣的美。除了擁有優(yōu)越的熱帶海島生態(tài)環(huán)境、獼猴特色資源、優(yōu)質(zhì)的海水以及濱海沙灘,還有水上疍家魚排的獨(dú)特民俗風(fēng)情。全國最長的跨海觀光索道,猶如一條凌空彩鏈橫跨新村港灣,將神秘的南灣猴島、迷人的熱帶港灣、濃郁的疍家民俗、喧鬧的漁港風(fēng)情等串成一線。
3 大東海是三亞我常去的沙灘,其他地方不是下餃子就是煮餛飩。
3 剛上船的時(shí)候心情還是挺激動(dòng)的~想象島上迷人的風(fēng)景,結(jié)果到站之后看到碼頭左邊的天空還有點(diǎn)藍(lán)色了,就先往左邊走去看看,一路上人都很多,零星的開著幾個(gè)小店,大概走了100多m的樣子都都到頭了,路封著的,一堆建筑垃圾在哪兒堆著,也沒看見機(jī)械設(shè)備動(dòng)工。于是只能調(diào)頭往回網(wǎng)右邊走,其實(shí)右邊一來我就看見了只有很小一片沙灘,我還以為左邊會(huì)有一大片沙灘和浮潛的海域等著我們呢~越往右邊走越是失望啊,先經(jīng)過美食一條街,各種高價(jià)的食品和紀(jì)念品出售,等終于穿過美食街的人群到了海邊那更是失望,比大東海劃分的每個(gè)游泳區(qū)域還要小一半以上~還只有三個(gè)區(qū)域,完全沒得浮潛地方!我也是醉了,我還以為是像東南亞那些海島一樣,上島都是很寬泛的游泳和浮潛區(qū)域,結(jié)果。。。而且這個(gè)區(qū)域離碼頭也不遠(yuǎn),水質(zhì)可想而知,當(dāng)然人也非常多,瞬間沒了下海的欲望~真不知道網(wǎng)上那些好評(píng)怎么來的~商業(yè)化的氣息太重了,我不相信大多數(shù)人來這里是為了去深潛去玩那些海上項(xiàng)目~家人都說還不如在大東海游泳,還要花100多的門票來看這烏泱泱的水~還好海邊沙灘椅收費(fèi)不貴,15塊一張隨便躺
3 三亞自游行心得1、我不想去景點(diǎn)打卡,只為純度假。所以選擇住大東海,我住在大菠蘿(類似于京華城)附近的哈曼酒店。去年才開的五星酒店,設(shè)施完備,吃住行都方便!哈曼有私家沙灘,有酒店電瓶車接送,服務(wù)很貼心!不是所有酒店都有私家沙灘,需看清。如果住在沒有私家沙灘的酒店,各種不便!我住的是哈曼的16樓行政山海房,(最高17層)記住:一定要高樓層,樓層低了什么都看不到2、大東海商業(yè)發(fā)達(dá),價(jià)廉物美,只是海水和沙灘略遜亞龍灣一籌。 3、交通:因?yàn)槲易〈髺|海,很便利,沒有租車的必要。去較遠(yuǎn)的景點(diǎn)、接送機(jī)等,我全程易到專車、滴滴專車,非常方便4、關(guān)于第一市場(chǎng):易到司機(jī)告訴我們,那已經(jīng)相當(dāng)于旅游商店的性質(zhì)了,大東海區(qū)域用餐,我都在大菠蘿。
3 從照片看就知道這時(shí)候的三亞天氣不是很好,時(shí)常烏云甚至下雨,所以找出來的照片好不好看很大程度取決于天氣怎么樣啦大東海海灘上人很多,長長的海岸線上都是人,我去的這個(gè)時(shí)候天不是很熱,海水還是有些涼的,多以游泳的人并不多,大多數(shù)都在沙灘上撿貝殼或石頭。
3 收拾完畢!步行至大東海廣場(chǎng)的沙灘~脫鞋玩水啦~!
3 亞龍灣是很長一個(gè)海灣。沙灘除了名地細(xì)膩。有很多的星級(jí)酒店私人沙灘。當(dāng)然我們?nèi)サ氖枪查_放海灘,建議四點(diǎn)以后再去游泳,否則日曬很嚴(yán)重。我和小果果都在陰涼下。
第3類都與沙灘有關(guān),聚類效果也不錯(cuò)。
- word2vec + k-means 聚類結(jié)果
1 直到回來后還在流連成都老火鍋的味道。真的很好吃。用牛油做鍋底,加熱后牛油化了,根本不用加水的。
1 離開寬窄巷子,回酒店附近吃了小天鵝,午睡過后下午去人民廣場(chǎng)喝茶采耳。
1 黃流老鴨:海南最有特色的美食之一,在三亞,最正的黃流老鴨還是在勝利路的光明黃流老鴨店,十多年的老店,黃流老鴨必然是白切的才是最好的,也是最好吃的,再加上微熱的蘸料,就更美味了,我們倆人點(diǎn)了白切黃流老鴨、蝦醬地瓜葉和冬瓜海螺湯,冬瓜海螺湯,可以說是此次去三亞吃到的最好吃的湯品,其他地方吃到的總有那么些不新鮮的無奈~,這的冬瓜海螺湯太讓我喜歡了,現(xiàn)在想起來都能感覺到的味美~當(dāng)然,鴨肉那可是吃得精光的~,海南的特色美食啊~~
1 很多老人在這里,聊天,喝茶,打牌,老成都的生活。我們也喝了蓋碗茶,叫了師傅來采耳,享受安逸。
1 第三次登臨這座熱帶島嶼。2013年來的時(shí)候還是一個(gè)剛上大一的小姑娘,在海邊遇到同是一個(gè)人來三亞游玩的泥巴,后來成為了朋友,在上海的時(shí)候還一起約著吃過飯,逛過上海博物館,在夜晚的浦江邊散步拍照。 2014年清明,趁著假期,去了海口,約見了在海南念書的閨蜜,住在海口巴納納國際青旅和一群來自五湖四海的朋友一起玩殺人游戲到凌晨三點(diǎn)多,第二天醒來和青旅認(rèn)識(shí)的姑娘一起逛海南的菜市場(chǎng)。來自濟(jì)南的她對(duì)南方的蔬果特別感興趣,她說,因?yàn)楹D系乃啵谑撬涂剂藗€(gè)海大的研究生,準(zhǔn)備過來撈水果了。 2015年國慶過后,和一起奮戰(zhàn)過高考的好朋友一起,在不同的城市出發(fā)來到三亞找在三亞念書的閨蜜。一起住在三亞老班長國際青旅,和青旅的義工老板們,去吃了三亞最好吃的炒冰炸雞,去大東海游泳玩沙子,好是快活。
1 從北京西開出的Z201次列車,在漫長的27小時(shí)行駛后來到了我的城市。晚上吃過晚飯,八點(diǎn)多到火車站候車,第二天早上八點(diǎn)就能到三亞了。全程762公里,途中跨越瓊州海峽,火車會(huì)被拆分成五節(jié)運(yùn)上粵海輪渡,抵達(dá)海南島接駁后將繼續(xù)行駛。(前三圖來自網(wǎng)絡(luò),侵刪。)
1 海南雞飯:雞飯的主料是雞和大米,最好的雞飯選用的作料是“文昌雞”。由于“文昌雞”供不應(yīng)求,一般雞飯攤檔選用本地雜色雞,要求是剛成熟而尚未下蛋的雞,以1至1.5公斤重為宜。大米選用上等新鮮的優(yōu)質(zhì)米,雞是白切雞。雞飯皮色油黃,肉白且嫩,骨髓帶血,吃來清甜爽口。這種米飯,油潤軟滑,香濃味爽。
1 出發(fā)前在老班長國際青旅訂好住宿。位置就在吉祥街,徑直往海邊走不到五分鐘,吉祥街口有到各個(gè)景點(diǎn)的汽車公交,招手即停,交通十分便利。周圍有海南最大的超市旺豪超市,還有很多吃東西的小飯館,住下來不用愁吃的。
1 三個(gè)人一起逛超市看海鮮買水果,海洋動(dòng)物多的就像水族館。因?yàn)楹D蠚夂蛟?,種出來的水果都像是放大版的。(如果不想在街頭小販那里買不足稱的水果,可以來超市看看,一般海南的各種水果在這里都可以買到。)
1 清補(bǔ)涼是三亞當(dāng)?shù)氐囊环N小吃。將紅棗、薏米、綠豆、芋頭、西瓜、湯圓等煮熟的東西,淋上椰子汁或糖水,清熱消暑,是夏季必備的飲品。在冬天也可以吃到熱的清補(bǔ)涼。清補(bǔ)涼攤多是設(shè)在路旁,擺上一席小桌子和小櫥窗,旁邊擺上一個(gè)保溫冰桶,幾套塑料的椅子和木桌。清補(bǔ)涼攤的小櫥窗里放著一排塑料碗,碗里面分別裝著糖水煮的蕓豆、煮好的綠豆、通心粉、鵪鶉蛋、菠蘿丁、西瓜丁、桂圓肉、紅棗、薏米等等,很是誘人
可以發(fā)現(xiàn),類別1的輸出基本都是美食,但是也有一些錯(cuò)分的情況發(fā)生,考慮到Doc2Vec輸出的向量跟向量大小、迭代次數(shù)等參數(shù),影響較大,這只是一個(gè)Doc2Vec的baseline,這些錯(cuò)誤聚類暫時(shí)還是可以接受的。
類別12主要是景區(qū)的介紹:
12 亞龍灣位于中國最南端的熱帶濱海旅游城市——三亞市東南28公里處,是海南最南端的一個(gè)半月形海灣,全長約7.5公里,是海南名景之一。亞龍灣沙灘綿延7公里且平緩寬闊,淺海區(qū)寬達(dá)50-60米。沙粒潔白細(xì)軟,海水澄澈晶瑩,而且蔚藍(lán)。能見度7-9米,適合潛水。海底世界資源豐富,有珊瑚礁、各種熱帶魚、名貴貝類等。年平均氣溫25.5°C,海水溫度22-25.1°C,終年可游泳,被譽(yù)為“天下第一灣”。.
12 繼續(xù)前行,今天的目標(biāo)是另一個(gè)好地方,這里雖然現(xiàn)在知名度不高,但其實(shí)開發(fā)的很早,曾經(jīng)和五公祠、鹿回頭、天涯海角、大小洞天等景點(diǎn)齊名,既有景色,又有深厚的人文,也是海南四大名菜的出產(chǎn)地之一,東山羊的那個(gè)東山,就是這里。好了,不賣關(guān)子了,這里就是萬寧的東山嶺,雖然海南最高的山是五指山,但這里才是傳說中的“海南第一山”。東山嶺風(fēng)景區(qū)在萬寧市區(qū)往東2公里,因?yàn)槿宀⒅?,形似筆架,歷史上又叫筆架山。這里海拔雖然只有184米高,但是遍山都是奇石,“一線天”勝景之處有塊風(fēng)動(dòng)石,重達(dá)百余噸,能在海風(fēng)的吹拂和人力的推搖下產(chǎn)生晃動(dòng)。當(dāng)年《紅樓夢(mèng)》劇組拍片頭的飛來石,也曾經(jīng)到這里來考察過,雖然最后選擇了黃山之巔的飛來石,但說明那個(gè)時(shí)候的東山嶺就已經(jīng)很著名了。可惜三亞的崛起,已經(jīng)讓人們快要把這里淡忘了。
12 拉市海位于麗江縣城西面10公里處的拉市壩中部,是云南省第一個(gè)以“濕地”命名的自然保護(hù)區(qū)。“拉市”,是古納西語的音譯,“拉”為荒壩,“市”為新,意為新的荒壩。拉市海是遷徙候鳥的棲息地,每年到此越冬或停歇的候鳥有80多種,為滇西北之冠。拉市海邊山清水秀,森林茂密,花草繁盛,清幽秀美。在拉市海一日游,內(nèi)容大都差不多,無非就是騎馬、劃船、馬幫飯等。但價(jià)格不等,從幾十元到幾百元都有,這就需要游客擦亮雙眼。價(jià)錢特別便宜的最好別選,很可能隱藏其他強(qiáng)制性消費(fèi),200左右價(jià)格比較適中,較為靠譜??傮w來講,拉市海作為麗江的著名景點(diǎn),值得一去。
12 我給大家按照從??诔霭l(fā)順時(shí)針環(huán)島方向推薦一下比較值得去的地方(沒去過的肯定還有很多好地方,但只推薦比較了解的,高門票景點(diǎn)一律排除,只保留了南山寺和馮小剛,我覺得可以值回票價(jià)):??谑械暮D鲜〔┪镳^、瓊臺(tái)書院、五公祠、騎樓老街、世紀(jì)大橋、馮小剛電影公社、火山群地質(zhì)公園;文昌市的孔廟、銅鼓嶺、石頭公園、東郊椰林;瓊海市的博鰲禪寺、和樂鎮(zhèn)港北港;萬寧市的東山嶺、大花角、大洲島、加井島;陵水縣的日月灣海門游覽區(qū)、陵水新村疍家漁排;三亞市的海棠灣海棠廣場(chǎng)、亞龍灣海底世界、三亞灣椰夢(mèng)長廊、太陽灣、大東海、小東海、鴻洲國際游艇碼頭夜游三亞灣、半山半島帆船港、鹿回頭山頂公園、鳳凰嶺、臨春嶺、白鷺公園、南山文化旅游區(qū)、崖城學(xué)宮;五指山市的水滿河熱帶雨林風(fēng)景區(qū);樂東縣的鶯歌海鹽場(chǎng)、尖峰嶺;東方市的魚鱗洲、大廣壩、白查村;昌江縣的棋子灣峻壁角;儋州市的東坡書院、千年古鹽田、峨蔓火山海岸、石花水洞、松濤天湖;澄邁縣的羅驛古村、鄰昌礁。安排出行計(jì)劃就從這里面挑吧,這些景點(diǎn)就足夠玩上半個(gè)多月了。如果不喜歡歷史人文,只喜歡風(fēng)光的就少選其中的人文景點(diǎn)。如果像我們一樣都喜歡,那么這些景點(diǎn)一定都不會(huì)讓你們失望的。
可以看出,兩種特征聚類得到的文本,粒度層次是有差別的,這正好有利于提取不同層次的聚類信息,構(gòu)建不同粒度的文本語料庫。
DBSCAN的聚類效果跟參數(shù)eps設(shè)置關(guān)系很大,雖然理論上基于密度的聚類算法要更優(yōu)一些,但是實(shí)驗(yàn)過程表明,在文本數(shù)量較少時(shí),還是k-means這樣的迭代算法,來的實(shí)用些(調(diào)參更簡(jiǎn)單....)
詳細(xì)代碼見筆者的github: TextClustering
××××××××××××××××××××××××××××××××××××××××××
本文屬于筆者(EdwardChou)原創(chuàng)
轉(zhuǎn)載請(qǐng)注明出處
××××××××××××××××××××××××××××××××××××××××××