之前沒有修索道,現(xiàn)在修了,從廬山站下高鐵,打出租到廬山索道的地方15分鐘左右就到,原答案適合從九江火車站下車的朋友。
原答案是買車票不要買到廬山站的,廬山站比九江站離廬山景區(qū)遠一些。在九江火車站下車后坐公交或者打車到九江汽車站,買票到廬山,司機會把大家送到景區(qū)北門,讓大家去買門票,在二樓檢完票以后,再去坐之前的那輛車。司機會把大家送到牯嶺鎮(zhèn)上。
在廬山站下車,一、沿著九江站出站口地下通道下去后,一路上都有廬山索道公交車地點的引導(dǎo)標識。
步行大概5分鐘后,就來到了公交總站,圖片上停了很多車的就是。九車溫馨提示:一定要在小編拍攝的位置乘車,公交總站里是不讓乘車的。
二、在火車站廣場公交站臺乘坐9/26/101/105/108路到達長虹立交橋站(3站路程)轉(zhuǎn)乘63路直達三疊泉
三、在火車站廣場公交站臺乘坐15/27/36/66路到九江汽車總站轉(zhuǎn)乘廬山風(fēng)景區(qū)專線車
具體公交線路詳見下表
想要飽覽廬山上的美景至少需要兩天,所以合理安排好自己的時間,(九車提示:乘車+游玩+吃住人均1000?左右)
返程依舊是乘索道纜車下山,然后乘坐57路公交返回九江站。
準確來講,廬山站更應(yīng)該叫“九江西站”,和廬山景區(qū)的關(guān)系不大。廬山站分為老站樓和新站樓,新站樓于2022年5月建成,所以目前坐到廬山站下的話都是從新站樓出站,老站樓已經(jīng)停止使用。
作為九江本地人,如果你不是自駕租車,那么其實是不建議前往廬山景區(qū)的游客在廬山站下車的,因為廬山站和廬山索道之間并無直接的公共交通連接,非常麻煩,最好在九江站下車。
但是,不論是在哪個火車站下車,都是建議打車前往廬山索道。
為什么建議打車?
因為兩個火車站離廬山景區(qū)的入口都很遠,從九江站出來的話,雖說有57路公交直達索道下站,但這個公交屬于中巴類型,一小時才發(fā)一班,旅游旺季等候57路公交的人會特別多,導(dǎo)致非常耗時。如果不趕時間或處于旅游淡季的話,當然也可以選擇坐57路。
如果處于旺季且趕時間可以優(yōu)先選擇打車前往廬山索道下站?;疖囌境稣究跁泻芏嗬偷?,不建議坐他們的車,基本都是坑游客。建議在滴滴等平臺上訂車,直接到索道下站,價格一般在50元左右算比較正常(至少沒坑太多)。如果在市內(nèi)攔車去索道下站的話,司機一般不會打表,只是提前說好價錢,可以還價。
為什么選擇坐索道上山而不是從北門換乘中心坐班車上山?
如果坐班車,你將會體驗40多分鐘的盤山路,易暈車者不要輕易嘗試!
下面再繼續(xù)說索道。
廬山大景區(qū)內(nèi)其實有多條索道,比如廬山索道、三疊泉索道等,如果是單純上山的話,那條索道就叫“廬山索道”,坐索道的地方叫“廬山索道下站”,下索道的地方叫“廬山索道上站”,這些地名在某德和某度地圖上都可以搜得到,索道往返票一人120元,具體的優(yōu)惠政策可以在某程上直接查。下索道的地方就在牯嶺鎮(zhèn)的鎮(zhèn)上,步行10分鐘左右即可到達牯嶺街、街心公園的中心地帶。
廬山推薦打卡地:牯嶺街、街心公園、如琴湖、錦繡谷(個人認為是最精華的,險峰和仙人洞在錦繡谷內(nèi)部)、花徑、含鄱口(看日出和鄱陽湖)、植物園、五老峰、三疊泉、大口瀑布、美廬別墅、廬山會議舊址、廬山戀影院、名人舊居等。
如果你想去看李白筆下的廬山瀑布,那么得去秀峰景區(qū)。秀峰景區(qū)不屬于廬山大景區(qū)管轄,屬于獨立出來的小景區(qū),得單獨購票前往。(秀峰景區(qū)的纜車稍微老舊了點,敞篷款)
廬山周邊的東林寺、東林大佛、廬山西海、鄱陽湖、落星墩、白鹿洞書院、石鐘山等景點以及九江市區(qū)也值得打卡。
美食的話,一定要嘗嘗本地的特色菜,推薦去一些小館子,可能會有不一樣的收獲。
江西已經(jīng)有2個多月沒有下雨,鄱陽湖提前3個月進入枯水期,落星墩也比以往更早成為了網(wǎng)紅景點。下高速時,等待掃碼的小車排成了長龍,防疫工作人員指著幾輛旅游大巴上烏泱泱的幾波人說,都是來看落星墩的。
一到周末,廬山市到處都是游客,玩到中午,選擇了這家排名靠前的星宴主題餐廳。餐廳位置,不錯,離落星墩開車也就5、6分鐘,不過店門口沒有停車位,人行道停滿后就只能到別處尋找停車位。
從找停車位開始,就已經(jīng)暗示這里接待能力有缺陷。所幸的是,雖然來得晚,但還有一個空包廂,剛好適合我們一行8個人。
這家店裝修復(fù)古、精致,中廳專門造了個水景,看上去很講究的樣子,有樓梯可以上二樓,總體面積挺大的。
雖然面積看上去可以容納足夠的客人,但服務(wù)和承載能力完全跟不上,比如服務(wù)員只有上菜的時候會來,其他時間是完全喊不到,因為他們忙得根本停不下來,很多時候你需要什么,只能靠自己動手;再拿廁所來說,女廁貌似只有1、2個隔間,所以門口一直是保持排隊的狀態(tài),洗手池也只有2個,其中一個還被拿來洗碗,洗個手也需要排隊的場景現(xiàn)在是很少見了。
說到菜,味道還是不錯的,贛菜的風(fēng)格非常明顯。尤其是牛肉燒得不錯,鋪在下面的土豆有些微焦,吃起來特別香。
總得來說值得一吃,希望能好好提升服務(wù)接待能力,這樣體驗感才會更好。
地址:廬山市南康鎮(zhèn)廬陽路6號星御國際旁邊
廬山位于中國江西省,是中國著名的風(fēng)景名勝區(qū)之一。廬山山勢雄奇,風(fēng)景秀麗,以山水相映、云霧繚繞而聞名于世。每年吸引著大批游客前來觀光、登山和避暑。
廬山擁有豐富多樣的住宿選擇,從高檔酒店到經(jīng)濟型客棧,應(yīng)有盡有。以下是一些廬山住宿推薦:
廬山大酒店位于廬山主峰腳下,環(huán)境優(yōu)美,交通便利。酒店設(shè)施齊全,提供豪華客房、餐廳、會議室等服務(wù)。游客可以欣賞到廬山美麗的風(fēng)景,盡情享受舒適的住宿體驗。
廬山賓館是一家歷史悠久的酒店,位于廬山主峰腳下的風(fēng)景區(qū)內(nèi)。酒店建筑典雅,環(huán)境清幽,提供各類客房和餐飲服務(wù)。在這里住宿可以感受到廬山的獨特魅力。
廬山青年旅舍是一個經(jīng)濟實惠的住宿選擇。房間簡潔舒適,價格親民,適合背包客和預(yù)算有限的游客。旅舍地理位置優(yōu)越,離各個景點都很近,方便游覽。
除了以上推薦的住宿地點,廬山還有許多其他的酒店和客??晒┻x擇。游客可以根據(jù)自己的需求和預(yù)算,選擇適合自己的住宿方式。
廬山旅游攻略住宿部分就介紹到這里。希望以上信息對計劃前往廬山旅游的游客有所幫助。感謝您閱讀本篇文章,祝您旅途愉快!
2.5級以上地震能感覺到,地震等級分為九級,一般小于2.5級的地震人無感覺,2.5級以上人有感覺?!∫话銓⑿∮?級的地震稱為超微震。M≥1級,小于3級的稱為弱震或微震,如果震源不是很淺,一般不易覺察。M≥3級,小于4.5級的稱為有感地震,這種地震人們能夠感覺到,但一般不會造成破壞。M≥4.5級,小于6級的稱為中強震,屬于可造成破壞的地震。M≥6級,小于7級的稱為強震。M≥7級,小于8級的稱為大地震。8級以及8級以上的稱為巨大地震。
高層樓撤下,電梯不可搭,萬一斷電力,欲速則不達。
平房避震有講究,是跑是留兩可求,因地制宜做決斷,錯過時機諸事休。
廬山位于中國江西省九江市,是中國著名的風(fēng)景名勝區(qū)之一。它以奇峻的山峰、清澈的湖水和秀麗的自然風(fēng)光而聞名于世。在我眼中,廬山是一片神奇的仙境。
我難以抑制內(nèi)心的激動,和同學(xué)們一同踏上了廬山的山峰。山路崎嶇,但是四周的景色卻讓人陶醉其中。我們看到了藍天白云下連綿的山峰,聽到了鳥兒歌唱的聲音,感受到了大自然的力量。登上山頂,我們俯瞰著下方的云海,仿佛來到了仙界。
廬山的湖水是如此清澈,宛如一面鏡子。我們乘坐游船漫游在湖上,欣賞著湖水周圍的美景。湖面上漂浮著白蓮花,倒映著遠處的山峰。湖水清澈見底,我們還能看到水中游動的魚兒。這樣的美景使我們心曠神怡,忘卻了一切煩惱。
廬山還有許多著名的名勝古跡,其中最有名的就是蓮花峰。蓮花峰猶如一朵盛開的蓮花,層層疊疊,美不勝收。還有一座古老的寺廟——歸元寺,廟內(nèi)古色古香,寺廟周圍群山圍繞,景色壯觀。我們頂禮膜拜,感受到了莊嚴肅穆的氛圍。
廬山之行給我留下了深刻的印象。這片美麗的土地教會了我如何欣賞大自然的美景,讓我感受到了大自然的力量和恩賜。登上山峰,俯瞰云海,我仿佛置身于仙境;漫游湖水,欣賞湖光山色,我忘卻了塵世間的煩惱。這次廬山之旅,不僅讓我近距離感受了自然的壯麗之美,還讓我明白了保護自然環(huán)境的重要性。
通過這次廬山之行,我學(xué)到了很多知識,也增加了對自然的敬畏之心。我將牢記這次難忘的經(jīng)歷,并將它融入到我的作文之中。
感謝您閱讀我關(guān)于廬山之旅的作文,希望通過這篇文章,能讓您感受到廬山之美,激發(fā)對大自然的熱愛,并有更深入的了解廬山這個美麗的地方。
廬山素有“天下第一奇山”之稱,它位于中國江西省,是中國著名的風(fēng)景名勝區(qū)之一。而在秋天的廬山,更是一片美不勝收的景象。廬山秋天以其壯麗的自然景觀和絢麗多彩的秋色,吸引著眾多游客前來欣賞。
廬山的秋天是一個絢麗多彩的季節(jié),充滿了濃厚的詩意和藝術(shù)氛圍。山上的樹木在秋風(fēng)的吹拂下,變換出各種明亮的色彩。紅葉、黃葉、橙葉交相輝映,在陽光的照射下,閃爍著如黃金般的光芒。整個山坡都被五彩斑斕的秋葉裝點得如同一幅繪畫,給人一種奇幻美好的感覺。
登上廬山,可以遠眺山下的美景。秋天的廬山,云霧繚繞,仿佛進入了童話世界。山川起伏,山峰在云海之間若隱若現(xiàn)。遠處的村莊、湖泊、河流隱約可見,與山景融為一體,構(gòu)成了一幅壯觀的畫卷。
在廬山的山巔,有許多著名的景點和步道,供游客觀賞和游覽。其中,著名的三大奇觀包括花崗巖峰林、云海和溫泉。廬山的花崗巖峰林是其獨特的自然景觀之一,峰巒疊嶂,形狀各異。廬山的云海更是令人驚嘆,云霧彌漫山間,如同一片白色的海洋,美不勝收。而廬山溫泉更是讓人身心舒暢,它有著豐富的礦物質(zhì)和療效,在秋天泡溫泉,舒緩疲勞,放松身心,是一種絕佳的享受。
廬山還有許多名勝古跡,可以讓游客感受到悠久的歷史文化。比如廬山瀑布群,這里有著眾多壯麗的瀑布,激起了無盡的美麗和浩然之氣。還有八百里廬山畫廊,這是一條蜿蜒曲折的山間小路,兩旁是高聳入云的山峰和茂密的樹林,每走一步都能感受到大自然的鬼斧神工。
而在廬山的秋天,還有一個讓人難以忘懷的美景,那就是日出和日落。登上廬山的山巔,站在高處,遠眺日出和日落的美景,是一種無與倫比的體驗。一輪紅日冉冉升起,映照著整個山脈,溫暖了人的心靈。而夕陽西下時,整個廬山都被余暉染紅,如同一個幻境般令人陶醉。
廬山的宜人氣候和獨特的自然環(huán)境,使得它成為了眾多攝影愛好者的圣地。在廬山秋天,不僅可以欣賞到絢麗的景色,還可以品味到大自然的純真和美好。無論是專業(yè)攝影師還是普通游客,都可以在這里找到屬于自己的美。
總之,廬山的秋天是一個充滿魅力和詩意的季節(jié)。它以其絢麗多彩的景色,吸引了無數(shù)游客前來游覽和欣賞。在廬山,你可以感受到大自然的美妙和力量,體驗到人與自然的和諧共生。如果你還沒有來過廬山,不妨在下一個秋天,來一場與大自然的約會,感受廬山秋天的魅力。
廬山,這座位于江西省北部、鄱陽湖畔的美麗山峰,以其豐富的自然資源,獨特的氣候條件,孕育出了獨具特色的廬山特產(chǎn)。這些特產(chǎn)不僅代表著廬山地區(qū)的文化底蘊,也成為了游客們必嘗的美食。今天,我們就來一起探尋廬山特產(chǎn)的魅力。
廬山云霧茶,被譽為“茶中瑰寶”,生長在海拔千米以上的高峰,吸取山水之精華,具有獨特的蘭花香味。廬山茶園分布在各個山谷、溪澗、坡地,以白鹿洞、大林山、小林山等地的品質(zhì)最佳。廬山云霧茶具有祛暑、解毒、消食、去脂之功效,是廬山特產(chǎn)中的明星產(chǎn)品。
廬山石雞,是一種生長在巖石縫隙中的珍稀蛙類。其肉質(zhì)鮮美,營養(yǎng)豐富,是廬山特產(chǎn)中的又一美味。廬山石雞主要分布在山區(qū)的溪流、水溝、石洞等地,以黃沙潭、汗流等地的石雞品質(zhì)最佳。在品嘗廬山石雞時,其獨特的口感和營養(yǎng)價值定會讓你回味無窮。
廬山竹筒飯是廬山地區(qū)的另一特色美食。將米飯和配料裝入竹筒,文火慢燉,竹香濃郁,美味可口。廬山地區(qū)的竹子品質(zhì)優(yōu)良,適合制作竹筒飯。此外,廬山地區(qū)的美食文化源遠流長,因此也衍生出了許多以竹筒為材料的特色菜肴。
除了以上介紹的幾種特產(chǎn),廬山地區(qū)還有許多其他獨具特色的美食和手工藝品。如廬山酥餅、廬山桂花糕、廬山野生獼猴桃等,都深受游客們的喜愛。此外,廬山的傳統(tǒng)手工藝品如竹編、木雕、石雕等,也是極具地方特色的紀念品。
總的來說,廬山特產(chǎn)是廬山地區(qū)文化底蘊和自然資源的完美結(jié)合。無論是品嘗美食,還是購買紀念品,廬山特產(chǎn)都是游客們不容錯過的選擇。在廬山的旅行中,讓我們一起品味這些獨具特色的美食,感受這片美食天堂的魅力吧!
之前看了Mahout官方示例 20news 的調(diào)用實現(xiàn);于是想根據(jù)示例的流程實現(xiàn)其他例子。網(wǎng)上看到了一個關(guān)于天氣適不適合打羽毛球的例子。
訓(xùn)練數(shù)據(jù):
Day Outlook Temperature Humidity Wind PlayTennis
D1 Sunny Hot High Weak No
D2 Sunny Hot High Strong No
D3 Overcast Hot High Weak Yes
D4 Rain Mild High Weak Yes
D5 Rain Cool Normal Weak Yes
D6 Rain Cool Normal Strong No
D7 Overcast Cool Normal Strong Yes
D8 Sunny Mild High Weak No
D9 Sunny Cool Normal Weak Yes
D10 Rain Mild Normal Weak Yes
D11 Sunny Mild Normal Strong Yes
D12 Overcast Mild High Strong Yes
D13 Overcast Hot Normal Weak Yes
D14 Rain Mild High Strong No
檢測數(shù)據(jù):
sunny,hot,high,weak
結(jié)果:
Yes=》 0.007039
No=》 0.027418
于是使用Java代碼調(diào)用Mahout的工具類實現(xiàn)分類。
基本思想:
1. 構(gòu)造分類數(shù)據(jù)。
2. 使用Mahout工具類進行訓(xùn)練,得到訓(xùn)練模型。
3。將要檢測數(shù)據(jù)轉(zhuǎn)換成vector數(shù)據(jù)。
4. 分類器對vector數(shù)據(jù)進行分類。
接下來貼下我的代碼實現(xiàn)=》
1. 構(gòu)造分類數(shù)據(jù):
在hdfs主要創(chuàng)建一個文件夾路徑 /zhoujainfeng/playtennis/input 并將分類文件夾 no 和 yes 的數(shù)據(jù)傳到hdfs上面。
數(shù)據(jù)文件格式,如D1文件內(nèi)容: Sunny Hot High Weak
2. 使用Mahout工具類進行訓(xùn)練,得到訓(xùn)練模型。
3。將要檢測數(shù)據(jù)轉(zhuǎn)換成vector數(shù)據(jù)。
4. 分類器對vector數(shù)據(jù)進行分類。
這三步,代碼我就一次全貼出來;主要是兩個類 PlayTennis1 和 BayesCheckData = =》
package myTesting.bayes;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.util.ToolRunner;
import org.apache.mahout.classifier.naivebayes.training.TrainNaiveBayesJob;
import org.apache.mahout.text.SequenceFilesFromDirectory;
import org.apache.mahout.vectorizer.SparseVectorsFromSequenceFiles;
public class PlayTennis1 {
private static final String WORK_DIR = "hdfs://192.168.9.72:9000/zhoujianfeng/playtennis";
/*
* 測試代碼
*/
public static void main(String[] args) {
//將訓(xùn)練數(shù)據(jù)轉(zhuǎn)換成 vector數(shù)據(jù)
makeTrainVector();
//產(chǎn)生訓(xùn)練模型
makeModel(false);
//測試檢測數(shù)據(jù)
BayesCheckData.printResult();
}
public static void makeCheckVector(){
//將測試數(shù)據(jù)轉(zhuǎn)換成序列化文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"testinput";
String output = WORK_DIR+Path.SEPARATOR+"tennis-test-seq";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean參數(shù)是,是否遞歸刪除的意思
fs.delete(out, true);
}
SequenceFilesFromDirectory sffd = new SequenceFilesFromDirectory();
String[] params = new String[]{"-i",input,"-o",output,"-ow"};
ToolRunner.run(sffd, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("文件序列化失??!");
System.exit(1);
}
//將序列化文件轉(zhuǎn)換成向量文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"tennis-test-seq";
String output = WORK_DIR+Path.SEPARATOR+"tennis-test-vectors";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean參數(shù)是,是否遞歸刪除的意思
fs.delete(out, true);
}
SparseVectorsFromSequenceFiles svfsf = new SparseVectorsFromSequenceFiles();
String[] params = new String[]{"-i",input,"-o",output,"-lnorm","-nv","-wt","tfidf"};
ToolRunner.run(svfsf, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("序列化文件轉(zhuǎn)換成向量失??!");
System.out.println(2);
}
}
public static void makeTrainVector(){
//將測試數(shù)據(jù)轉(zhuǎn)換成序列化文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"input";
String output = WORK_DIR+Path.SEPARATOR+"tennis-seq";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean參數(shù)是,是否遞歸刪除的意思
fs.delete(out, true);
}
SequenceFilesFromDirectory sffd = new SequenceFilesFromDirectory();
String[] params = new String[]{"-i",input,"-o",output,"-ow"};
ToolRunner.run(sffd, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("文件序列化失??!");
System.exit(1);
}
//將序列化文件轉(zhuǎn)換成向量文件
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"tennis-seq";
String output = WORK_DIR+Path.SEPARATOR+"tennis-vectors";
Path in = new Path(input);
Path out = new Path(output);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean參數(shù)是,是否遞歸刪除的意思
fs.delete(out, true);
}
SparseVectorsFromSequenceFiles svfsf = new SparseVectorsFromSequenceFiles();
String[] params = new String[]{"-i",input,"-o",output,"-lnorm","-nv","-wt","tfidf"};
ToolRunner.run(svfsf, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("序列化文件轉(zhuǎn)換成向量失??!");
System.out.println(2);
}
}
public static void makeModel(boolean completelyNB){
try {
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String input = WORK_DIR+Path.SEPARATOR+"tennis-vectors"+Path.SEPARATOR+"tfidf-vectors";
String model = WORK_DIR+Path.SEPARATOR+"model";
String labelindex = WORK_DIR+Path.SEPARATOR+"labelindex";
Path in = new Path(input);
Path out = new Path(model);
Path label = new Path(labelindex);
FileSystem fs = FileSystem.get(conf);
if(fs.exists(in)){
if(fs.exists(out)){
//boolean參數(shù)是,是否遞歸刪除的意思
fs.delete(out, true);
}
if(fs.exists(label)){
//boolean參數(shù)是,是否遞歸刪除的意思
fs.delete(label, true);
}
TrainNaiveBayesJob tnbj = new TrainNaiveBayesJob();
String[] params =null;
if(completelyNB){
params = new String[]{"-i",input,"-el","-o",model,"-li",labelindex,"-ow","-c"};
}else{
params = new String[]{"-i",input,"-el","-o",model,"-li",labelindex,"-ow"};
}
ToolRunner.run(tnbj, params);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("生成訓(xùn)練模型失?。?#34;);
System.exit(3);
}
}
}
package myTesting.bayes;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.mahout.classifier.naivebayes.BayesUtils;
import org.apache.mahout.classifier.naivebayes.NaiveBayesModel;
import org.apache.mahout.classifier.naivebayes.StandardNaiveBayesClassifier;
import org.apache.mahout.common.Pair;
import org.apache.mahout.common.iterator.sequencefile.PathType;
import org.apache.mahout.common.iterator.sequencefile.SequenceFileDirIterable;
import org.apache.mahout.math.RandomAccessSparseVector;
import org.apache.mahout.math.Vector;
import org.apache.mahout.math.Vector.Element;
import org.apache.mahout.vectorizer.TFIDF;
import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.Multiset;
public class BayesCheckData {
private static StandardNaiveBayesClassifier classifier;
private static Map<String, Integer> dictionary;
private static Map<Integer, Long> documentFrequency;
private static Map<Integer, String> labelIndex;
public void init(Configuration conf){
try {
String modelPath = "/zhoujianfeng/playtennis/model";
String dictionaryPath = "/zhoujianfeng/playtennis/tennis-vectors/dictionary.file-0";
String documentFrequencyPath = "/zhoujianfeng/playtennis/tennis-vectors/df-count";
String labelIndexPath = "/zhoujianfeng/playtennis/labelindex";
dictionary = readDictionnary(conf, new Path(dictionaryPath));
documentFrequency = readDocumentFrequency(conf, new Path(documentFrequencyPath));
labelIndex = BayesUtils.readLabelIndex(conf, new Path(labelIndexPath));
NaiveBayesModel model = NaiveBayesModel.materialize(new Path(modelPath), conf);
classifier = new StandardNaiveBayesClassifier(model);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("檢測數(shù)據(jù)構(gòu)造成vectors初始化時報錯。。。。");
System.exit(4);
}
}
/**
* 加載字典文件,Key: TermValue; Value:TermID
* @param conf
* @param dictionnaryDir
* @return
*/
private static Map<String, Integer> readDictionnary(Configuration conf, Path dictionnaryDir) {
Map<String, Integer> dictionnary = new HashMap<String, Integer>();
PathFilter filter = new PathFilter() {
@Override
public boolean accept(Path path) {
String name = path.getName();
return name.startsWith("dictionary.file");
}
};
for (Pair<Text, IntWritable> pair : new SequenceFileDirIterable<Text, IntWritable>(dictionnaryDir, PathType.LIST, filter, conf)) {
dictionnary.put(pair.getFirst().toString(), pair.getSecond().get());
}
return dictionnary;
}
/**
* 加載df-count目錄下TermDoc頻率文件,Key: TermID; Value:DocFreq
* @param conf
* @param dictionnaryDir
* @return
*/
private static Map<Integer, Long> readDocumentFrequency(Configuration conf, Path documentFrequencyDir) {
Map<Integer, Long> documentFrequency = new HashMap<Integer, Long>();
PathFilter filter = new PathFilter() {
@Override
public boolean accept(Path path) {
return path.getName().startsWith("part-r");
}
};
for (Pair<IntWritable, LongWritable> pair : new SequenceFileDirIterable<IntWritable, LongWritable>(documentFrequencyDir, PathType.LIST, filter, conf)) {
documentFrequency.put(pair.getFirst().get(), pair.getSecond().get());
}
return documentFrequency;
}
public static String getCheckResult(){
Configuration conf = new Configuration();
conf.addResource(new Path("/usr/local/hadoop/conf/core-site.xml"));
String classify = "NaN";
BayesCheckData cdv = new BayesCheckData();
cdv.init(conf);
System.out.println("init done...............");
Vector vector = new RandomAccessSparseVector(10000);
TFIDF tfidf = new TFIDF();
//sunny,hot,high,weak
Multiset<String> words = ConcurrentHashMultiset.create();
words.add("sunny",1);
words.add("hot",1);
words.add("high",1);
words.add("weak",1);
int documentCount = documentFrequency.get(-1).intValue(); // key=-1時表示總文檔數(shù)
for (Multiset.Entry<String> entry : words.entrySet()) {
String word = entry.getElement();
int count = entry.getCount();
Integer wordId = dictionary.get(word); // 需要從dictionary.file-0文件(tf-vector)下得到wordID,
if (StringUtils.isEmpty(wordId.toString())){
continue;
}
if (documentFrequency.get(wordId) == null){
continue;
}
Long freq = documentFrequency.get(wordId);
double tfIdfValue = tfidf.calculate(count, freq.intValue(), 1, documentCount);
vector.setQuick(wordId, tfIdfValue);
}
// 利用貝葉斯算法開始分類,并提取得分最好的分類label
Vector resultVector = classifier.classifyFull(vector);
double bestScore = -Double.MAX_VALUE;
int bestCategoryId = -1;
for(Element element: resultVector.all()) {
int categoryId = element.index();
double score = element.get();
System.out.println("categoryId:"+categoryId+" score:"+score);
if (score > bestScore) {
bestScore = score;
bestCategoryId = categoryId;
}
}
classify = labelIndex.get(bestCategoryId)+"(categoryId="+bestCategoryId+")";
return classify;
}
public static void printResult(){
System.out.println("檢測所屬類別是:"+getCheckResult());
}
}