基于sklearn的线性分类器logistics(对数几率回归)Python实现


声明:本人小白,文章作为自己的学习参考资料,供大家学习交流
本文章 refer to

作者:月见樽 链接:https://www.jianshu.com/p/f9cb59dc99ec 来源:简书
作者: 周志华 书名:《机器学习》 出版社:清华大学出版社

感谢此文章及书籍原创者
如有侵犯您的知识产权和版权问题,请通知本人,本人会即时做出处理并删除文章

Email:louhergetup@163.com

理论部分

线性分类器

特征与分类结果存在线性关系的模型为线性分类器,模型通过累积特征和对应权值的方式决策,几何学上可看成一个n维空间中的超平面,学习的过程就是不断调整超平面的位置与倾斜程度,使该超平面可以最完美的将属于不同类别的特征点区分开,公式为: f ( w , x , b ) = w T x + b f(w,x,b) = w^{T}x+b f(w,x,b)=wTx+b

logistic 函数

线性分类器输出的是一个数,我们希望这个数在区间[0,1]之间,需要一个映射关系,这个映射关系就是logistic函数 g ( x ) = 1 1 + e − x g(x) = \cfrac{1}{1 + e^{-x}} g(x)=1+ex1下面使用numpy和matplot绘制该函数的图像

x = np.linspace(start=-10,stop=10,num=1000)
y = 1 / (1 + np.exp(-x))
plt.plot(x,y)
plt.show()

logistics.png
将线性分类器公式带入logistics函数后,可得logistics回归模型 f ( x , w , b ) = 1 1 + e − ( w T x + b ) f(x,w,b) = \cfrac{1}{1 + e{-(w{T}x+b)}} f(x,w,b)=1+e(wTx+b)1

对数几率回归

对数几率回归实际上是在用线性回归模型的预测结果去逼近真实的对数几率,特别需要注意的是虽然他的名字是“回归”,但实际上却是一种分类学习的方法,这种方法的优点有很多,例如:

  • 它是直接对分类可能性进行建模,无需事先假设数据分布,这样就避免了假设分布不准所带来的问题;
  • 它不是仅预测“类别”,而是可得到近似概率预测,这对许多需利用概率辅助决策的任务很有用;
  • 对率回归求解的目标函数是任意阶可导的凸函数,有很好的数学性质,现有的许多数值化算法都可直接用于求解最优解。

使用python实现logistics

实验环境

  • 操作系统:win10 64
  • 编程语言:Python3.7.3

导入Python库

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import re
import csv
from sklearn.feature_extraction import DictVectorizer

数据源

我们用买电脑的例子作为数据源
在这里插入图片描述
在这里插入图片描述

将这些数据记录保存成.csv文件:

RID,age,income,student,credit_rating,class:buys_computer
1,youth,hight,no,fair,no
2,youth,hight,no,excellent,no
3,middle_aged,hight,no,fair,yes
4,senior,medium,no,fair,yes
5,senior,low,yes,fair,yes
6,senior,low,yes,excellent,no
7,middle_aged,low,yes,excellent,yes
8,youth,medium,no,fair,no
9,youth,low,yes,fair,yes
10,senior,medium,yes,fair,yes
11,youth,medium,yes,excellent,yes
12,middle_aged,medium,no,excellent,yes
13,middle_aged,hight,yes,fair,yes
14,senior,medium,no,excellent,no

这些数据即我们这次应用的数据源

数据整理

利用python标准库中csv对这个数据源进行读取
整理原始数据集,把随机变量放在一个数组,分类结果放到另一个数组,形如:

future_list = [
    {
        "age"   : "youth",
        "income": "hight",
        ...
    }
    ...
]
​
answer_list = ["no", "no", "yes", ...]

按照这个思路我们构造一下:

data_file = open("computer_buy.csv", "r")
reader = csv.reader(data_file)
headers = next(reader)

future_list = []
label_list = []

for row in reader:
    label_list.append(row[-1])
    row_dict = {}
    for i in range(1, len(row) - 1):
        row_dict[headers[i]] = row[i]
    future_list.append(row_dict)
data_file.close()

随机变量向量化

在 sklearn 提供的库中,对输入的特征有一定的要求,所有特征和分类都要是数值型的值,不能是例子中的类别的值。

怎么转化呢? 比方说 age 这个特征,它有三个值: youth , middle_aged , senior 。有一条记录的 age=youth 针对这个特征我们就变成:

youthmiddle_agedsenior
100

那么第一条记录 youth,hight,no,fair 转化为:

age=middle_agedage=seniorage=youthcredit_rating=excellentcredit_rating=faircredit_rating=fairincome=lowincome=mediumstudent=nostudent=yes
0010110010

特征向量化

vec = DictVectorizer()
dummy_x = vec.fit_transform(future_list).toarray()

print("dummy_x:", dummy_x)
print("vec.get_feature_names()", vec.get_feature_names())

特征向量化结果

dummy_x: [[0. 0. 1. 0. 1. 1. 0. 0. 1. 0.]
 [0. 0. 1. 1. 0. 1. 0. 0. 1. 0.]
 [1. 0. 0. 0. 1. 1. 0. 0. 1. 0.]
 [0. 1. 0. 0. 1. 0. 0. 1. 1. 0.]
 [0. 1. 0. 0. 1. 0. 1. 0. 0. 1.]
 [0. 1. 0. 1. 0. 0. 1. 0. 0. 1.]
 [1. 0. 0. 1. 0. 0. 1. 0. 0. 1.]
 [0. 0. 1. 0. 1. 0. 0. 1. 1. 0.]
 [0. 0. 1. 0. 1. 0. 1. 0. 0. 1.]
 [0. 1. 0. 0. 1. 0. 0. 1. 0. 1.]
 [0. 0. 1. 1. 0. 0. 0. 1. 0. 1.]
 [1. 0. 0. 1. 0. 0. 0. 1. 1. 0.]
 [1. 0. 0. 0. 1. 1. 0. 0. 0. 1.]
 [0. 1. 0. 1. 0. 0. 0. 1. 1. 0.]]

分类结果向量化

from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
dummy_y = lb.fit_transform(label_list)

模型建立

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()

模型训练

lr.fit(dummy_x, dummy_y)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
          verbose=0, warm_start=False)

模型测试

from sklearn.metrics import classification_report
#测试数据
first_row = dummy_x[0, :]
new_row = list(first_row)
new_row[0] = 1
new_row[2] = 0

print(lr.score(dummy_x,dummy_y))
y_result = lr.predict(dummy_x)
print(classification_report(dummy_y, y_result, target_names=['NO', 'YES']))
0.8571428571428571
              precision    recall  f1-score   support

          NO       1.00      0.60      0.75         5
         YES       0.82      1.00      0.90         9

   micro avg       0.86      0.86      0.86        14
   macro avg       0.91      0.80      0.82        14
weighted avg       0.88      0.86      0.85        14
  • classification_report()用于测试准确率,精确率和召回率
  • .score()用于评估本模型的准确率
  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LouHerGetUp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值