用二项逻辑斯蒂回归解决二分类问题

逻辑斯蒂回归:

逻辑斯蒂回归是统计学习中的经典分类方法,属于对数线性模型。logistic回归的因变量可以是二分类的,

也可以是多分类的

基本原理
logistic 分布

折X是连续的随机变量,X服从logistic分布是指X具有下列分布函数和密度函数:

其中为位置参数,为形状参数。图像如下,其中分布函数是以为中心对阵,越小曲线变化越快

二项logistic回归模型;

二项logistic回归模型如下:

其中是输入,输出,W称为权值向量,b称为偏置, 是w和x的内积

参数估计

? 假设:

?

? 则似然函数为:

?

? 求对数似然函数:

?

?

? 从而对

求极大值,得到w的估计值。求极值的方法可以是梯度下降法,梯度上升法等。

示例代码:

#导入需要的包:

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

#用二项逻辑斯蒂回归解决 二分类 问题

sc = SparkContext(‘local‘,‘用二项逻辑斯蒂回归解决二分类问题‘)

spark = SparkSession.builder.master(‘local‘).appName(‘用二项逻辑斯蒂回归解决二分类问题‘).getOrCreate()

#读取数据,简要分析

#我们定制一个函数,来返回一个指定的数据,然后读取文本文件,第一个map把每行的数据用","

#隔开,比如在我们的数据集中,每行被分成了5部分,目前4部分是鸢尾花的四个特征,最后一部分鸢尾花的分类;

#我们这里把特征存储在Vector中,创建一个Iris模式的RDd,然后转化成DataFrame;最后调用show()方法查看数据

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()

# 因为我们现在处理的是2分类问题,所以我们不需要全部的3类数据,我们要从中选出两类的

#数据。这里首先把刚刚得到的数据注册成一个表iris,注册成这个表之后,我们就可以

#通过sql语句进行数据查询,比如我们这里选出了所有不属于“Iris-setosa”类别的数

#据;选出我们需要的数据后,我们可以把结果打印出来看一下,这时就已经没有“Iris-setosa”类别的数据

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)

如图:

  

#构建ML的pipeline

#分别获取标签列和特征列,进行索引,并进行了重命名

labelIndexer = StringIndexer().setInputCol(‘label‘).setOutputCol(‘indexedLabel‘).fit(df)

featureIndexer = VectorIndexer().setInputCol(‘features‘).setOutputCol(‘indexedFeatures‘).fit(df)

#把数据集随机分成训练集和测试集,其中训练集占70%

trainingData, testData =df.randomSplit([0.7,0.3])

#设置logistic的参数,这里我们统一用setter的方法来设置,也可以用ParamMap来设置

#(具体的可以查看spark mllib的官网)。这里我们设置了循环次数为10次,正则化项为

#0.3等,具体的可以设置的参数可以通过explainParams()来获取,还能看到我们已经设置

#的参数的结果。

lr= LogisticRegression().setLabelCol("indexedLabel").setFeaturesCol(‘indexedFeatures‘).setMaxIter(10).setRegParam(0.3).setElasticNetParam(0.8)

print("LogisticRegression parameters:\n"+ lr.explainParams())

如图:

#设置一个labelConverter,目的是把预测的类别重新转化成字符型的

labelConverter = IndexToString().setInputCol("prediction").setOutputCol("predictedLabel").setLabels(labelIndexer.labels)

#构建pipeline,设置stage,然后调用fit()来训练模型

LrPipeline = Pipeline().setStages([labelIndexer, featureIndexer, lr, labelConverter])

LrPipelineModel = LrPipeline.fit(trainingData)

#用训练得到的模型进行预测,即对测试数据集进行验证

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‘]))

如图:

#模型评估1

#创建一个MulticlassClassificationEvaluator实例,用setter方法把预测分类的列名和真实分类的列名进行设置;然后计算预测准确率和错误率

evaluator = MulticlassClassificationEvaluator().setLabelCol("indexedLabel").setPredictionCol("prediction")

lrAccuracy = evaluator.evaluate(lrPredictions)

print("Test Error=" + str(1.0- lrAccuracy))

如图:

#从上面可以看到预测的准确性达到94%,接下来我们可以通过model来获取我们训练得到

#的逻辑斯蒂模型。前面已经说过model是一个PipelineModel,因此我们可以通过调用它的

#stages来获取模型

lrModel = LrPipelineModel.stages[2]

print("Coefficients: " + str(lrModel.coefficients)+"Intercept: "+str(lrModel.intercept)+"numClasses: "+str(lrModel.numClasses)+"numFeatures: "+str(lrModel.numFeatures))

如图:

#模型评估2

#spark的ml库还提供了一个对模型的摘要总结(summary),不过目前只支持二项逻辑斯

#蒂回归,而且要显示转化成BinaryLogisticRegressionSummary 。在下面的代码中,首

#先获得二项逻辑斯模型的摘要;然后获得10次循环中损失函数的变化,并将结果打印出来

#,可以看到损失函数随着循环是逐渐变小的,损失函数越小,模型就越好;接下来,我们

#把摘要强制转化为BinaryLogisticRegressionSummary,来获取用来评估模型性能的矩阵;

#通过获取ROC,我们可以判断模型的好坏,areaUnderROC达到了 0.969551282051282,说明

#我们的分类器还是不错的;最后,我们通过最大化fMeasure来选取最合适的阈值,其中fMeasure

