Scikit-learn学习

 

目录

一,安装

二、数据的特征提取

1、字典特征提取

2、文本特征提取

3、数据的特征处理

4、缺失值的处理

5、特征降维

三、数据集

四、分类算法

1、K近邻算法

2、朴素贝叶斯算法

模型的选择与调优

3、决策树

4、随机森林

5、逻辑回归

五、回归算法

1、线性回归

欠拟合与过拟合

回归算法之岭回归

保存模型与载入模型

2、逻辑回归

六、非监督学习-聚类K-Means


 

一,安装

pip3 install Scikit-learn

 

二、数据的特征提取

  • 特征提取针对非连续型数据
  • 特征提取对文本等进行特征值化

特征提取API:sklearn.feature_extraction

1、字典特征提取

sklearn.feature_extraction.DictVectorizer

from sklearn.feature_extraction import DictVectorizer

dict = DictVectorizer(sparse=False)

data = dict.fit_transform(
    [{'name': 'Bob', 'age': 12, 'gender': 'male'}, {'name': 'Lucy', 'age': 15, 'gender': 'female'}])

print(dict.get_feature_names())
print(dict.inverse_transform(data))

print(data)

['age', 'gender=female', 'gender=male', 'name=Bob', 'name=Lucy']
[{'age': 12.0, 'gender=male': 1.0, 'name=Bob': 1.0}, {'age': 15.0, 'gender=female': 1.0, 'name=Lucy': 1.0}]
[[12.  0.  1.  1.  0.]
 [15.  1.  0.  0.  1.]] 

#特征分布采用了one-hot编码

  • DictVectorizer.fit_transform(X)       
    • X:字典或者包含字典的迭代器
    • 返回值:返回sparse矩阵
  • DictVectorizer.inverse_transform(X)
    • X:array数组或者sparse矩阵
    • 返回值:转换之前数据格式
  • DictVectorizer.get_feature_names()
    • 返回类别名称
  • DictVectorizer.transform(X)
    • 按照原先的标准转换

 

2、文本特征提取

sklearn.feature_extraction.text.CountVectorizer

  • CountVectorizer(max_df=1.0,min_df=1,…)
    • 返回词频矩阵
    • CountVectorizer.fit_transform(X,y)       
      • X:文本或者包含文本字符串的可迭代对象
      • 返回值:返回sparse矩阵
    • CountVectorizer.inverse_transform(X)
      • X:array数组或者sparse矩阵
    • 返回值:转换之前数据格式

    • CountVectorizer.get_feature_names()
      • 返回值:单词列表

使用方法:

  1. 实例化类CountVectorizer
  2. 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组
from sklearn.feature_extraction.text import CountVectorizer

tc = CountVectorizer()
data = tc.fit_transform(['声明 一个 变量 的 方法', '定义 一个 函数 的 方法'])
print(tc.get_feature_names())

print(data)
print('-' * 10)
print(data.toarray())

print(type(data))

['一个', '函数', '变量', '声明', '定义', '方法']
  (0, 5)    1
  (0, 2)    1
  (0, 0)    1
  (0, 3)    1
  (1, 1)    1
  (1, 4)    1
  (1, 5)    1
  (1, 0)    1
----------
[[1 0 1 1 0 1]
 [1 1 0 0 1 1]]
<class 'scipy.sparse.csr.csr_matrix'>

特征值的分割是以字符数的空格为分割点做分割。单个字符(英文的单个字母、中文单字、标点)不会作为特征值,。 

from sklearn.feature_extraction.text import CountVectorizer
import jieba

c1 = jieba.cut('当前出现的问题,表面上是孩子为上学而纠结的问题,其实是这个家出现了问题。比如,家庭成员之间的沟通不顺畅,家人之间的爱没有流动,而且不是一天两天构成的,是许许多多个日子堆积起来的。')

c2 = jieba.cut(
    '追根求源,是夫妻之间的不和谐。遇事的时候,双方相互抱怨。孩子不上学了,我埋怨孩子爸爸教育方式简单粗暴、冷酷无情,他埋怨我对孩子没原则、没底线、没要求。仔细想来,这些埋怨竟然都是对的。孩子夹在中间,他不明白该往哪里去,他生活在撕扯中,他痛苦不堪!')

c3 = jieba.cut('问题一股脑儿地出现的时候,人会感到痛苦不堪,但这时恰恰是该长长吐口气的时候了!憋屈了那么久,装了那么久,是该释放的时候了,声嘶力竭地吵一架、狗血喷头地骂一场,感觉真好!')

cot1 = list(c1)
cot2 = list(c2)
cot3 = list(c3)

c1 = ' '.join(cot1)
c2 = ' '.join(cot2)
c3 = ' '.join(cot3)

cv = CountVectorizer()
data = cv.fit_transform([c1,c2,c3])

print(cv.get_feature_names())
print(data.toarray())

['一场', '一天两天', '一架', '一股脑儿', '上学', '不是', '中间', '之间', '人会', '仔细', '其实', '冷酷无情', '出现', '原则', '双方', '口气', '和谐', '哪里', '地吵', '地骂', '埋怨', '堆积起来', '声嘶力竭', '夫妻', '孩子', '家人', '家庭成员', '底线', '当前', '恰恰', '想来', '感到', '感觉', '憋屈', '抱怨', '撕扯', '教育', '方式', '日子', '时候', '明白', '构成', '比如', '沟通', '没有', '流动', '爸爸', '狗血喷头', '生活', '痛苦不堪', '相互', '竟然', '简单', '粗暴', '纠结', '而且', '表面', '要求', '许许多多', '该往', '这个', '这些', '这时', '追根求源', '遇事', '那么', '释放', '长长', '问题', '顺畅']
[[0 1 0 0 1 1 0 2 0 0 1 0 2 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0
  0 0 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 0 0 3 1]
 [0 0 0 0 1 0 1 1 0 1 0 1 0 1 1 0 1 1 0 0 3 0 0 1 4 0 0 1 0 0 1 0 0 0 1 1
  1 1 0 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0]
 [1 0 1 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0
  0 0 0 3 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 1 1 1 0]]

 

TF-IDF:sklearn.feature_extraction.text.TfidfVectorizer

