python logistic 多标签_用python实现Logistic

python实现

#算法一 调用sklearn里面的方法

# _*_ encoding:utf-8 _*_

from matplotlib import pyplot

import scipy as sp

import numpy as np

from matplotlib import pylab

from sklearn.cross_validation import train_test_split

from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.metrics import precision_recall_curve

from sklearn.metrics import classification_report

from sklearn.linear_model import LogisticRegression

import time

start_time=time.time()

#绘制R/p曲线

def plot_pr(auc_score,precision,recall,label=None):

pylab.figure(num=None, figsize=(6, 5))

pylab.xlim([0.0, 1.0])

pylab.ylim([0.0, 1.0])

pylab.xlabel("Recall")

pylab.ylabel("Precision")

pylab.title("P/R (AUC=%0.2f) / %s" % (auc_score, label))

pylab.fill_between(recall, precision, alpha=0.5)

pylab.grid(True, linestyle="-", color="0.75")

pylab.plot(recall, precision, lw=1)

pylab.show()

#读取

movie_data=sp.load("move_data.npy")

movie_target=sp.load("move_target.npy")

x=movie_data

y=movie_target

#向量空间模型,

count_vec = TfidfVectorizer(binary = False, decode_error = "ignore",\

stop_words = "english")

average = 0

testNum = 10

#注意,训练样本调用fit_transform接口,测试样本调用的是transform接口

for i in range(0,testNum):

#加载数据集,切分数据集80%训练,20%测试

x_train, x_test, y_train, y_test\

= train_test_split(movie_data, movie_target, test_size = 0.2)

x_train = count_vec.fit_transform(x_train)

x_test = count_vec.transform(x_test)

#训练LR分类器

clf=LogisticRegression()

clf.fit(x_train,y_train)

y_pred=clf.predict(x_test)

p=np.mean(y_pred==y_test)

print "第%d次测试的准确率为:%.5f"%(i,p)

average+=p

#精确率与召回率

#answer = clf.predict_proba(x_test)[:,0]#属于第neg类的概率

answer = clf.predict_proba(x_test)[:,1]#属于第pos类的概率

#这个地方可以查看官方文档,

precision, recall, thresholds = precision_recall_curve(y_test, answer)

#thresholds对应着一个向量,个数为answer中不重复的值的个数,每个位置上的值对应着一个threshold,并且是越来越大

#precision 和recall也是一个向量,个数比thresholds多一个,precision最后一个为1,recall最后一个值为0,确保图像从x轴=0开始

#precision每个值对应着,当阈值为thresholds对应位置值的时候的准确度

#例如:当取值取thresholds[0]的时候,precision[0]表示所有的训练集所对应的准确率recall[0]表示召回率

report = answer > 0.5#这里的0.5可以换为其他值

#我们通常使用0.5来划分两类数据,但是我们可以根据P/R图分析,选择一个合适的优秀的阈值。

#print report

print(classification_report(y_test, report, target_names = ["neg", "pos"]))

print("平均精确度为:", average/testNum)

print("花费的时间为:", time.time() - start_time)

plot_pr(0.6, precision, recall, "pos")

实验结果:

第0次测试的准确率为:0.81071

第1次测试的准确率为:0.79643

第2次测试的准确率为:0.79643

第3次测试的准确率为:0.80000

第4次测试的准确率为:0.80714

第5次测试的准确率为:0.81071

第6次测试的准确率为:0.75714

第7次测试的准确率为:0.78214

第8次测试的准确率为:0.78214

第9次测试的准确率为:0.81429

precision recall f1-score support

neg 0.84 0.79 0.81 145

pos 0.79 0.84 0.81 135

avg / total 0.82 0.81 0.81 280

平均精度率为: 0.795714285714

花费时间为: 12.1490001678

通过上图可以看出,如果选择的阈值过低,那么更多的测试样本都将分为1类,因此召回率得到提升,但是要牺牲相应的准确率。 注意precision_recall_curve()方法中的thresholds中的阈值是逐渐增大的,对应到图像是就会,x轴从左到右对应的阈值是逐渐减小的。

# -*- encoding:utf-8 -*-

import matplotlib.pyplot as plt

from matplotlib import animation

import numpy as np

#加载数据集

def loadDataSet():

"""

:return: 输入向量矩阵和输出向量

"""

dataMat=[]

labelMat=[]

fr=open("test.txt","r")#一共有三列,每一列为x1,x2,Y

for line in fr.readlines():

lineArr=line.strip().split("##")

#注意在这里将字符串转换成float型的时候总是遇到问题

#感觉每一行的开头存在其他字符,所以我们多添加了一列"##"分隔符,是的第一个有效数字从第二个开始

dataMat.append([1.0,float(lineArr[1]),float(lineArr[2])])#设x0为1,构成拓展之后的输入向量

labelMat.append(int(lineArr[3]))

return dataMat,labelMat

#可视化数据,画出数据集合逻辑斯蒂最佳回归直线

def plotBestFit(weights):

dataMat,labelMat=loadDataSet()

dataArr=np.array(dataMat)

n=dataArr.shape[0]

x1=[]

y1=[]

x2=[]

y2=[]

for i in range(n):

if int(labelMat[i])==1:

x1.append(dataArr[i,1])

y1.append(dataArr[i,2])

else:

x2.append(dataArr[i,1])

y2.append(dataArr[i,2])

fig=plt.figure()

ax=fig.add_subplot(111)

ax.scatter(x1,y1,s=30,c="red",marker="s")

ax.scatter(x2,y2,s=30,c="green",)

if weights is not None:

x=np.arange(-3.0,3.0,0.1)

y=(-weights[0]-weights[1]*x)/weights[2]# #令w0*x0 + w1*x1 + w2*x2 = 0,其中x0=1,解出x1和x2的关系

ax.plot(x,y)

plt.xlabel("X1")

plt.ylabel("X2")

plt.show()

def sigmoid(inX):

return 1.0/(1+np.exp(-inX))

#逻辑斯提回归梯度上升批量算法,静态展示

def gradAscent_static(dataMatIn,classLabels):

"""

:param dataMatIn: 输入X矩阵,每一行代表一个实例,每一列分别是x0,x1,x2

:param classLabels: 类别标签组成的向量

:return: 权值向量

"""

dataMatrix=np.mat(dataMatIn)#转换为numpy矩阵数据类型,(100,3)

labelMat=np.mat(classLabels).transpose()#转换为numpy矩阵数据类型,(100,1)

m,n=dataMatrix.shape

alpha=0.001

maxCycles=500

weights=np.ones((n,1))#(3,1)

for k in range(maxCycles):

h=sigmoid(dataMatrix*weights)

error=(labelMat-h)#向量减法

weights+=alpha*dataMatrix.transpose()*error#矩阵内积

return weights

def draw_line(weights,lines):

x = np.arange(-5.0, 5.0, 0.1)

y = (-weights[0]-weights[1]*x)/weights[2] #令w0*x0 + w1*x1 + w2*x2 = 0,其中x0=1,解出x1和x2的关系

lines.set_data(x, y)

return lines

def main1():#实现批量梯度上升,展示静态图像

datas,labels=loadDataSet()

weights=gradAscent_static(datas,labels)

plotBestFit(weights)#静态图

if __name__ == "__main__":

main1()

实验结果:

最终得到的权重向量为: [[ 4.12414349]

[ 0.48007329]

[-0.6168482 ]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值