使用 scikit-learn 介绍机器学习 | ApacheCN

中文文档:http://sklearn.apachecn.org/cn/0.19.0/tutorial/basic/tutorial.html

英文文档:http://sklearn.apachecn.org/en/0.19.0/tutorial/basic/tutorial.html

GitHub:https://github.com/apachecn/scikit-learn-doc-zh(觉得不错麻烦给个 Star,我们一直在努力)

贡献者:https://github.com/apachecn/scikit-learn-doc-zh#贡献者

使用 scikit-learn 介绍机器学习 | ApacheCN

内容提要

在本节中,我们介绍一些在使用 scikit-learn 过程中用到的机器学习词汇,并且给出一些例子阐释它们。

机器学习:问题设置

一般来说,一个学习问题通常会考虑一系列 n 个样本数据,然后尝试预测未知数据的属性。 如果每个样本是多个属性的数据(比如说是一个多维记录),就说它有许多“属性”,或称features(特征)

我们可以将学习问题分为几大类:

监督学习, 其中数据带有一个附加属性,即我们想要预测的结果值(点击此处转到 scikit-learn 监督学习页面)。这个问题可以是:

分类: 样本属于两个或更多个类,我们想从已经标记的数据中学习如何预测未标记数据的类别。 分类问题的一个例子是手写数字识别,其目的是将每个输入向量分配给有限数目的离散类别之一。 我们通常把分类视作监督学习的一个离散形式(区别于连续形式),从有限的类别中,给每个样本贴上正确的标签。

回归: 如果期望的输出由一个或多个连续变量组成,则该任务称为回归. 回归问题的一个例子是预测鲑鱼的长度是其年龄和体重的函数。

无监督学习, 其中训练数据由没有任何相应目标值的一组输入向量x组成。这种问题的目标可能是在数据中发现彼此类似的示例所聚成的组,这种问题称为聚类, 或者,确定输入空间内的数据分布,称为密度估计,又或从高维数据投影数据空间缩小到二维或三维以进行可视化点击此处转到 scikit-learn 无监督学习页面)。

训练集和测试集

机器学习是从数据的属性中学习,并将它们应用到新数据的过程。 这就是为什么机器学习中评估算法的普遍实践是把数据分割成训练集(我们从中学习数据的属性)和测试集(我们测试这些性质)。

加载示例数据集

scikit-learn提供了一些标准数据集,例如 用于分类的irisdigits数据集 和波士顿房价回归数据集.

在下文中,我们从我们的 shell 启动一个 Python 解释器,然后加载iris和digits数据集。我们的符号约定是$表示 shell 提示符,而>>>表示 Python 解释器提示符:

$ python

>>> from sklearn import datasets

>>> iris = datasets.load_iris()

>>> digits = datasets.load_digits()

数据集是一个类似字典的对象,它保存有关数据的所有数据和一些元数据。 该数据存储在.data成员中,它是n_samples,n_features数组。 在监督问题的情况下,一个或多个响应变量存储在.target成员中。 有关不同数据集的更多详细信息,请参见专用数据集部分.

例如,在数字数据集的情况下,digits.data使我们能够得到一些用于分类的样本特征:

>>>

>>>print(digits.data)[[  0.  0.  5. ...,  0.  0.  0.][  0.  0.  0. ...,  10.  0.  0.][  0.  0.  0. ...,  16.  9.  0.]...,[  0.  0.  1. ...,  6.  0.  0.][  0.  0.  2. ...,  12.  0.  0.][  0.  0.  10. ...,  12.  1.  0.]]

并且digits.target表示了数据集内每个数字的真实类别,也就是我们期望从每个手写数字图像中学得的相应的数字标记:

>>>

>>>digits.targetarray([0, 1, 2, ..., 8, 9, 8])

数据数组的形状

数据总是 2D 数组,形状(n_samples,n_features),尽管原始数据可能具有不同的形状。 在数字的情况下,每个原始样本是形状(8,8)的图像,可以使用以下方式访问:

>>>

