用二项逻辑斯蒂回归解决二分类问题
生活随笔
收集整理的這篇文章主要介紹了
用二项逻辑斯蒂回归解决二分类问题
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
邏輯斯蒂回歸:
邏輯斯蒂回歸是統(tǒng)計(jì)學(xué)習(xí)中的經(jīng)典分類方法,屬于對(duì)數(shù)線性模型。logistic回歸的因變量可以是二分類的,
也可以是多分類的
基本原理
logistic 分布
折X是連續(xù)的隨機(jī)變量,X服從logistic分布是指X具有下列分布函數(shù)和密度函數(shù):
?
其中為位置參數(shù),為形狀參數(shù)。與圖像如下,其中分布函數(shù)是以為中心對(duì)陣,越小曲線變化越快
?
二項(xiàng)logistic回歸模型;
二項(xiàng)logistic回歸模型如下:
?
其中是輸入,輸出,W稱為權(quán)值向量,b稱為偏置, 是w和x的內(nèi)積
?
參數(shù)估計(jì)
?
? 假設(shè):
?
?
?
??
?
? 則似然函數(shù)為:
?
?
?
??
?
? 求對(duì)數(shù)似然函數(shù):
?
?
?
??
?
?
?
??
?
? 從而對(duì)
?
??
?
求極大值,得到w的估計(jì)值。求極值的方法可以是梯度下降法,梯度上升法等。
?
示例代碼:?
#導(dǎo)入需要的包: from pyspark import SparkContext from pyspark.sql import SparkSession,Row,functions from pyspark.ml.linalg import Vector,Vectors from pyspark.ml.evaluation import MulticlassClassificationEvaluator from pyspark.ml import Pipeline from pyspark.ml.feature import IndexToString,StringIndexer,VectorIndexer,HashingTF,Tokenizer from pyspark.ml.classification import LogisticRegression,LogisticRegressionModel,BinaryLogisticRegressionSummary,LogisticRegression#用二項(xiàng)邏輯斯蒂回歸解決 二分類 問(wèn)題 sc = SparkContext('local','用二項(xiàng)邏輯斯蒂回歸解決二分類問(wèn)題') spark = SparkSession.builder.master('local').appName('用二項(xiàng)邏輯斯蒂回歸解決二分類問(wèn)題').getOrCreate() #讀取數(shù)據(jù),簡(jiǎn)要分析 #我們定制一個(gè)函數(shù),來(lái)返回一個(gè)指定的數(shù)據(jù),然后讀取文本文件,第一個(gè)map把每行的數(shù)據(jù)用"," #隔開,比如在我們的數(shù)據(jù)集中,每行被分成了5部分,目前4部分是鳶尾花的四個(gè)特征,最后一部分鳶尾花的分類; #我們這里把特征存儲(chǔ)在Vector中,創(chuàng)建一個(gè)Iris模式的RDd,然后轉(zhuǎn)化成DataFrame;最后調(diào)用show()方法查看數(shù)據(jù) def f(x): rel ={} rel['features'] = Vectors.dense(float(x[0]),float(x[1]),float(x[2]),float(x[3])) rel['label'] = str(x[4]) return rel data= sc.textFile("file:///usr/local/spark/mycode/exercise/iris.txt").map(lambda line : line.split(',')).map(lambda p : Row(**f(p))).toDF() #?因?yàn)槲覀儸F(xiàn)在處理的是2分類問(wèn)題,所以我們不需要全部的3類數(shù)據(jù),我們要從中選出兩類的 #數(shù)據(jù)。這里首先把剛剛得到的數(shù)據(jù)注冊(cè)成一個(gè)表iris,注冊(cè)成這個(gè)表之后,我們就可以 #通過(guò)sql語(yǔ)句進(jìn)行數(shù)據(jù)查詢,比如我們這里選出了所有不屬于“Iris-setosa”類別的數(shù) #據(jù);選出我們需要的數(shù)據(jù)后,我們可以把結(jié)果打印出來(lái)看一下,這時(shí)就已經(jīng)沒(méi)有“Iris-setosa”類別的數(shù)據(jù) data.createOrReplaceTempView("iris") df = spark.sql("select * from iris where label != 'Iris-setosa'") rel = df.rdd.map(lambda t : str(t[1])+":"+str(t[0])).collect() for item in rel: print(item) 如圖:
?
#構(gòu)建ML的pipeline #分別獲取標(biāo)簽列和特征列,進(jìn)行索引,并進(jìn)行了重命名 labelIndexer = StringIndexer().setInputCol('label').setOutputCol('indexedLabel').fit(df) featureIndexer = VectorIndexer().setInputCol('features').setOutputCol('indexedFeatures').fit(df) #把數(shù)據(jù)集隨機(jī)分成訓(xùn)練集和測(cè)試集,其中訓(xùn)練集占70% trainingData, testData =df.randomSplit([0.7,0.3]) #設(shè)置logistic的參數(shù),這里我們統(tǒng)一用setter的方法來(lái)設(shè)置,也可以用ParamMap來(lái)設(shè)置 #(具體的可以查看spark mllib的官網(wǎng))。這里我們?cè)O(shè)置了循環(huán)次數(shù)為10次,正則化項(xiàng)為 #0.3等,具體的可以設(shè)置的參數(shù)可以通過(guò)explainParams()來(lái)獲取,還能看到我們已經(jīng)設(shè)置 #的參數(shù)的結(jié)果。 lr= LogisticRegression().setLabelCol("indexedLabel").setFeaturesCol('indexedFeatures').setMaxIter(10).setRegParam(0.3).setElasticNetParam(0.8) print("LogisticRegression parameters:\n"+ lr.explainParams()) 如圖:?
#設(shè)置一個(gè)labelConverter,目的是把預(yù)測(cè)的類別重新轉(zhuǎn)化成字符型的 labelConverter = IndexToString().setInputCol("prediction").setOutputCol("predictedLabel").setLabels(labelIndexer.labels) #構(gòu)建pipeline,設(shè)置stage,然后調(diào)用fit()來(lái)訓(xùn)練模型 LrPipeline = Pipeline().setStages([labelIndexer, featureIndexer, lr, labelConverter]) LrPipelineModel = LrPipeline.fit(trainingData) #用訓(xùn)練得到的模型進(jìn)行預(yù)測(cè),即對(duì)測(cè)試數(shù)據(jù)集進(jìn)行驗(yàn)證 lrPredictions = LrPipelineModel.transform(testData) preRel = lrPredictions.select("predictedLabel",'label','features','probability').collect() for item in preRel: print(str(item['label'])+','+str(item['features'])+'-->prob='+str(item['probability'])+',predictedLabel'+str(item['predictedLabel'])) 如圖:?
#模型評(píng)估1 #創(chuàng)建一個(gè)MulticlassClassificationEvaluator實(shí)例,用setter方法把預(yù)測(cè)分類的列名和真實(shí)分類的列名進(jìn)行設(shè)置;然后計(jì)算預(yù)測(cè)準(zhǔn)確率和錯(cuò)誤率 evaluator = MulticlassClassificationEvaluator().setLabelCol("indexedLabel").setPredictionCol("prediction") lrAccuracy = evaluator.evaluate(lrPredictions) print("Test Error=" + str(1.0- lrAccuracy)) 如圖:?
#從上面可以看到預(yù)測(cè)的準(zhǔn)確性達(dá)到94%,接下來(lái)我們可以通過(guò)model來(lái)獲取我們訓(xùn)練得到 #的邏輯斯蒂模型。前面已經(jīng)說(shuō)過(guò)model是一個(gè)PipelineModel,因此我們可以通過(guò)調(diào)用它的 #stages來(lái)獲取模型 lrModel = LrPipelineModel.stages[2] print("Coefficients: " + str(lrModel.coefficients)+"Intercept: "+str(lrModel.intercept)+"numClasses: "+str(lrModel.numClasses)+"numFeatures: "+str(lrModel.numFeatures)) 如圖:?
#模型評(píng)估2 #spark的ml庫(kù)還提供了一個(gè)對(duì)模型的摘要總結(jié)(summary),不過(guò)目前只支持二項(xiàng)邏輯斯 #蒂回歸,而且要顯示轉(zhuǎn)化成BinaryLogisticRegressionSummary?。在下面的代碼中,首 #先獲得二項(xiàng)邏輯斯模型的摘要;然后獲得10次循環(huán)中損失函數(shù)的變化,并將結(jié)果打印出來(lái) #,可以看到損失函數(shù)隨著循環(huán)是逐漸變小的,損失函數(shù)越小,模型就越好;接下來(lái),我們 #把摘要強(qiáng)制轉(zhuǎn)化為BinaryLogisticRegressionSummary,來(lái)獲取用來(lái)評(píng)估模型性能的矩陣; #通過(guò)獲取ROC,我們可以判斷模型的好壞,areaUnderROC達(dá)到了 0.969551282051282,說(shuō)明 #我們的分類器還是不錯(cuò)的;最后,我們通過(guò)最大化fMeasure來(lái)選取最合適的閾值,其中fMeasure #是一個(gè)綜合了召回率和準(zhǔn)確率的指標(biāo),通過(guò)最大化fMeasure,我們可以選取到用來(lái)分類的最合適的閾值 trainingSummary = lrModel.summary objectiveHistory = trainingSummary.objectiveHistory for item in objectiveHistory: print (item) print("areaUnderRoC:"+str(trainingSummary.areaUnderROC)) 如圖:?
fMeasure = trainingSummary.fMeasureByThreshold maxFMeasure = fMeasure.groupBy().max('F-Measure').select('max(F-Measure)').head() print(maxFMeasure) 如圖: bestThreshold = fMeasure.where(fMeasure['F-Measure'] == maxFMeasure['max(F-Measure)']).select('threshold').head()['threshold'] print(bestThreshold) lr.setThreshold(bestThreshold) #用多項(xiàng)邏輯斯蒂回歸解決 二分類 問(wèn)題 mlr = LogisticRegression().setLabelCol("indexedLabel").setFeaturesCol("indexedFeatures").setMaxIter(10).setRegParam(0.3).setElasticNetParam(0.8).setFamily("multinomial") mlrPipeline = Pipeline().setStages([labelIndexer, featureIndexer, mlr, labelConverter]) mlrPipelineModel = mlrPipeline.fit(trainingData) mlrPrediction = mlrPipelineModel.transform(testData) mlrPreRel =mlrPrediction.select("predictedLabel", "label", "features", "probability").collect() for item in mlrPreRel: print('('+str(item['label'])+','+str(item['features'])+')-->prob='+str(item['probability'])+',predictLabel='+str(item['predictedLabel'])) 如圖:?
mlrAccuracy = evaluator.evaluate(mlrPrediction) print("mlr Test Error ="+ str(1.0-mlrAccuracy)) 如圖: mlrModel = mlrPipelineModel.stages[2] print("Multinomial coefficients: " +str(mlrModel.coefficientMatrix)+"Multinomial intercepts: "+str(mlrModel.interceptVector)+"numClasses: "+str(mlrModel.numClasses)+"numFeatures: "+str(mlrModel.numFeatures)) 如圖; #用多項(xiàng)邏輯斯蒂回歸解決多分類問(wèn)題 mlrPreRel2 = mlrPrediction.select("predictedLabel", "label", "features", "probability").collect() for item in mlrPreRel2: print('('+str(item['label'])+','+str(item['features'])+')-->prob='+str(item['probability'])+',predictLabel='+str(item['predictedLabel'])) 如圖:?
mlr2Accuracy = evaluator.evaluate(mlrPrediction) print("Test Error = " + str(1.0 - mlr2Accuracy))?
mlr2Model = mlrPipelineModel.stages[2] print("Multinomial coefficients: " + str(mlrModel.coefficientMatrix)+"Multinomial intercepts: "+str(mlrModel.interceptVector)+"numClasses: "+str(mlrModel.numClasses)+"numFeatures: "+str(mlrModel.numFeatures))?
轉(zhuǎn)載于:https://www.cnblogs.com/SoftwareBuilding/p/9512653.html
總結(jié)
以上是生活随笔為你收集整理的用二项逻辑斯蒂回归解决二分类问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 从壹开始前后端分离【 .NET Core
- 下一篇: anaconda安装scrapy报错解决