逆向文件频率(inverse document frequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到.

TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

  • TfidfVectorizer(stop_words=None,…)
    • 返回词的权重矩阵
    • TfidfVectorizer.fit_transform(X,y)       
      • X:文本或者包含文本字符串的可迭代对象
      • 返回值:返回sparse矩阵
    • TfidfVectorizer.inverse_transform(X)
      • X:array数组或者sparse矩阵
    • 返回值:转换之前数据格式

    • TfidfVectorizer.get_feature_names()
      • 返回值:单词列表
from sklearn.feature_extraction.text import TfidfVectorizer
tf = TfidfVectorizer()
data = tf.fit_transform([c1,c2,c3])

print(tf.get_feature_names())
print(data.toarray())

['一场', '一天两天', '一架', '一股脑儿', '上学', '不是', '中间', '之间', '人会', '仔细', '其实', '冷酷无情', '出现', '原则', '双方', '口气', '和谐', '哪里', '地吵', '地骂', '埋怨', '堆积起来', '声嘶力竭', '夫妻', '孩子', '家人', '家庭成员', '底线', '当前', '恰恰', '想来', '感到', '感觉', '憋屈', '抱怨', '撕扯', '教育', '方式', '日子', '时候', '明白', '构成', '比如', '沟通', '没有', '流动', '爸爸', '狗血喷头', '生活', '痛苦不堪', '相互', '竟然', '简单', '粗暴', '纠结', '而且', '表面', '要求', '许许多多', '该往', '这个', '这些', '这时', '追根求源', '遇事', '那么', '释放', '长长', '问题', '顺畅']
[[0.         0.18260587 0.         0.         0.13887647 0.18260587
  0.         0.27775294 0.         0.         0.18260587 0.
  0.27775294 0.         0.         0.         0.         0.
  0.         0.         0.         0.18260587 0.         0.
  0.13887647 0.18260587 0.18260587 0.         0.18260587 0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.18260587 0.         0.         0.18260587
  0.18260587 0.18260587 0.18260587 0.18260587 0.         0.
  0.         0.         0.         0.         0.         0.
  0.18260587 0.18260587 0.18260587 0.         0.18260587 0.
  0.18260587 0.         0.         0.         0.         0.
  0.         0.         0.41662942 0.18260587]
 [0.         0.         0.         0.         0.11144747 0.
  0.14654002 0.11144747 0.         0.14654002 0.         0.14654002
  0.         0.14654002 0.14654002 0.         0.14654002 0.14654002
  0.         0.         0.43962007 0.         0.         0.14654002
  0.44578986 0.         0.         0.14654002 0.         0.
  0.14654002 0.         0.         0.         0.14654002 0.14654002
  0.14654002 0.14654002 0.         0.11144747 0.14654002 0.
  0.         0.         0.         0.         0.14654002 0.
  0.14654002 0.11144747 0.14654002 0.14654002 0.14654002 0.14654002
  0.         0.         0.         0.14654002 0.         0.14654002
  0.         0.14654002 0.         0.14654002 0.14654002 0.
  0.         0.         0.         0.        ]
 [0.19266144 0.         0.19266144 0.19266144 0.         0.
  0.         0.         0.19266144 0.         0.         0.
  0.14652399 0.         0.         0.19266144 0.         0.
  0.19266144 0.19266144 0.         0.         0.19266144 0.
  0.         0.         0.         0.         0.         0.19266144
  0.         0.19266144 0.19266144 0.19266144 0.         0.
  0.         0.         0.         0.43957198 0.         0.
  0.         0.         0.         0.         0.         0.19266144
  0.         0.14652399 0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.19266144 0.         0.         0.38532289
  0.19266144 0.19266144 0.14652399 0.        ]]
 

3、数据的特征处理

特征处理:通过特定的统计方法(数学方法)将数据转换成算法要求的数据

  • 数值型数据:标准缩放:

            1、归一化

            2、标准化

            3、缺失值

  • 类别型数据:one-hot编码
  • 时间类型:时间的切分

特征处理API:

sklearn. preprocessing 

归一化:X=[(x-min)/(max-min)] * (mx - mi) + mi

注:作用于每一列,max为一列的最大值,min为一列的最小值,那么X’’为最终结果,mx,mi分别为指定区间值默认mx为1,mi为0

特点:通过对原始数据进行变换把数据映射到(默认为[0,1])之间

sklearn归一化API:  sklearn.preprocessing.MinMaxScaler

  • MinMaxScalar(feature_range=(0,1)…)
    • 每个特征缩放到给定范围(默认[0,1])
    • MinMaxScalar.fit_transform(X)       
      • X:numpy array格式的数据[n_samples,n_features]
      • 返回值:转换后的形状相同的array

使用:

1、实例化MinMaxScalar

2、通过fit_transform转换

from sklearn.preprocessing import MinMaxScaler

mm = MinMaxScaler(feature_range=(4,5))
data = mm.fit_transform([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
print(data)

[[5.         4.         4.         4.        ]
 [4.         5.         5.         4.83333333]
 [4.5        4.5        4.6        5.        ]]  

总结:

注意在特定场景下最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。

标准化:X=(x-mean)/σ

σ为标准差,mean为平均值

方差s^2=[(x1-x)^2+(x2-x)^2+......(xn-x)^2]/(n)(x为平均数)

标准差=方差的算术平方根errorbar

特点:通过对原始数据进行变换把数据变换到均值为0,方差为1范围内 

对比归一化:

对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然

会发生改变

对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对

于平均值的影响并不大,从而方差改变较小。

API:sklearn特征化API:  scikit-learn.preprocessing.StandardScaler

  • StandardScaler(…)
    • 处理之后每列来说所有数据都聚集在均值0附近方差为1
    • StandardScaler.fit_transform(X,y)       
      • X:numpy array格式的数据[n_samples,n_features]
      • 返回值:转换后的形状相同的array
      • StandardScaler.mean_
        • 原始数据中每列特征的平均值
      • StandardScaler.std_
        • 原始数据每列特征的方差

使用:

1、实例化StandardScaler

2、通过fit_transform转换

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
data = ss.fit_transform([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
print(data)

[[ 1.22474487 -1.22474487 -1.29777137 -1.3970014 ]
 [-1.22474487  1.22474487  1.13554995  0.50800051]
 [ 0.          0.          0.16222142  0.88900089]]

总结:

在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。 

 

4、缺失值的处理

(1)处理方法

        删除:如果每列或者行数据缺失值达到一定的比例,建议放弃整行或者整列

        插补:可以通过缺失值每行或者每列的平均值、中位数来填充

(2)处理API: sklearn.preprocessing.Imputer

  • Imputer(missing_values='NaN'strategy='mean'axis=0)
    • 完成缺失值插补
    • Imputer.fit_transform(X,y)       
      • X:numpy array格式的数据[n_samples,n_features]
      • 返回值:转换后的形状相同的array

(3)使用流程

  1. 初始化Imputer,指定”缺失值”,指定填补策略,指定行或列(注:缺失值也可以是别的指定要替换的值)
  2. 调用fit_transform
from sklearn.preprocessing import Imputer
import numpy as np

im = Imputer(missing_values='NaN', strategy='mean', axis=0)

data = im.fit_transform([[np.nan, 12], [np.nan, 73], [72, 26]])

print(data)

[[72. 12.]
 [72. 73.]
 [72. 26.]] 

 Class Imputer is deprecated; Imputer was deprecated in version 0.20 and will be removed in 0.22

所以使用上需要用 impute.SimpleImputer 来替换 Imputer

from sklearn.impute import SimpleImputer
import numpy as np

im = SimpleImputer(missing_values=np.nan, strategy='mean')

data = im.fit_transform([[np.nan, 12], [np.nan, 73], [72, 26]])

print(data)

[[72. 12.]
 [72. 73.]
 [72. 26.]] 

(4)nan/Nan

  1.  numpy的数组中可以使用np.nan/np.NaN来代替缺失值,属于float类型
  2. 如果是文件中的一些缺失值,可以替换成nan,通过np.array转化成float型的数组即可

5、特征降维

1、特征选择

冗余:部分特征的相关度高,容易消耗计算性能

噪音:部分特征对预测结果有负影响

特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后可以改变值、也不改变值,但是选择后的特征维数肯定比选择前小,毕竟我们只选择了其中的一部分特征。

主要方法(三大武器):Filter(过滤式):VarianceThreshold

                                       Embedded(嵌入式):正则化、决策树

                                       Wrapper(包裹式)

特征选择API:sklearn.feature_selection.VarianceThreshold

顾名思义就是通过给定方差范围来进行过滤

  • VarianceThreshold(threshold = 0.0)
    • 删除所有低方差特征
    • Variance.fit_transform(X,y)       
      • X:numpy array格式的数据[n_samples,n_features]
      • 返回值:训练集差异低于threshold的特征将被删除。
      • 默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。

使用流程:

  1. 初始化VarianceThreshold,指定阀值方差(范围一般在0到10之间)
  2. 调用fit_transform

 

from sklearn.feature_selection import VarianceThreshold

var = VarianceThreshold(threshold=1)
data = var.fit_transform([[9, 1, 2, 5], [9, 2, 2, 1], [9, 3, 2, 9]])
print(data)

[[5]
 [1]
 [9]]

2、特征降维 

PCA(principal Component Analysis)主成分分析方法

本质:PCA是一种分析、简化数据集的技术

目的:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。

作用:可以削减回归分析或者聚类分析中特征的数量

高维度数据容易出现的问题:特征之间通常是线性相关的

  • PCA(n_components=None)
    • 将数据分解为较低维数空间
    • PCA.fit_transform(X)       
      • X:numpy array格式的数据[n_samples,n_features]
      • 返回值:转换后指定维度的array

使用流程:

  1. 初始化PCA,指定减少后的维度
  2. 调用fit_transform
from sklearn.decomposition import PCA

pa = PCA(n_components=0.9)  # 一般在0.9-0.95之间(保留特征百分比)
data = pa.fit_transform([[12,11,16,2],[15,2,9,1],[1,6,7,21]])
print(data)

[[-7.57623708  5.99449456]
 [-8.2972636  -5.81567566]
 [15.87350068 -0.1788189 ]]

三、数据集

数据集的划分:

训练数据:用于训练,构建模型

测试数据:在模型检验时使用,用于评估模型是否有效

划分数据集API:sklearn.model_selection.train_test_split

数据集API:

1)datasets.load_*()

获取小规模数据集,数据包含在datasets里

(2)datasets.fetch_*()

获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是 ~/scikit_learn_data/,要修改默认目录,可以修改环境变量SCIKIT_LEARN_DATA

(3)datasets.make_*()

本地生成数据集

load*和 fetch* 函数返回的数据类型是 datasets.base.Bunch,本质上是一个 dict,它的键值对可用通过对象的属性方式访问。主要包含以下属性:

 

  • load*和fetch*返回的数据类型datasets.base.Bunch(字典格式)
  • data:特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
  • target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
  • target_names:标签名,回归数据集没有
  • feature_names:特征名,新闻数据,手写数字、回归数据集没有
  • DESCR:数据描述

数据集目录可以通过datasets.get_data_home()获取,clear_data_home(data_home=None)删除所有下载数据

  • datasets.get_data_home(data_home=None)

返回scikit学习数据目录的路径。这个文件夹被一些大的数据集装载器使用,以避免下载数据。默认情况下,数据目录设置为用户主文件夹中名为“scikit_learn_data”的文件夹。或者,可以通过“SCIKIT_LEARN_DATA”环境变量或通过给出显式的文件夹路径以编程方式设置它。'〜'符号扩展到用户主文件夹。如果文件夹不存在,则会自动创建。

  • sklearn.datasets.clear_data_home(data_home=None)

删除存储目录中的数据

 

from sklearn.datasets import load_iris

li = load_iris()
#特征值
print(li.data)
#目标值
print(li.target)
#数据描述
print(li.DESCR)
#分类名
print(li.target_names)

[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]
... ...
 [6.3 2.5 5.  1.9]
 [6.5 3.  5.2 2. ]
 [6.2 3.4 5.4 2.3]
 [5.9 3.  5.1 1.8]]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
.. _iris_dataset:

Iris plants dataset
--------------------

**Data Set Characteristics:**

    :Number of Instances: 150 (50 in each of three classes)
    :Number of Attributes: 4 numeric, predictive attributes and the class
    :Attribute Information:
        - sepal length in cm
        - sepal width in cm
        - petal length in cm
        - petal width in cm
... ...
    :Summary Statistics:

    ============== ==== ==== ======= ===== ====================
                    Min  Max   Mean    SD   Class Correlation
    ============== ==== ==== ======= ===== ====================
    sepal length:   4.3  7.9   5.84   0.83    0.7826
    sepal width:    2.0  4.4   3.05   0.43   -0.4194
    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)
    petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)
    ============== ==== ==== ======= ===== ====================

    :Missing Attribute Values: None
    :Class Distribution: 33.3% for each of 3 classes.
    :Creator: R.A. Fisher
    :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
    :Date: July, 1988

The famous Iris database, first used by Sir R.A. Fisher. The dataset is taken
...   ...

ASS II
     conceptual clustering system finds 3 classes in the data.
   - Many, many more ...
['setosa' 'versicolor' 'virginica']

分割API演示

  • sklearn.model_selection.train_test_split(*arrays**options)
    • x       数据集的特征值
    • y        数据集的标签值
    • test_size      测试集的大小,一般为float
    • random_state        随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
    • return  训练集特征值,测试集特征值,训练标签,测试标签(默认随机取)
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

li = load_iris()

#训练集特征、测试集特征、训练集目标、测试集目标 = 总特征、总目标、测试集范围
x_train,x_test,y_train,y_test =train_test_split(li.data,li.target,test_size=0.25)   #   测试集范围25%
print(y_train)   #训练集目标
print(y_test)    #测试集目标

 [1 0 0 1 1 2 0 1 0 0 0 2 0 0 2 1 2 0 2 1 1 1 2 0 1 0 2 2 1 0 2 2 1 0 1 2 2
 2 1 1 0 2 0 2 0 0 1 0 2 2 1 1 2 1 2 1 2 1 1 0 1 2 0 0 1 1 2 2 2 0 1 1 0 0
 1 2 1 2 1 0 0 2 1 1 0 0 1 1 1 1 2 0 1 0 1 0 2 0 2 2 2 2 2 1 2 2 0 2 1 2 2
 0]
[1 0 2 2 0 0 1 0 0 2 2 0 1 2 1 0 1 1 2 2 0 0 1 0 1 0 2 1 0 1 0 0 0 2 2 1 0
 2]

 用于分类的大数据集

  • sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
    • subset: 'train'或者'test','all',可选,选择要加载的数据集.训练集的“训练”,测试集的“测试”,两者的“全部”
    • datasets.clear_data_home(data_home=None)
      • 清除目录下的数据
from sklearn.datasets import fetch_20newsgroups

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

news = fetch_20newsgroups(subset='all')
print(news.data)
print(news.target)

 

DOS doesn't use the IRQ for anything.......

[10  3 17 ...  3  1  7] 

 

 

算法的实现:估算器

在sklearn中,估计器(estimator)是一个重要的角色,分类器和回归器都属于estimator,是一类实现了算法的API

 

1、用于分类的估计器:

    • sklearn.neighbors k-近邻算法
    • sklearn.naive_bayes      贝叶斯
    • sklearn.linear_model.LogisticRegression     逻辑回归

2、用于回归的估计器:

    • sklearn.linear_model.LinearRegression     线性回归
    • sklearn.linear_model.Ridge      岭回归 

工作流程:

 

 

四、分类算法

1、K近邻算法

定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。(来源:KNN算法最早是由Cover和Hart提出的一种分类算法)

公式:

        两个样本的距离可以通过如下公式计算,又叫欧式距离

        比如说,a(a1,a2,a3),b(b1,b2,b3)

API:

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')

  • n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数 
  • algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法:‘ball_tree’将会使BallTree,‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。 (不同实现方式影响效率)

实例流程:

1、数据集的处理

2、分割数据集

3、对数据集进行标准化

4、estimator流程进行分类预测

鸢尾花分类预测:

from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 1.获取数据
li = load_iris()

#2.分割数据集
x_train,x_test,y_train,y_test =train_test_split(li.data,li.target,test_size=0.25)

#3.特征工程标准化
std =StandardScaler()

# 对测试集和训练集的特征值进行标准化
x_train = std.fit_transform(x_train)

x_test = std.transform(x_test)

# 进行算法流程 # 超参数
knn = KNeighborsClassifier()
# fit, predict,score
knn.fit(x_train, y_train)

# 得出预测结果
y_predict = knn.predict(x_test)

print("预测的目标分类为:", y_predict)

# 得出准确率
print("预测的准确率:", knn.score(x_test, y_test))

优点:简单,易于理解,易于实现,无需估计参数,无需训练

缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大必须指定K值,K值选择不当则分类精度不能保证

使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试 

 

分类模型的评估:

estimator.score()

一般最常见使用的是准确率,即预测结果正确的百分比

混淆矩阵:在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)

精确率:预测结果为正例样本中真实为正例的比例(查得准)

召回率:真实为正例的样本中预测结果为正例的比例(查的全,对正样本的区分能力)

其他分类标准,F1-score,反映了模型的稳健型:

分类模型评估API:

sklearn.metrics.classification_report

 

  • sklearn.metrics.classification_report(y_truey_predtarget_names=None)
    • y_true:真实目标值
    • y_pred:估计器预测目标值
    • target_names:目标类别名称
    • return:每个类别精确率与召回率

 

from sklearn.metrics import classification_report

[...]

report = classification_report(y_test,y_predict,target_names=['setosa','versicolor','virginica'])     
print(report)

结果

['setosa' 'versicolor' 'virginica']

预测的准确率: 0.9210526315789473
              precision    recall  f1-score   support

      setosa       1.00      1.00      1.00         7
  versicolor       0.83      1.00      0.91        15
   virginica       1.00      0.81      0.90        16

   micro avg       0.92      0.92      0.92        38
   macro avg       0.94      0.94      0.94        38
weighted avg       0.93      0.92      0.92        38
 

 

2、朴素贝叶斯算法

概率基础:

联合概率:包含多个条件,且所有条件同时成立的概率

                    P(A,B) = P(A)*P(B)

条件概率:就是事件A在另外一个事件B已经发生条件下的发生概率

                P(A1,A2|B) = P(A1|B)P(A2|B)

注意:此条件概率的成立,是由于A1,A2相互独立的结果

公式:

           

如果词频列表里面有很多出现次数都为0,很可能计算结果都为零

解决方法:拉普拉斯平滑系数

一般为1,m为训练文档中统计出的特征词个数

API:

  • sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
    • alpha:拉普拉斯平滑系数
from sklearn.datasets import load_iris, fetch_20newsgroups
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer

news = fetch_20newsgroups(subset='all')

# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25)

# 对数据进行特征抽取
tf = TfidfVectorizer()

x_train = tf.fit_transform(x_train)
print(tf.get_feature_names())
x_test = tf.transform(x_test)

# 进行朴素贝叶斯预测
mlt = MultinomialNB(alpha=1.0)

print(x_train.toarray())

mlt.fit(x_train, y_train)

y_predict = mlt.predict(x_test)

print("预测的文章类别为:", y_predict)

# 得出准确率
print("准确率为:", mlt.score(x_test, y_test))

 

优点:

朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。

对缺失数据不太敏感,算法也比较简单,常用于文本分类。

分类准确度高,速度快

缺点:

需要知道先验概率P(F1,F2,…|C),因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。

 

模型的选择与调优

交叉验证:为了让被评估的模型更加准确可信,将数据分为n等份。

       将拿到的数据,分为训练和验证集。以下图为例:将数据分

成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同

的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉

验证。

 

网格搜索:

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

