有了上面的前提,接下來的工作就簡單多了,大體分為兩步,處理訓練樣本集和計算測試樣本數(shù)據(jù)結果。
第零步:樣本數(shù)據(jù)格式
#ID F1 F2 F3 F4 CF1 1 0 5 1 男2 0 1 4 0 女3 1 1 3 1 男
第一步:處理訓練樣本集
代碼邏輯
def NBmodelformat(rdd:RDD[String],path:String)={ //定義接口:輸入為讀取訓練樣本的RDD,訓練樣本處理后的輸出路徑 val allCompute = rdd.map(_.split("\u0009")).map(record => //SEPARATOR0定義為分隔符,這里為"\u0009" { var str = "" val lengthParm = record.length for(i <- 1 until lengthParm) { if(i<lengthParm-1){ //SEPARATOR2定義為分隔符,這里為"_" val standKey = "CF"+i+"_"+record(i)+"_"+record(lengthParm-1) //對特征與類別的關聯(lián)值進行計數(shù) str=str.concat(standKey).concat("\u0009") }else{ //對分類(男/女)進行計數(shù) val standKey = "CA"+"_"+record(lengthParm-1) str=str.concat(standKey).concat("\u0009") } } //對樣本總數(shù)進行計數(shù) str.concat("SUM").trim() } ).flatMap(_.split("\u0009")).map((_,1)).reduceByKey(_+_) //本地輸出一個文件,保存到本地目錄 allCompute.repartition(1).saveAsTextFile(path) }
最終得到訓練樣本結果如下所示:
[[email protected] model1]$ cat cidmap20161121 |more -3(CF1_1_男,1212)(CF1_0_女,205)(CF2_0_男,427)
第二步:樸素貝葉斯計算邏輯
模型demo
def NBmodels(line:String,cidMap:Map[String,Int]):String={ val record = line.split("\u0009") val manNum = cidMap.get("CA_男").getOrElse(0).toDouble val womanNum = cidMap.get("CA_女").getOrElse(0).toDouble val sum = cidMap.get("SUM").getOrElse(0).toDouble //計算先驗概率,這里采取了拉普拉斯平滑處理,解決冷啟動問題 val manRate = (manNum+1)/(sum+2) val womanRate = (womanNum+1)/(sum+2) var manProbability = 1.0 var womanProbability = 1.0 for(i <- 1 until record.length){ //組合key鍵 val womanKey = "CF"+i+"_"+record(i)+"_"+"女" val manKey = "CF"+i+"_"+record(i)+"_"+"男" val catWoman = "CA"+"_"+"女" val catMan = "CA"+"_"+"男" //確定特征向量空間的種類,解決冷啟動問題 val num = 3 //獲取訓練模型得到的結果值 val womanValue = http://www.netofthings.cn/JieJueFangAn/2016-12/(cidMap.get(womanKey).getOrElse(0)+1)/(cidMap.get(catWoman).getOrElse(0)+num)"女" else "男" }
第三步:用測試數(shù)據(jù)集得到分類結果
驅動模塊
def main(args:Array[String]):Unit={ val SAMPLEDATA = "file:///E...本地目錄1" val SAMPLEMODEL = "file:///E...本地目錄2" val INPUTDATA = "file:///E...本地目錄3" val RESULTPATH = "file:///E...本地目錄4" val sc = new SparkContext("local","TestNBModel") //刪除目錄文件 DealWays(sc,SAMPLEMODEL) //讀取訓練數(shù)據(jù)SAMPLEDATA,featureNum為特征向量個數(shù) //首先過濾長度不標準的行 val NaiveBayesData = http://www.netofthings.cn/JieJueFangAn/2016-12/sc.textFile(SAMPLEDATA, 1).map(_.trim).filter(line =>Filter(line,6))>總結:上面主要介紹了三個步驟去編寫一個簡單的樸素貝葉斯算法demo,還有一些值得優(yōu)化的點,寫法也比較偏命令式編程(告訴計算機你想要做什么事?)。但是目的在于給一些童鞋一個印象,理解上也方便些,清楚如何去落地一個簡單的算法,這很重要。
后續(xù)系列文章主要有這幾個方面:
- 實現(xiàn)一些常用的算法模型,一切洞察背后的來龍去脈。
- 結合線上業(yè)務場景模型,介紹實際的大數(shù)據(jù)挖掘流程。
- 介紹大數(shù)據(jù)挖掘與數(shù)據(jù)產(chǎn)品的融合對接。
作者介紹
汪榕,3年場景建模經(jīng)驗,曾累計獲得8次數(shù)學建模一等獎,包括全國大學生國家一等獎,在國內期刊發(fā)表過相關學術研究。兩年電商數(shù)據(jù)挖掘實踐,負責開發(fā)精準營銷產(chǎn)品中的用戶標簽體系。發(fā)表過數(shù)據(jù)挖掘相關的多篇文章。目前在互聯(lián)網(wǎng)金融行業(yè)從事數(shù)據(jù)挖掘工作,參與開發(fā)反欺詐實時監(jiān)控系統(tǒng)。