>>>digits.images[0]array([[  0.,  0.,  5.,  13.,  9.,  1.,  0.,  0.],[  0.,  0.,  13.,  15.,  10.,  15.,  5.,  0.],[  0.,  3.,  15.,  2.,  0.,  11.,  8.,  0.],[  0.,  4.,  12.,  0.,  0.,  8.,  8.,  0.],[  0.,  5.,  8.,  0.,  0.,  9.,  8.,  0.],[  0.,  4.,  11.,  0.,  1.,  12.,  7.,  0.],[  0.,  2.,  14.,  5.,  10.,  12.,  0.,  0.],[  0.,  0.,  6.,  13.,  10.,  0.,  0.,  0.]])

数据集上的简单示例说明了如何从原始数据开始调整,形成可以在 scikit-learn 中使用的数据。

从外部数据集加载

要从外部数据集加载,请参阅加载外部数据集.

学习和预测

在数字数据集的情况下,任务是给出图像来预测其表示的数字。 我们给出了 10 个可能类(数字 0 到 9)中的每一个的样本,我们在这些类上拟合一个估计器,以便能够预测未知的样本所属的类。

在 scikit-learn 中,分类的估计器是一个 Python 对象,它实现了fit(X,y)和predict(T)等方法。

估计器的一个例子类sklearn.svm.SVC,实现了支持向量分类。 估计器的构造函数以相应模型的参数为参数,但目前我们将把估计器视为即可:

>>>

>>>fromsklearnimportsvm>>>clf=svm.SVC(gamma=0.001,C=100.)

选择模型的参数

在这个例子中,我们手动设置gamma值。不过,通过使用网格搜索交叉验证等工具,可以自动找到参数的良好值。

我们把我们的估计器实例命名为clf,因为它是一个分类器(classifier)。我们需要它适应模型,也就是说,要它从模型中*学习*。 这是通过将我们的训练集传递给fit方法来完成的。作为一个训练集,让我们使用数据集中除最后一张以外的所有图像。 我们用[:-1]Python 语法选择这个训练集,它产生一个包含digits.data中除最后一个条目(entry)之外的所有条目的新数组

>>>

>>>clf.fit(digits.data[:-1],digits.target[:-1])SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma=0.001, kernel='rbf',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)

现在你可以预测新的值,特别是我们可以向分类器询问digits数据集中最后一个图像(没有用来训练的一条实例)的数字是什么:

>>>

>>>clf.predict(digits.data[-1:])array([8])

相应的图像如下:

正如你所看到的,这是一项具有挑战性的任务:图像分辨率差。你是否认同这个分类?

这个分类问题的一个完整例子可以作为一个例子来运行和学习: 识别手写数字。Recognizing hand-written digits.

模型持久化

可以通过使用 Python 的内置持久化模块(即pickle)将模型保存:

>>>

>>>fromsklearnimportsvm>>>fromsklearnimportdatasets>>>clf=svm.SVC()>>>iris=datasets.load_iris()>>>X,y=iris.data,iris.target>>>clf.fit(X,y)SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)>>>importpickle>>>s=pickle.dumps(clf)>>>clf2=pickle.loads(s)>>>clf2.predict(X[0:1])array([0])>>>y[0]0

在scikit的具体情况下,使用 joblib 替换 pickle(joblib.dump&joblib.load)可能会更有趣,这对大数据更有效,但只能序列化 (pickle) 到磁盘而不是字符串:

>>>

>>>fromsklearn.externalsimportjoblib>>>joblib.dump(clf,'filename.pkl')

之后,您可以加载已保存的模型(可能在另一个 Python 进程中):

>>>

>>>clf=joblib.load('filename.pkl')

Warning

joblib.dump以及joblib.load函数也接受 file-like(类文件) 对象而不是文件名。有关 Joblib 的数据持久化的更多信息,请点击此处

请注意,pickle 有一些安全性和维护性问题。有关使用 scikit-learn 的模型持久化的更多详细信息,请参阅模型持久化部分。

规定

scikit-learn 估计器遵循某些规则,使其行为更可预测。

类型转换

除非特别指定,输入将被转换为float64

>>>

>>>importnumpyasnp>>>fromsklearnimportrandom_projection>>>rng=np.random.RandomState(0)>>>X=rng.rand(10,2000)>>>X=np.array(X,dtype='float32')>>>X.dtypedtype('float32')>>>transformer=random_projection.GaussianRandomProjection()>>>X_new=transformer.fit_transform(X)>>>X_new.dtypedtype('float64')

在这个例子中,X原本是float32,被fit_transform(X)被转换成float64。