API:

  • sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
    • 对估计器的指定参数值进行详尽搜索
    • estimator:估计器对象
    • param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
    • cv:指定几折交叉验证
    • fit:输入训练数据
    • score:准确率
    • 结果分析:
    • best_score_:在交叉验证中测试的最好结果
    • best_estimator_:最好的参数模型
    • cv_results_:每次交叉验证后的测试集准确率结果和训练集准确率结果
rom sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV

# 1.获取数据
li = load_iris()
print(li.target_names)
#2.分割数据集
x_train,x_test,y_train,y_test =train_test_split(li.data,li.target,test_size=0.25)

#3.特征工程标准化
std =StandardScaler()

# # 对测试集和训练集的特征值进行标准化
x_train = std.fit_transform(x_train)

x_test = std.transform(x_test)

# 进行算法流程 # 超参数
knn = KNeighborsClassifier()
# fit, predict,score
knn.fit(x_train, y_train)

param = {"n_neighbors": [3, 5, 10]}

#进行网格搜索
gc = GridSearchCV(knn , param_grid=param ,cv=5)

gc.fit(x_train,y_train)

print('测试集准确率:',gc.score(x_test,y_test))

print('交叉验证中最好的结果:',gc.best_score_)

print('最好的模型:',gc.best_estimator_)

print('每个超参数每次交叉验证的结果',gc.cv_results_)

3、决策树

决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法  。

信息熵:

H的专业术语称之为信息熵,单位为比特。

公式:

决策树的划分依据:

1、信息增益:特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:

注:信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度

信息熵的计算:

条件熵的计算:

常见算法:

  • ID3   信息增益 最大的准则
  • C4.5  信息增益比 最大的准则
  • CART  回归树: 平方误差 最小 

分类树: 基尼系数   最小的准则 在sklearn中可以选择划分的原则

API:

  • class sklearn.tree.DecisionTreeClassifier(criterion=’gini’max_depth=None,random_state=None)
    • 决策树分类器
    • criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
    • max_depth:树的深度大小
    • random_state:随机数种子
    • method:
    • decision_path:返回决策树的路径

案例:泰坦尼克号获救分析

import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz

titan = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')

# print(titan.info())
# 处理数据,找出特征值和目标值


x = titan[['pclass', 'age', 'sex']]

y = titan['survived']

# print(x)
# 处理缺失值
x['age'].fillna(x['age'].mean(), inplace=True)
# print(x)
# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)

# 特征处理-onehot编码
dit = DictVectorizer(sparse=False)

x_train = dit.fit_transform(x_train.to_dict(orient='records'))
print(dit.get_feature_names())

x_test = dit.transform(x_test.to_dict(orient='records'))
# 决策树实例
dec = DecisionTreeClassifier()
dec.fit(x_train, y_train)

# 预测准确率:
print('预测的准确率:', dec.score(x_test, y_test))

# 导出决策树的结构
export_graphviz(dec, out_file='tree.dot', feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])

文件导出1:

1、sklearn.tree.export_graphviz() 该函数能够导出DOT格式

tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])

 

2、工具:(能够将dot文件转换为pdf、png)

安装graphviz

ubuntu:sudo apt-get install graphviz                    Mac:brew install graphviz

 

3、运行命令

然后我们运行这个命令

$ dot -Tpng tree.dot -o tree.png

文件导出2:


from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.externals.six import StringIO
import pydotplus


# 导出决策树的结构
data = StringIO()
export_graphviz(dec, out_file=data, feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])

graph = pydotplus.graph_from_dot_data(data.getvalue())
graph.write_png('tree.png')   #write_pdf->pdf

 

优点:

简单的理解和解释,树木可视化。

需要很少的数据准备,其他技术通常需要数据归一化,

 

缺点:

决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。

决策树可能不稳定,因为数据的小变化可能会导致完全不同的树被生成

 

改进:

减枝cart算法

随机森林

 

4、随机森林

 

集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。

定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

 

学习算法

根据下列算法而建造每棵树:

  1. 用N来表示训练用例(样本)的个数,M表示特征数目。
  2. 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
  3. 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
  • 为什么要随机抽样训练集?  

如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的

 

  • 为什么要有放回地抽样?

  如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。

API:

  • class sklearn.ensemble.RandomForestClassifier(n_estimators=10criterion=’gini’,

 max_depth=None, bootstrap=Truerandom_state=None)

  •   随机森林分类器
    • n_estimators:integer,optional(default = 10) 森林里的树木数量
    • criteria:string,可选(default =“gini”)分割特征的测量方法
    • max_depth:integer或None,可选(默认=无)树的最大深度 
    • bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样 

 

案例:

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import export_graphviz
from sklearn.model_selection import GridSearchCV
from sklearn.externals.six import StringIO
import pydotplus

titan = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')

# print(titan.info())
# 处理数据,找出特征值和目标值


x = titan[['pclass', 'age', 'sex']]

y = titan['survived']

# print(x)
# 处理缺失值
x['age'].fillna(x['age'].mean(), inplace=True)
# print(x)
# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)

# 特征处理-onehot编码
dit = DictVectorizer(sparse=False)

x_train = dit.fit_transform(x_train.to_dict(orient='records'))
print(dit.get_feature_names())

x_test = dit.transform(x_test.to_dict(orient='records'))
# 随机森林实例
rf = RandomForestClassifier(n_jobs=-1)
param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}

# 网格搜索
gc = GridSearchCV(rf, param_grid=param, cv=5)
gc.fit(x_train, y_train)
# 准确率
print('准确率:', gc.score(x_test, y_test))
#最优参数
print('最优参数:',gc.best_params_)

 

准确率: 0.8449848024316109
最有参数: {'max_depth': 5, 'n_estimators': 800}
 

最优参数,导出部分图片


rf2 = RandomForestClassifier(n_jobs=-1, n_estimators=800, max_depth=5)
rf2.fit(x_train, y_train)

print('准确率:', rf2.score(x_test, y_test))
es = rf2.estimators_[1:10]     #列表

# 导出决策树的结构
for index,model in enumerate(es):
    data=export_graphviz(model, out_file=None, feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])

    graph = pydotplus.graph_from_dot_data(data)
    graph.write_png(f'tree{ index }.png')

优点:

  • 在当前所有算法中,具有极好的准确率
  • 能够有效地运行在大数据集上
  • 能够处理具有高维特征的输入样本,而且不需要降维
  • 能够评估各个特征在分类问题上的重要性
  • 对于缺省值问题也能够获得很好得结果

5、逻辑回归

          放在  -->  2、逻辑回归

五、回归算法

1、线性回归

定义:线性回归通过一个或者多个自变量与因变量之间之间进行建模的回归分析。其中特点为一个或多个称为回归系数的模型参数的线性组合

 

一元线性回归:涉及到的变量只有一个

多元线性回归:涉及到的变量两个或两个以上

线性回归的定义是:目标值预期是输入变量的线性组合。线性模型形式简单、易于建模,但却蕴含着机器学习中一些重要的基本思想。线性回归,是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。

优点:结果易于理解,计算不复杂

缺点:对非线性的数据拟合不好

适用数据类型:数值型和标称型

对于单变量线性回归,例如:前面房价例子中房子的大小预测房子的价格。f(x) = w1*x+w0,这样通过主要参数w1就可以得出预测的值。

通用公式为:

h(θ)=θ​0​​+θ​1​​x

那么对于多变量回归,例如:瓜的好坏程度 f(x) = w0+0.2色泽+0.5根蒂+0.3*敲声,得出的值来判断一个瓜的好与不好的程度。

通用公式为:

h(θ)=θ​0​​+θ​1​​x​1​​+θ​2​​x​2​​

线性模型中的向量W值,客观的表达了各属性在预测中的重要性,因此线性模型有很好的解释性。对于这种“多特征预测”也就是(多元线性回归),那么线性回归就是在这个基础上得到这些W的值,然后以这些值来建立模型,预测测试数据。简单的来说就是学得一个线性模型以尽可能准确的预测实值输出标记。

那么如果对于多变量线性回归来说我们可以通过向量的方式来表示W值与特征X值之间的关系:

 

两向量相乘,结果为一个整数是估计值,其中所有特征集合的第一个特征值x_0x​0​​=1,那么我们可以通过通用的向量公式来表示线性模型:

h(θ)=θ​T​​∗x

损失函数是一个贯穿整个机器学习重要的一个概念,大部分机器学习算法都会有误差,我们得通过显性的公式来描述这个误差,并且将这个误差优化到最小值。

对于线性回归模型,将模型与数据点之间的距离差之和做为衡量匹配好坏的标准,误差越小,匹配程度越大。我们要找的模型就是需要将f(x)和我们的真实值之间最相似的状态。于是我们就有了误差公式,模型与数据差的平方和最小:

上面公式定义了所有的误差和,那么现在需要使这个值最小--两种方法,一种使用梯度下降算法另一种使正规方程解法(只适用于简单的线性回归)

梯度下降算法

上面误差公式是一个通式,我们取两个单个变量来求最小值,误差和可以表示为:

可以通过调整不同的w​1​​和w​0​​的值,就能使误差不断变化,而当你找到这个公式的最小值时,你就能得到最好的w​1​​,w​0​​ 而这对(w​1​​,w​0​​)就是能最好描述你数据关系的模型参数。

怎么找cost(w​0​​+w​1​​x​1​​)的最小?cost(w​0​​+w​1​​x​1​​)的图像其实像一个山谷一样,有一个最低点。找这个最低点的办法就是,先随便找一个点(w​1​​=5, w​0​​=4), 然后 沿着这个碗下降的方向找,最后就能找到山谷的最低点。

所以得出w​1​​′′​​​​−w​1​​′​​​​=−​∂cost(w​0​​+w​1​​x​1​​)​​/(∂w1)​​,那么这个过程是按照某一点在w​1​​上的偏导数下降寻找最低点。当然在进行移动的时候也需要考虑,每次移动的速度,也就是\alphaα的值,这个值也叫做(学习率),如下式:

w​1​​:=−w​1​​−α​​∂cost(w​0​​+w​1​​x​1​​)​​/(​∂w1)

w​0​​:=−w​0​​−α​​​∂cost(w​0​​+w​1​​x​1​​)​​/(​∂w1)

这样就能求出w​0​​,w​1​​的值,当然你这个过程是不断的进行迭代求出来,通过交叉验证方法即可。

理解:沿着这个函数下降的方向找,最后就能找到山谷的最低点,然后更新W值

使用:面对训练数据规模十分庞大的任务

API:

  • sklearn.linear_model.LinearRegression
    • 正规方程--普通最小二乘线性回归
    • coef_:回归系数
  • sklearn.linear_model.SGDRegressor
    • 梯度下降--通过使用SGD最小化线性模型
    • coef_:回归系数
class LinearRegression(fit_intercept = True,normalize = False,copy_X = True,n_jobs = 1)
  """
  :param normalize:如果设置为True时,数据进行标准化。请在使用normalize = False的估计器调时用fit之前使用preprocessing.StandardScaler

  :param copy_X:boolean,可选,默认为True,如果为True,则X将被复制

  :param n_jobs:int,可选,默认1。用于计算的CPU核数
  """

方法

fit(X,y,sample_weight = None)

使用X作为训练数据拟合模型,y作为X的类别值。X,y为数组或者矩阵

reg.fit ([[0, 0], [1, 1], [2, 2]], [0, 1, 2])

predict(X)

预测提供的数据对应的结果

reg.predict([[3,3]])

array([ 3.])

属性

coef_

表示回归系数w=(w1,w2....)

reg.coef_

array([ 0.5,  0.5])

intercept_ 表示w0

加入交叉验证

前面我们已经提到了模型的交叉验证,那么我们这个自己去建立数据集,然后通过线性回归的交叉验证得到模型。由于sklearn中另外两种回归岭回归、lasso回归都本省提供了回归CV方法,比如linear_model.Lasso,交叉验证linear_model.LassoCV;linear_model.Ridge,交叉验证linear_model.RidgeCV。所以我们需要通过前面的cross_validation提供的方法进行k-折交叉验证。

from sklearn.datasets.samples_generator import make_regression
from sklearn.model_selection import cross_val_score
from sklearn import linear_model
import matplotlib.pyplot as plt

lr = linear_model.LinearRegression()
X, y = make_regression(n_samples=200, n_features=5000, random_state=0)
result = cross_val_score(lr, X, y)
print result

案例:波士顿房价预测

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import SGDRegressor

# 获取数据集
lb = load_boston()
# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target.reshape(-1, 1), test_size=0.25)

# 目标值和特征值进行标准化处理
std_x = StandardScaler()
std_y = StandardScaler()

x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)

y_train = std_y.fit_transform(y_train)  # 必须传入二维数组,如果是一维数组必须转为二维。
y_test = std_y.transform(y_test)

# 预测结果
# 正规方程
lr = LinearRegression()
lr.fit(x_train, y_train)
print(lr.coef_)
# 预测测试集房价
y_lr_predict = std_y.inverse_transform(lr.predict(x_test))  # 从标准化转换回来
print("正规方程测试集的预测房价:", y_lr_predict)
print("正规方程预测的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_lr_predict))

# 梯度下降
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
print(sgd.coef_)
y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test))
print('梯度下降测试集的预测房价:', y_sgd_predict)
print('梯度下降预测的均方误差:', mean_squared_error(std_y.inverse_transform(y_test), y_sgd_predict))

ps:版本的问题,转换器对数组的要求不一样。

回归性能的评估

对于不同的类别预测,我们不能苛刻的要求回归预测的数值结果要严格的与真实值相同。一般情况下,我们希望衡量预测值与真实值之间的差距。因此,可以测评函数进行评价。其中最为直观的评价指标均方误差(Mean Squared Error)MSE,因为这也是线性回归模型所要优化的目标

通过比较发现,使用梯度下降估计参数的方法在性能表现上不及使用解析方法的LinearRegression,但是如果面对训练数据规模十分庞大的任务,随即梯度法不论是在分类还是回归问题上都表现的十分高效,可以在不损失过多性能的前提下,节省大量计算时间。根据Scikit-learn光网的建议,如果数据规模超过10万,推荐使用随机梯度法估计参数模型。

注意:线性回归器是最为简单、易用的回归模型。正式因为其对特征与回归目标之间的线性假设,从某种程度上说也局限了其应用范围。特别是,现实生活中的许多实例数据的各种特征与回归目标之间,绝大多数不能保证严格的线性关系。尽管如此,在不清楚特征之间关系的前提下,我们仍然可以使用线性回归模型作为大多数数据分析的基线系统。

API:   sklearn.metrics.mean_squared_error

  • mean_squared_error(y_truey_pred)
    • 均方误差回归损失
    • y_true:真实值
    • y_pred:预测值
    • return:浮点数结果
    • 注意:真实值,预测值为标准化之前的值

 

欠拟合与过拟合

机器学习中的泛化,泛化即是,模型学习到的概念在它处于学习的过程中时模型没有遇见过的样本时候的表现。在机器学习领域中,当我们讨论一个机器学习模型学习和泛化的好坏时,我们通常使用术语:过拟合和欠拟合。我们知道模型训练和测试的时候有两套数据,训练集和测试集。在对训练数据进行拟合时,需要照顾到每个点,而其中有一些噪点,当某个模型过度的学习训练数据中的细节和噪音,以至于模型在新的数据上表现很差,这样的话模型容易复杂,拟合程度较高,造成过拟合。而相反如果值描绘了一部分数据那么模型复杂度过于简单,欠拟合指的是模型在训练和预测时表现都不好的情况,称为欠拟合。

解决过拟合的方法

在线性回归中,对于特征集过小的情况,容易造成欠拟合(underfitting),对于特征集过大的情况,容易造成过拟合(overfitting)。针对这两种情况有了更好的解决办法

欠拟合

欠拟合指的是模型在训练和预测时表现都不好的情况,欠拟合通常不被讨论,因为给定一个评估模型表现的指标的情况下,欠拟合很容易被发现。矫正方法是继续学习并且试着更换机器学习算法。

如果主要原因是特征过少,那么就想办法增加特征。

过拟合

主要原因是原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点。

解决办法:

  • 进行特征选择,消除关联性大的特征(很难做)
  • 交叉验证(让所有数据都有过训练)
  • 正则化(了解)

L2正则化

作用:可以使得W的每个元素都很小,都接近于0

优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象

 

回归算法之岭回归

具有L2正则化的线性最小二乘法。岭回归是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价获得回归系数更为符合实际、更可靠的回归方法,对病态数据的拟合要强于最小二乘法。当数据集中存在共线性的时候,岭回归就会有用。

sklearn.linear_model.Ridge

class sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, normalize=False, copy_X=True, max_iter=None, tol=0.001, solver='auto', random_state=None)**
  """
  :param alpha:float类型,正规化的程度
  """
from sklearn.linear_model import Ridge
clf = Ridge(alpha=1.0)
clf.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1]))

方法

score(X, y, sample_weight=None)

clf.score()

属性

coef_

clf.coef_
array([ 0.34545455,  0.34545455])

intercept_

clf.intercept_
0.13636...
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import SGDRegressor
from sklearn.linear_model import Ridge

# 获取数据集
lb = load_boston()
# 分割数据集
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target.reshape(-1, 1), test_size=0.25)

# 目标值和特征值进行标准化处理
std_x = StandardScaler()
std_y = StandardScaler()

x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)

y_train = std_y.fit_transform(y_train)  # 必须传入二维数组,如果是一维数组必须转为二维。
y_test = std_y.transform(y_test)

# 预测结果
# 岭回归
rd = Ridge(alpha=1.0)  #0~1\1~10
rd.fit(x_train, y_train)
print(rd.coef_)
# 预测测试集房价
y_rd_predict = std_y.inverse_transform(rd.predict(x_test))  # 从标准化转换回来
print("岭回归测试集的预测房价:", y_rd_predict)
print("领回归预测的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_rd_predict))

保存模型与载入模型

from sklearn.externals import joblib

# joblib.dump(rd,'rdtest.pkl')
#加载训练好的模型
model = joblib.load('rdtest.pkl')
y_rdmodel_predict = std_y.inverse_transform(model.predict(x_test))
print("已保存岭回归测试集的预测房价:", y_rdmodel_predict)
print("已保存领回归预测的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_rdmodel_predict))

 

2、逻辑回归

逻辑回归(Logistic Regression),简称LR。它的特点是能够是我们的特征输入集合转化为0和1这两类的概率。一般来说,回归不用在分类问题上,因为回归是连续型模型,而且受噪声影响比较大。如果非要应用进入,可以使用逻辑回归。了解过线性回归之后再来看逻辑回归可以更好的理解。

优点:计算代价不高,易于理解和实现

缺点:容易欠拟合,分类精度不高

适用数据:数值型和标称型

Logistic回归本质上是线性回归,只是在特征到结果的映射中加入了一层函数映射,即先把特征线性求和,然后使用函数g(z)将最为假设函数来预测。g(z)可以将连续值映射到0和1上。Logistic回归用来分类0/1问题,也就是预测结果属于0或者1的二值分类问题

映射函数为:

输出:[0,1]区间的概率值,默认0.5作为阀值

注:g(z)为sigmoid函数

映射出来的效果如下如:

主要解决问题:

  • 广告点击率
  • 判断用户的性别
  • 预测用户是否会购买给定的商品类
  • 判断一条评论是正面的还是负面的

逻辑回归是解决二分类问题的利器。

哪一个类别少,就判断是该类别的概率。

损失函数

与线性回归原理相同,但由于是分类问题,损失函数不一样,只能通过梯度下降求解

对数似然损失函数:

     

完整的损失函数:

API:      sklearn.linear_model.LogisticRegression

 

class sklearn.linear_model.LogisticRegression(penalty='l2', dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='liblinear', max_iter=100, multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)
  """
  :param C: float,默认值:1.0

  :param penalty: 特征选择的方式

  :param tol: 公差停止标准
  """

 

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits
from sklearn.linear_model import LogisticRegression
LR = LogisticRegression(C=1.0, penalty='l1', tol=0.01)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
LR.fit(X_train,y_train)
LR.predict(X_test)
LR.score(X_test,y_test)
0.96464646464646464
# c=100.0
0.96801346801346799

属性

coef_

决策功能的特征系数

Cs_

数组C,即用于交叉验证的正则化参数值的倒数

特点分析

线性分类器可以说是最为基本和常用的机器学习模型。尽管其受限于数据特征与分类目标之间的线性假设,我们仍然可以在科学研究与工程实践中把线性分类器的表现性能作为基准。

 

案例:

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import ssl
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

ssl._create_default_https_context = ssl._create_unverified_context
# 获取数据
column_names = ['Sample code 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']

data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data',
                   names=column_names)

# 处理缺失值
data = data.replace(to_replace='?', value=np.nan)
data = data.dropna()
data[column_names[1:-1]] = data[column_names[1:-1]].astype(float)   #不转换类型,标准化会触发警告


#分割数据集
x_train,x_test,y_train,y_test = train_test_split(data[column_names[1:-1]],data[column_names[-1]],test_size=0.25)

# 查看训练和测试样本的数量和类别分布
print(y_train.value_counts())

print(y_test.value_counts())

#特征标准化
std = StandardScaler()

x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)

#逻辑回归预测
lg = LogisticRegression(C=1.0,solver='liblinear')    #不指定solver会触发警告
lg.fit(x_train,y_train)

y_predict = lg.predict(x_test)
print(lg.coef_)

print('准确率:',lg.score(x_test,y_test))
print('召回率:',classification_report(y_test,y_predict,labels=[2,4],target_names=['良性','恶性']))

六、非监督学习-聚类K-Means

K-means通常被称为劳埃德算法,这在数据聚类中是最经典的,也是相对容易理解的模型。算法执行的过程分为4个阶段。

  • 1.首先,随机设K个特征空间内的点作为初始的聚类中心。
  • 2.然后,对于根据每个数据的特征向量,从K个聚类中心中寻找距离最近的一个,并且把该数据标记为这个聚类中心。
  • 3.接着,在所有的数据都被标记过聚类中心之后,根据这些数据新分配的类簇,通过取分配给每个先前质心的所有样本的平均值来创建新的质心重,新对K个聚类中心做计算。
  • 4.最后,计算旧和新质心之间的差异,如果所有的数据点从属的聚类中心与上一次的分配的类簇没有变化,那么迭代就可以停止,否则回到步骤2继续循环。

K均值等于具有小的全对称协方差矩阵的期望最大化算法

API:sklearn.cluster.KMeans

class sklearn.cluster.KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm='auto')
  """
  :param n_clusters:要形成的聚类数以及生成的质心数

  :param init:初始化方法,默认为'k-means ++',以智能方式选择k-均值聚类的初始聚类中心,以加速收敛;random,从初始质心数据中随机选择k个观察值(行

  :param n_init:int,默认值:10使用不同质心种子运行k-means算法的时间。最终结果将是n_init连续运行在惯性方面的最佳输出。

  :param n_jobs:int用于计算的作业数量。这可以通过并行计算每个运行的n_init。如果-1使用所有CPU。如果给出1,则不使用任何并行计算代码,这对调试很有用。对于-1以下的n_jobs,使用(n_cpus + 1 + n_jobs)。因此,对于n_jobs = -2,所有CPU都使用一个。

  :param random_state:随机数种子,默认为全局numpy随机数生成器
  """
from sklearn.cluster import KMeans
import numpy as np
X = np.array([[1, 2], [1, 4], [1, 0],[4, 2], [4, 4], [4, 0]])
kmeans = KMeans(n_clusters=2, random_state=0)

方法

fit(X,y=None)

使用X作为训练数据拟合模型

kmeans.fit(X)

predict(X)

预测新的数据所在的类别

kmeans.predict([[0, 0], [4, 4]])
array([0, 1], dtype=int32)

属性

clustercenters

集群中心的点坐标

kmeans.cluster_centers_
array([[ 1.,  2.],
       [ 4.,  2.]])

labels_

每个点的类别

kmeans.labels_

模型评估指标:

轮廓系数:

如果结果小于0,说明平均距离大于最近的其他簇,聚类效果不好;如果结果越大,说明 的平均距离小于最近的其他簇,聚类效果好。

轮廓系数的值是介于 [-1,1] ,越趋近于1代表内聚度和分离度都相对较优

一般情况下大于0.5,0.6到0.7左右。如果达不到,就应该去调整K值。

特点分析:

采用迭代式算法,直观易懂并且非常实用

 

缺点:容易收敛到局部最优解(多次聚类)

             需要预先设定簇的数量(k-means++解决)

 

import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt

# 读取四张表的数据
prior = pd.read_csv('/Users/marvinking/Downloads/9-Market Basket Analysis/order_products__prior.csv')
products = pd.read_csv('/Users/marvinking/Downloads/9-Market Basket Analysis/products.csv')
orders = pd.read_csv('/Users/marvinking/Downloads/9-Market Basket Analysis/orders.csv')
aisles = pd.read_csv('/Users/marvinking/Downloads/9-Market Basket Analysis/aisles.csv')

# 四合一
_mg = pd.merge(prior, products, on=['product_id', 'product_id'])
_mg = pd.merge(_mg, orders, on=['order_id', 'order_id'])
mg = pd.merge(_mg, aisles, on=['aisle_id', 'aisle_id'])

# 交叉表,特殊的分组工具
cross = pd.crosstab(mg['user_id'], mg['aisle'])

# 主成分分析
pca = PCA(n_components=0.9)

data = pca.fit_transform(cross)

# 减少样本数量以加速计算
x = data[:500]

# 假设将用户分为4类
km = KMeans(n_clusters=4)

km.fit(x)

predict = km.predict(x)

# 显示聚类部分结果
plt.figure(figsize=(10, 10))
colors = ['red', 'yellow', 'blue', 'green']
x_color = [colors[i] for i in predict]
plt.scatter(x[:, 1], x[:, 20], color=x_color)
plt.xlabel('asian foods')
plt.ylabel('tortillas flat bread')
plt.show()

# 评判聚类效果,轮廓系数
print(silhouette_score(x, predict))

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值