基于sklearn的线性分类器

导入可能用到的Python库

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import re

目标

  • 学习机器学习算法——线性分类器
  • 使用良性/恶性乳腺癌肿瘤数据集进行预测

理论学习

线性分类器

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

logistic 函数

线性分类器输出的是一个数,我们希望这个数在区间[0,1]之间,需要一个映射关系,这个映射关系就是logistic函数$$g(x) = \cfrac{1}{1 + e^{-x}}$$下面使用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) = \cfrac{1}{1 + e{-(w{T}x+b)}}$$

优化

完成了模型的构建之后,需要对算法进行优化已确定最优的W和b参数。这时,需要一个函数用于评价现有参数的质量,这个函数应该满足以下条件

  • 连续可导(用于基于梯度的优化算法需要连续可导)
  • 当预测结果越正确时,函数取值越大;预测结果越错误时,函数取值越小(反过来也可)

对于一个logistics的线性分类器,可以将输出看做取1值的概率,那么,该分类器可以视为一个条件概率$P(y|x)$,其中w与b是分布的参数,于是我们使用最大似然估计的方法确定这个评价函数(其中y是期望输出,即正确值)$$l(w,b) = \prod ((f(w,b,x))^{y}*(1 - f(w,b,x))^{1 - y})$$

  • 是否连续可导:是
  • 当y = 0时,$l(w,b) = 1 - f(w,b,x)$,预测值越接近0,取值越大;y=1时同理

于是我们只要对$l(w,b)$进行优化,通过梯度优化的方法找到最好的w,b参数即可

代码实现

导入数据——良性/恶性乳腺癌肿瘤数据集

数据下载

data_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
data_label = """ 1. Sample code number            1id number
   2. Clump Thickness               1 - 10
   3. Uniformity of Cell Size       1 - 10
   4. Uniformity of Cell Shape      1 - 10
   5. Marginal Adhesion             1 - 10
   6. Single Epithelial Cell Size   1 - 10
   7. Bare Nuclei                   1 - 10
   8. Bland Chromatin               1 - 10
   9. Normal Nucleoli               1 - 10
  10. Mitoses                       1 - 10
  11. Class                         2 for benign, 4 for malignant)
"""
data_label = [re.sub(r"\s+\d","",x[2:]) for x in re.findall(r"\. [\w\s]+\d",data_label)]
print(data_label)
data = pd.read_csv(data_url,names=data_label)
print(data[:5],data.shape)
['Sample code numberid number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']
   Sample code numberid number  Clump Thickness  Uniformity of Cell Size  \
0                      1000025                5                        1   
1                      1002945                5                        4   
2                      1015425                3                        1   
3                      1016277                6                        8   
4                      1017023                4                        1   

   Uniformity of Cell Shape  Marginal Adhesion  Single Epithelial Cell Size  \
0                         1                  1                            2   
1                         4                  5                            7   
2                         1                  1                            2   
3                         8                  1                            3   
4                         1                  3                            2   

  Bare Nuclei  Bland Chromatin  Normal Nucleoli  Mitoses  Class  
0           1                3                1        1      2  
1          10                3                2        1      2  
2           2                3                1        1      2  
3           4                3                7        1      2  
4           1                3                1        1      2   (699, 11)

清洗数据(去除有缺失的数据)

data = data.replace(to_replace="?",value=np.nan)
data = data.dropna(how='any')
print(data.shape)
(683, 11)

切分数据集(75%训练-25%测试)

from sklearn.cross_validation import train_test_split
x_train,x_test,y_train,y_test = train_test_split(data[data_label[:10]],data[data_label[10]],test_size=0.25,random_state=1)
print(x_train.shape,x_test.shape)
print(y_train.shape,y_test.shape)
(512, 10) (171, 10)
(512,) (171,)

sklearn.cross_validation中的train_test_split()函数用于切分数据集,输入参数为:

  • 数据
  • 标签
  • test_size:0~1之间,表示测试集占总数据的比例
  • random_state:随机种子

数据标准化

from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
x_train_norm = ss.fit_transform(x_train)
x_test_norm = ss.transform(x_test)
  • StandardScalerfit_transform()函数,先计算均值与方差再标准化
  • StandardScalertransform()函数,使用fit_transform()计算出的均值方差标准化

模型建立与训练

模型建立

logistics分类器

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()

SGD分类器

from sklearn.linear_model import SGDClassifier
sgdc = SGDClassifier()
c:\users\qiank\appdata\local\programs\python\python35\lib\site-packages\sklearn\linear_model\stochastic_gradient.py:84: FutureWarning: max_iter and tol parameters have been added in <class 'sklearn.linear_model.stochastic_gradient.SGDClassifier'> in 0.19. If both are left unset, they default to max_iter=5 and tol=None. If tol is not None, max_iter defaults to max_iter=1000. From 0.21, default max_iter will be 1000, and default tol will be 1e-3.
  "and default tol will be 1e-3." % type(self), FutureWarning)

训练模型

logistics分类器

lr.fit(x_train_norm,y_train)
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)

SGD分类器

sgdc.fit(x_train_norm,y_train)
SGDClassifier(alpha=0.0001, average=False, class_weight=None, epsilon=0.1,
       eta0=0.0, fit_intercept=True, l1_ratio=0.15,
       learning_rate='optimal', loss='hinge', max_iter=5, n_iter=None,
       n_jobs=1, penalty='l2', power_t=0.5, random_state=None,
       shuffle=True, tol=None, verbose=0, warm_start=False)

模型测试

from sklearn.metrics import 

logistics分类器

print(lr.score(x_test_norm,y_test))
y_result = lr.predict(x_test_norm)
print(classification_report(y_test,y_result,target_names=['Benign','Malignant']))
0.988304093567
             precision    recall  f1-score   support

     Benign       0.98      1.00      0.99       111
  Malignant       1.00      0.97      0.98        60

avg / total       0.99      0.99      0.99       171

SGD分类器

print(sgdc.score(x_test_norm,y_test))
y_result = sgdc.predict(x_test_norm)
print(classification_report(y_test,y_result,target_names=['Benign','Malignant']))
0.970760233918
             precision    recall  f1-score   support

     Benign       0.96      1.00      0.98       111
  Malignant       1.00      0.92      0.96        60

avg / total       0.97      0.97      0.97       171
  • classification_report()用于测试准确率,精确率和召回率
  • .score()用于评估本模型的准确率
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容