回归目标被转换为float64,但分类目标维持不变:

>>>

>>>fromsklearnimportdatasets>>>fromsklearn.svmimportSVC>>>iris=datasets.load_iris()>>>clf=SVC()>>>clf.fit(iris.data,iris.target)SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)>>>list(clf.predict(iris.data[:3]))[0, 0, 0]>>>clf.fit(iris.data,iris.target_names[iris.target])SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)>>>list(clf.predict(iris.data[:3]))['setosa', 'setosa', 'setosa']

这里,第一个predict()返回一个整数数组,因为在fit中使用了iris.target(一个整数数组)。 第二个predict()返回一个字符串数组,因为iris.target_names是一个字符串数组。

再次训练和更新参数

估计器的超参数可以通过sklearn.pipeline.Pipeline.set_params方法在实例化之后进行更新。 调用fit()多次将覆盖以前的fit()所学到的参数:

>>>

>>>importnumpyasnp>>>fromsklearn.svmimportSVC>>>rng=np.random.RandomState(0)>>>X=rng.rand(100,10)>>>y=rng.binomial(1,0.5,100)>>>X_test=rng.rand(5,10)>>>clf=SVC()>>>clf.set_params(kernel='linear').fit(X,y)SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)>>>clf.predict(X_test)array([1, 0, 1, 1, 0])>>>clf.set_params(kernel='rbf').fit(X,y)SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto', kernel='rbf',max_iter=-1, probability=False, random_state=None, shrinking=True,tol=0.001, verbose=False)>>>clf.predict(X_test)array([0, 0, 0, 1, 0])

在这里,估计器被SVC()构造之后,默认内核rbf首先被改变到linear,然后改回到rbf重新训练估计器并进行第二次预测。

多分类与多标签拟合

当使用多类分类器时,执行的学习和预测任务取决于参与训练的目标数据的格式:

>>>

>>>fromsklearn.svmimportSVC>>>fromsklearn.multiclassimportOneVsRestClassifier>>>fromsklearn.preprocessingimportLabelBinarizer>>>X=[[1,2],[2,4],[4,5],[3,2],[3,1]]>>>y=[0,0,1,1,2]>>>classif=OneVsRestClassifier(estimator=SVC(random_state=0))>>>classif.fit(X,y).predict(X)array([0, 0, 1, 1, 2])

在上述情况下,分类器被使用一个含有多个标签的一维数组训练,因此predict()方法提供相应的多类别预测。分类器也可以通过二进制表示的的标签的二维数组来训练:

>>>

>>>y=LabelBinarizer().fit_transform(y)>>>classif.fit(X,y).predict(X)array([[1, 0, 0],[1, 0, 0],[0, 1, 0],[0, 0, 0],[0, 0, 0]])

这里,使用LabelBinarizer使目标向量 y 被转化成二维数组的标签表示。在这种情况下,predict()返回一个表示相应多重标签预测的 2d 矩阵。

请注意,第四个和第五个实例返回全零向量,表明它们不能匹配用来训练中的目标标签中的任意一个。使用多分类输出,类似地可以为一个实例分配多个标签:

>>fromsklearn.preprocessingimportMultiLabelBinarizer>>y=[[0,1],[0,2],[1,3],[0,2,3],[2,4]]>>y=MultiLabelBinarizer().fit_transform(y)>>classif.fit(X,y).predict(X)array([[1,1,0,0,0],[1,0,1,0,0],[0,1,0,1,0],[1,0,1,1,0],[0,0,1,0,1]])

在这种情况下,用来训练分类器的多个向量被赋予多个标记,MultiLabelBinarizer被用来二进制化多个标签的二维数组,使之用来训练。predict()函数返回带有多个标记的二维数组作为每个实例的结果。

中文文档:http://sklearn.apachecn.org/cn/0.19.0/tutorial/basic/tutorial.html

英文文档:http://sklearn.apachecn.org/en/0.19.0/tutorial/basic/tutorial.html

GitHub:https://github.com/apachecn/scikit-learn-doc-zh(觉得不错麻烦给个 Star,我们一直在努力)

贡献者:https://github.com/apachecn/scikit-learn-doc-zh#贡献者

有兴趣的大佬们也可以和我们一起来维护,持续更新中 。。。

机器学习交流群: 629470233

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

推荐阅读更多精彩内容