#是一个综合了召回率和准确率的指标,通过最大化fMeasure,我们可以选取到用来分类的最合适的阈值

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)

#用多项逻辑斯蒂回归解决 二分类 问题

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))

如图;

#用多项逻辑斯蒂回归解决多分类问题

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))

原文地址:https://www.cnblogs.com/SoftwareBuilding/p/9512653.html

时间: 2024-10-08 08:24:11

用二项逻辑斯蒂回归解决二分类问题的相关文章

第六章 逻辑斯蒂回归与最大熵模型

书中重要定义及一些理解 先通过介绍逻辑史蒂的分布来引出logist模型 而通过极大似然法来推导模型的参数估计问题 通过对模型参数的似然函数通过求导来得到递归方程 通过公式可以看出logist是对前面的感知机的升级版,感知机的判断方式过于简单.而其梯度下降的时候也将sign的去掉了,否则无法微分. 后通过方程来写出公式,代码如下 import numpy as np from read_data import get_2_kind_data def logistic_Regression(tra_

逻辑斯蒂回归(logisic regression)和SVM的异同

逻辑斯蒂回归主要用于二分类,推广到多分类的话是类似于softmax分类.求 上述问题可以通过最大化似然函数求解. 上述问题可以采用最小化logloss进行求解. 一般地,我们还需要给目标函数加上正则项,参数w加上l1或者l2范数. LR适合大规模数据,数据量太小的话可能会欠拟合(考虑到数据通常比较稀疏).另外,我们可以将连续型属性转化成离散型属性,这样可以提升模型的鲁棒性,防止模型过拟合. LR和SVM的异同点 相同点 1.他们都是分类算法,是监督学习算法. 2.如果不考虑核函数,LR和SVM都

逻辑斯蒂回归

1,逻辑斯蒂回归问题有一组病人的数据,我们需要预测他们在一段时间后患上心脏病的“可能性”,就是我们要考虑的问题.通过二值分类,我们仅仅能够预测病人是否会患上心脏病,不同于此的是,现在我们还关心患病的可能性,即 f(x) = P(+1|x),取值范围是区间 [0,1]. 然而,我们能够获取的训练数据却与二值分类完全一样,x 是病人的基本属性,y 是+1(患心脏病)或 -1(没有患心脏病).输入数据并没有告诉我们有关“概率” 的信息. 在二值分类中,我们通过w*x 得到一个"score"

梯度下降法解逻辑斯蒂回归

梯度下降法解逻辑斯蒂回归 本文是Andrew Ng在Coursera的机器学习课程的笔记. Logistic回归属于分类模型.回顾线性回归,输出的是连续的实数,而Logistic回归输出的是[0,1]区间的概率值,通过概率值来判断因变量应该是1还是0.因此,虽然名字中带着"回归"(输出范围常为连续实数),但Logistic回归属于分类模型(输出范围为一组离散值构成的集合). 整体步骤 假如我们的自变量是"数学课和英语课的成绩",x={x1,x2},因变量是"

逻辑斯蒂回归(Logistic Regression)

逻辑回归名字比较古怪,看上去是回归,却是一个简单的二分类模型. 逻辑回归的目标函数是如下形式: 其中x是features,θ是feature的权重,σ是sigmoid函数.将θ0视为θ0*x0(x0取值为常量1),那么 这里我们取阈值为0.5,那么二分类的判别公式为: 下面说一下参数θ的求解: 为啥子这样去损失函数呢? 当y=1的时候,显然hθ(x)越接近1我们的预测越靠谱:y=0时同理.所以应该在y=1时,使损失韩式-log(hθ(x))越小越好,y=0时,同样使损失函数-log(1-hθ(x

逻辑斯蒂回归模型

http://blog.csdn.net/hechenghai/article/details/46817031 主要参照统计学习方法.机器学习实战来学习.下文作为参考. 第一节中说了,logistic 回归和线性回归的区别是:线性回归是根据样本X各个维度的Xi的线性叠加(线性叠加的权重系数wi就是模型的参数)来得到预测值的Y,然后最小化所有的样本预测值Y与真实值y‘的误差来求得模型参数.我们看到这里的模型的值Y是样本X各个维度的Xi的线性叠加,是线性的. Y=WX (假设W>0),Y的大小是随

[转]逻辑斯蒂回归 via python

# -*- coding:UTF-8 -*-import numpydef loadDataSet(): return dataMat,labelMat def sigmoid(inX): return 1.0/(1+numpy.exp(-inX)) def gradAscent(dataMatIn,classLabels): dataMatrix=numpy.mat(damaMatIn) labelMat=numpy.mat(classLabels).transpose() #上升梯度 alp

《统计学习方法》第六章,逻辑斯蒂回归

? 使用逻辑地模型来进行分类,可以算出每个测试样本分属于每个类别的概率 ● 二分类代码 1 import numpy as np 2 import matplotlib.pyplot as plt 3 from mpl_toolkits.mplot3d import Axes3D 4 from mpl_toolkits.mplot3d.art3d import Poly3DCollection 5 from matplotlib.patches import Rectangle 6 7 data

Spark 二项逻辑回归__二分类

package Spark_MLlib import org.apache.spark.ml.Pipeline import org.apache.spark.ml.classification.{BinaryLogisticRegressionSummary, LogisticRegression, LogisticRegressionModel} import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator i