joblib.dump 会产生多少个var dump 输出不完整

http://www.52ml.net/15539.html
所谓学习问题,是指观察由n个组成的集合,并根据这些数据来预测未知数据的性质。
学习任务(一个二分类问题):
区分一个普通的互联网检索Query是否具有某个垂直领域的意图。假设现在有一个O2O领域的垂直搜索引擎,专门为用户提供团购、优惠券的检索;同时存在一个通用的搜索引擎,比如百度,通用搜索引擎希望能够识别出一个Query是否具有O2O检索意图,如果有则调用O2O垂直搜索引擎,获取结果作为通用搜索引擎的结果补充。
我们的目的是学习出一个分类器(classifier),分类器可以理解为一个函数,其输入为一个Query,输出为0(表示该Query不具有o2o意图)或1(表示该Query具有o2o意图)。
特征提取:
要完成这样一个学习任务,首先我们必须找出决定一个Query是否具有O2O意图的影响因素,这些影响因素称之为特征(feature)。特征的好坏很大程度上决定了分类器的效果。在机器学习领域我们都知道特征比模型(学习算法)更重要。(顺便说一下,工业界的人都是这么认为的,学术界的人可能不以为然,他们整天捣鼓算法,发出来的文章大部分都没法在实际中应用。)举个例子,如果我们的特征选得很好,可能我们用简单的规则就能判断出最终的结果,甚至不需要模型。比如,要判断一个人是男还是女(人类当然很好判断,一看就知道,这里我们假设由计算机来完成这个任务,计算机有很多传感器(摄像头、体重器等等)可以采集到各种数据),我们可以找到很多特征:身高、体重、皮肤颜色、头发长度等等。因为根据统计我们知道男人一般比女人重,比女人高,皮肤比女人黑,头发比女人短;所以这些特征都有一定的区分度,但是总有反例存在。我们用最好的算法可能准确率也达不到100%。假设计算机还能够读取人的身份证号码,那么我们可能获得一个更强的特征:身份证号码的倒数第二位是否是偶数。根据身份证编码规则,我们知道男性的身份证号码的倒数第二位是奇数,女生是偶数。因此,有了这个特征其他的特征都不需要了,而且我们的分类器也很简单,不需要复杂的算法。
言归正传,对于O2O Query意图识别这一学习任务,我们可以用的特征可能有:Query在垂直引擎里能够检索到的结果数量、Query在垂直引擎里能够检索到的结果的类目困惑度(perplexity)(检索结果的类目越集中说明其意图越强)、Query能否预测到特征的O2O商品类目、Query是否包含O2O产品词或品牌词、Query在垂直引擎的历史展现次数(PV)和点击率(ctr)、Query在垂直引擎的检索结果相关性等等。
特征表示:
特征表示是对特征提取结果的再加工,目的是增强特征的表示能力,防止模型(分类器)过于复杂和学习困难。比如对连续的特征值进行离散化,就是一种常用的方法。这里我们以&Query在垂直引擎里能够检索到的结果数量&这一特征为例,简要介绍一下特征值分段的过程。首先,分析一下这一维特征的分布情况,我们对这一维特征值的最小值、最大值、平均值、方差、中位数、三分位数、四分位数、某些特定值(比如零值)所占比例等等都要有一个大致的了解。获取这些值,python编程语言的numpy模块有很多现成的函数可以调用。最好的办法就是可视化,借助python的matplotlib工具我们可以很容易地划出数据分布的直方图,从而判断出我们应该对特征值划多少个区间,每个区间的范围是怎样的。比如说我们要对&结果数量&这一维特征值除了&0&以为的其他值均匀地分为10个区间,即每个区间内的样本数大致相同。&0&是一个特殊的值,因此我们想把它分到一个单独的区间,这样我们一共有11个区间。python代码实现如下:
def&bin(bins):
& &&assert&isinstance(bins,&(list,&tuple))
& &&def&scatter(x):
& & & &&if&x ==&0:&return&0
& & & &&for&i&in&range(len(bins)):
& & & & & &&if&x&<= bins[i]:&return&i +&1
& & & &&return&len(bins)
& &&return&np.frompyfunc(scatter,&1,&1)
data = np.loadtxt("D:\query_features.xls", dtype='int')
# descrete
o2o_result_num = data[:,0]
o2o_has_result = o2o_result_num[o2o_result_num&>&0]
bins =&[&np.percentile(o2o_has_result, x)&for&x&in&range(10,&101,&10)&]
data[:,0]&= bin(bins)(o2o_result_num)
我们首先获取每个区间的起止范围,即分别算法特征向量的10个百分位数,并依此为基础算出新的特征值(通过bin函数,一个numpy的universal function)。
训练数据:
这里我们通过的方法来拟合分类器模型。所谓有监督学习是指通过提供一批带有标注(学习的目标)的数据(称之为训练样本),学习器通过分析数据的规律尝试拟合出这些数据和学习目标间的函数,使得定义在训练集上的总体误差尽可能的小,从而利用学得的函数来预测未知数据的学习方法。注意这不是一个严格的定义,而是我根据自己的理解简化出来的。
一批带有标注的训练数据从何而来,一般而言都需要人工标注。我们从搜索引擎的日志里随机采集一批Query,并且保证这批Query能够覆盖到每维特征的每个取值(从这里也可以看出为什么要做特征分区间或离散化了,因为如不这样做我们就不能保证能够覆盖到每维特征的每个取值)。然后,通过人肉的方法给这边Query打上是否具有O2O意图的标签。数据标注是一个痛苦而漫长的过程,需要具有一定领域知识的人来干这样的活。标注质量的好坏很有可能会影响到学习到的模型(这里指分类器)在未知Query上判别效果的好坏。即正确的老师更可能教出正确的学生,反之,错误的老师教坏学生的可能性越大。在我自己标注数据的过程中,发现有一些Query的O2O意图比较模棱两可,导致我后来回头看的时候总觉得自己标得不对,反反复复修改了好几次。
选择模型:
在我们的问题中,模型就是要学习的分类器。有监督学习的分类器有很多,比如决策树、随机森林、逻辑回归、梯度提升、SVM等等。如何为我们的分类问题选择合适的机器学习算法呢?当然,如果我们真正关心准确率,那么最佳方法是测试各种不同的算法(同时还要确保对每个算法测试不同参数),然后通过交叉验证选择最好的一个。但是,如果你只是为你的问题寻找一个&足够好&的算法,或者一个起点,也是有一些还不错的一般准则的,比如如果训练集很小,那么高偏差/低方差分类器(如朴素贝叶斯分类器)要优于低偏差/高方差分类器(如k近邻分类器),因为后者容易过拟合。然而,随着训练集的增大,低偏差/高方差分类器将开始胜出(它们具有较低的渐近误差),因为高偏差分类器不足以提供准确的模型。
这里我们重点介绍一次完整的机器学习全过程,所以不花大篇幅在模型选择的问题上,推荐大家读一些这篇文章:《》。
通过交叉验证拟合模型:
机器学习会学习数据集的某些属性,并运用于新数据。这就是为什么习惯上会把数据分为两个集合,由此来评价算法的优劣。这两个集合,一个叫做训练集(train data),我们从中获得数据的性质;一个叫做测试集(test data),我们在此测试这些性质,即模型的准确率。将一个算法作用于一个原始数据,我们不可能只做出随机的划分一次train和test data,然后得到一个准确率,就作为衡量这个算法好坏的标准。因为这样存在偶然性。我们必须好多次的随机的划分train data和test data,分别在其上面算出各自的准确率。这样就有一组准确率数据,根据这一组数据,就可以较好的准确的衡量算法的好坏。交叉验证就是一种在数据量有限的情况下的非常好evaluate performance的方法。
&2&from&sklearn&import&tree
&3&from&sklearn&import&ensemble
&4&from&sklearn&import&linear_model
&5&from&sklearn&import&svm
&7&lr = linear_model.LogisticRegression()
&8&lr_scores = cross_validation.cross_val_score(lr, train_data, train_target, cv=5)
&9&print("logistic regression accuracy:")
10&print(lr_scores)
12&clf = tree.DecisionTreeClassifier(criterion='entropy', max_depth=8, min_samples_split=5)
13&clf_scores = cross_validation.cross_val_score(clf, train_data, train_target, cv=5)
14&print("decision tree accuracy:")
15&print(clf_scores)
17&rfc = ensemble.RandomForestClassifier(criterion='entropy', n_estimators=3, max_features=0.5, min_samples_split=5)
18&rfc_scores = cross_validation.cross_val_score(rfc, train_data, train_target, cv=5)
19&print("random forest accuracy:")
20&print(rfc_scores)
22&etc = ensemble.ExtraTreesClassifier(criterion='entropy', n_estimators=3, max_features=0.6, min_samples_split=5)
23&etc_scores = cross_validation.cross_val_score(etc, train_data, train_target, cv=5)
24&print("extra trees accuracy:")
25&print(etc_scores)
27&gbc = ensemble.GradientBoostingClassifier()
28&gbc_scores = cross_validation.cross_val_score(gbc, train_data, train_target, cv=5)
29&print("gradient boosting accuracy:")
30&print(gbc_scores)
32&svc = svm.SVC()
33&svc_scores = cross_validation.cross_val_score(svc, train_data, train_target, cv=5)
34&print("svm classifier accuracy:")
35&print(svc_scores)
上面的代码我们尝试同交叉验证的方法对比五种不同模型的准确率,结果如下:
&2&[&0.&&0.&&0.&&0.&&0.]
&3&decision tree accuracy:
&4&[&0.&&0.8&& & & &&0.&&0.&&0.]
&5&random&forest accuracy:
&6&[&0.75&& & & &0.&&0.&&0.&&0.]
&7&extra trees accuracy:
&8&[&0.734375&& &0.&&0.7992126&&&0.&&0.]
&9&gradient boosting accuracy:
10&[&0.7578125&&&0.&&0.&&0.&&0.]
11&svm classifier accuracy:
12&[&0.703125&& &0.&&0.&&0.&&0.]
在O2O意图识别这个学习问题上,逻辑回归分类器具有最好的准确率,其次是梯度提升分类器;决策树和随机森林在我们的测试结果中并没有体现出明显的差异,可能是我们的特殊数量太少并且样本数也较少的原因;另外大名典典的SVM的表现却比较让人失望。总体而言,准确率只有82%左右,分析其原因,一方面我们实现的特征数量较少;另一方面暂时未能实现区分能力强的特征。后续会对此持续优化。
由于逻辑回归分类器具有最好的性能,我们决定用全部是可能训练数据来拟合之。
&strong&模型数据持久化&/strong&:
学到的模型要能够在将来利用起来,就必须把模型保存下来,以便下次使用。同时,数据离散化或数据分区的范围数据也要保存下来,在预测的时候同样也需要对特征进行区间划分。python提供了pickle模块用来序列号对象,并保存到硬盘上。同时,scikit-learn库也提供了更加高效的模型持久化模块,可以直接使用。
&pre lang="python"&1&from&sklearn.externals&import&joblib
2&joblib.dump(lr,&'D:\lr.model')
3&import&pickle
4&bin_file =&open(r'D:\result_bin.data',&'wb')
5&pickle.dump(bins, bin_file)
6&bin_file.close()
分类器的使用:
现在大功告成了,我们需要做的就是用学习到的分类器来判断一个新的Query到底是否具有O2O意图。因为我们分类器的输入是Query的特征向量,而不是Query本身,因此我们需要实现提取好Query的特征。假设我们已经离线算好了每个Query的特征,现在使用的时候只需要将其加载进内场即可。分类器使用的过程首先是从硬盘读取模型数据和Query特征,然后调用模型对Query进行预测,输出结果。
&2&bin_file =&open(r'D:\result_bin.data',&'rb')
&3&bins =&pickle.load(bin_file)
&4&bin_file.close()
&6&lr = joblib.load('D:\lr.model')
&8&# load data
&9&query = np.genfromtxt(r'D:\o2o_query_rec\all_query', dtype='U2', comments=None, converters={0:&lambda&x:&str(x,&'utf-8')})
10&feature = np.loadtxt(r'D:\o2o_query_rec\all_features', dtype='int', delimiter='\001')
12&# descrite
13&feature[:,0]&= bin(bins)(feature[:,0])
14&feature[:,1]&= ufunc_segment(feature[:,1])
16&# predict
17&result = lr.predict(feature)
19&# save result
20&#np.savetxt(r'D:\o2o_query_rec\classify_result.txt', np.c_[query, result], fmt=u"%s", delimiter="\t")
21&result_file =&open(r'D:\o2o_query_rec\classify_result.txt',&'w')
23&for&q&in&query:
24&& & result_file.write('%s\t%d\n'&%&(q, result[i]))
25&& & i +=&1
26&result_file.close()
需要注意的是我们Query的编码是UTF-8,load的时候需要做相应的转换。另外,在python 3.3版本,numpy的savetxt函数并不能正确保持UTF-8格式的中文Query(第20行注释掉的代码输出的Query都变成了bytes格式的),如果小伙伴们有更好的办法能够解决这个问题,请告诉我,谢谢!
阅读(...) 评论()Python scikit-learn: exporting trained classifier - Stack Overflow
to customize your list.
Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
J it only takes a minute:
I am using a DBN (deep belief network) from
based on scikit-learn.
I have already build a Network which can classify my data very well, now I am interested in exporting the model for deployment, but I don't know how (I am training the DBN every time I want predict something). In matlab I would just export the weight matrix and import it in another machine.
Does someone know how to export the model/the weight matrix to be imported without needing to train the whole model again?
1,73542752
You can use:
&&& from sklearn.externals import joblib
&&& joblib.dump(clf, 'my_model.pkl', compress=9)
And then later, on the prediction server:
&&& from sklearn.externals import joblib
&&& model_clone = joblib.load('my_model.pkl')
This is basically a Python pickle with an optimized handling for large numpy arrays. It has the same limitations as the regular pickle w.r.t. code change: if the class structure of the pickle object changes you might no longer be able to unpickle the object with new versions of nolearn or scikit-learn.
If you want long-term robust way of storing your model parameters you might need to write your own IO layer (e.g. using binary format serialization tools such as protocol buffers or avro or an inefficient yet portable text / json / xml representation such as ).
17.1k39146285
21.6k65373
Pickling/unpickling has the disadvantage that it only works with matching python versions (major and possibly also minor versions) and sklearn, joblib library versions.
There are alternative descriptive output formats for machine learning models, such as developed by the , such as the predictive models markup language (PMML) and the portable format for analytics (PFA). Of the two, PMML is .
So you have the option of saving a model from scikit-learn into PMML (for example using ), and then deploy and run it in java, spark, or hive using
(of course you have more choices).
The section
in scikit-learn documentation covers pretty much everything.
In addition to sklearn.externals.joblib ogrisel pointed to, it shows how to use the regular pickle package:
&&& from sklearn import svm
&&& from sklearn import datasets
&&& 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, degree=3, gamma=0.0,
kernel='rbf', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
&&& import pickle
&&& s = pickle.dumps(clf)
&&& clf2 = pickle.loads(s)
&&& clf2.predict(X[0])
array([0])
and gives a few warnings such as models saved in one version of scikit-learn might not load in another version.
16.6k1195211
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
rev .24790
Stack Overflow works best with JavaScript enabledSave sklearn cross validation object [保存sklearn交叉验证对象] - 问题-字节技术
Save sklearn cross validation object
保存sklearn交叉验证对象
问题 (Question)
Following the tutorial for , I attempted to save an object that was created via sklearn but was unsuccessful. It appears the problem is with the cross validation object, as I can save the actual (final) model.
rf_model = RandomForestRegressor(n_estimators=1000, n_jobs=4, compute_importances = False)
cvgridsrch = GridSearchCV(estimator=rf_model, param_grid=parameters,n_jobs=4)
cvgridsrch.fit(X,y)
This will succeed:
joblib.dump(cvgridsrch.best_estimator_, 'C:\\Users\\Desktop\\DMA\\cvgridsrch.pkl', compress=9)
and this will fail:
joblib.dump(cvgridsrch, 'C:\\Users\\Desktop\\DMA\\cvgridsrch.pkl', compress=9)
with error:
PicklingError: Can't pickle &type 'instancemethod'&: it's not found as __builtin__.instancemethod
How to save the full object?
下面的教程,我试图拯救一个对象通过创建sklearn但不成功。看来问题是与交叉验证对象,我可以节省实际的(最终)模型。考虑到:rf_model = RandomForestRegressor(n_estimators=1000, n_jobs=4, compute_importances = False)
cvgridsrch = GridSearchCV(estimator=rf_model, param_grid=parameters,n_jobs=4)
cvgridsrch.fit(X,y)
这将会成功:joblib.dump(cvgridsrch.best_estimator_, 'C:\\Users\\Desktop\\DMA\\cvgridsrch.pkl', compress=9)
这将会失败:joblib.dump(cvgridsrch, 'C:\\Users\\Desktop\\DMA\\cvgridsrch.pkl', compress=9)
错误:PicklingError: Can't pickle &type 'instancemethod'&: it's not found as __builtin__.instancemethod
如何保存完整的对象?
最佳答案 (Best Answer)
One possible cause could be multithreading issue, which you may refer to
stackoverflow answer.
Also, is it possible for you to dump your object not via joblib but a more fundamental method like pickle (and not even cPickle, which is more restrictive)?
一个可能的原因可能是多线程问题,你可以参考stackoverflow回答。也有可能你把你对象通过joblib但是一个更根本的方法不像泡菜(甚至不是cPickle、更多的限制)?
本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:一、机器学习:问题设定
通常,一个学习问题是通过分析一些数据样本来尝试预测未知数据的属性。如果每一个样本不仅仅是一个单独的数字,比如一个多维的实例(multivariate data),也就是说有着多个属性特征
我们可以把学习问题分成如下的几个大类:
(1)有监督学习
数据带有我们要预测的属性。这种问题主要有如下几种:
样例属于两类或多类,我们想要从已经带有标签的数据学习以预测未带标签的数据。识别手写数字就是一个分类问题,这个问题的主要目标就是把每一个输出指派到一个有限的类别中的一类。另一种思路去思考分类问题,其实分类问题是有监督学习中的离散形式问题。每一个都有一个有限的分类。对于样例提供的多个标签,我们要做的就是把未知类别的数据划分到其中的一种。
去过预期的输出包含连续的变量,那么这样的任务叫做回归。根据三文鱼的年纪和中联预测其长度就是一个回归样例。
(2)无监督学习
训练数据包含不带有目标值的输入向量x。对于这些问题,目标就是根据数据发现样本中相似的群组——聚类。或者在输入空间中判定数据的分布——密度估计,或者把数据从高维空间转换到低维空间以用于可视化
训练集和测试集
机器学习是学习一些数据集的特征属性并将其应用于新的数据。这就是为什么在机器学习用来评估算法时一般把手中的数据分成两部分。一部分我们称之为训练集,用以学习数据的特征属性。一部分我们称之为测试集,用以检验学习到的特征属性。
二、加载一个样本数据集
scikit-learn带有一些标准数据集。比如用来分类的iris数据集、digits数据集;用来回归的boston house price 数据集。
接下来,我们我们从shell开启一个Python解释器并加载iris和digits两个数据集。【译注:一些代码惯例就不写了,提示符&&&之类的学过Python的都懂】
&&&from sklearn import datasets
&&&iris = datasets.load_iris()
&&&digits = datasets.load_digits()
一个数据集是一个包含数据所有元数据的类字典对象。这个数据存储在 '.data'成员变量中,是一个$n*n$的数组,行表示样例,列表示特征。在有监督学习问题中,一个或多个响应变量(Y)存储在‘.target’成员变量中。不同数据集的更多细节可以在dedicated section中找到。
例如,对于digits数据集,digits.data可以访问得到用来对数字进行分类的特征:
&&&print(digits.data)
digits.target 就是数字数据集对应的真实数字值。也就是我们的程序要学习的。
&&&digits.target
array([0, 1, 2, ..., 8, 9, 8])
数据数组的形状
尽管原始数据也许有不同的形状,但实际使用的数据通常是一个二维数组(n个样例,n个特征)。对于数字数据集,每一个原始的样例是一张(8 x 8)的图片,也能被使用:
&&&digits.images[0]
三、学习和预测
对于数字数据集(digits dataset),任务是预测一张图片中的数字是什么。数字数据集提供了0-9每一个数字的可能样例,可以用它们来对位置的数字图片进行拟合分类。
在scikit-learn中,用以分类的拟合(评估)函数是一个Python对象,具体有fit(X,Y)和predic(T)两种成员方法。
其中一个拟合(评估)样例是sklearn.svmSVC类,它实现了支持向量分类(SVC)。一个拟合(评估)函数的构造函数需要模型的参数,但是时间问题,我们将会把这个拟合(评估)函数作为一个黑箱:
&&&from sklearn import svm
&&&clf = svm.SVC(gamma=0.001, C=100.)
选择模型参数
我们调用拟合(估测)实例clf作为我们的分类器。它现在必须要拟合模型,也就是说,他必须要学习模型。这可以通过把我们的训练集传递给fit方法。作为训练集,我们使用其中除最后一组的所有图像。我们可以通过Python的分片语法[:-1]来选取训练集,这个操作将产生一个新数组,这个数组包含digits.dataz中除最后一组数据的所有实例。
&&&clf.fit(digits.data[:-1], digits.target[:-1])
SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0, 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])
相应的图片如下图:
正如你所看到的,这是一个很有挑战的任务:这张图片的分辨率很低。你同意分类器给出的答案吗?
这个分类问题的完整示例在这里识别手写数字,你可以运行并使用它。[译:看本文附录]
四、模型持久化
可以使用Python的自带模块——pickle来保存scikit中的模型:
&&&from sklearn import svm
&&&from sklearn import datasets
&&&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, degree=3, gamma=0.0,
kernel='rbf', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
&&&import pickle
&&&s = pickle.dumps(clf)
&&&clf2 = pickle.loads(s)
&&&clf2.predict(X[0])
array([0])
对于scikit,也许使用joblib的pickle替代——(joblib.dump&joblib.load)更有趣。因为它在处理带数据时更高效。但是遗憾的是它只能把数据持久化到硬盘而不是一个字符串(译注:搬到string字符串意味着数据在内存中):
&&&from sklearn.externals import joblib
&&&joblib.dump(clf, 'filename.pkl')
往后你就可以加载这个转储的模型(也能在另一个Python进程中使用),如下:
&&&clf = joblib.load('filename.pkl')
joblib.dump返回一个文件名的列表,每一个numpy数组元素包含一个clf在文件系统上的名字,在用joblib.load加载的时候所有的文件需要在相同的文件夹下
注意pickle有一些安全和可维护方面的问题。请参考Model persistent 获得在scikit-learn中模型持久化的细节。
五、惯例约定
scikit-learn的各种拟合(评估)函数遵循一些确定的规则以使得他们的用法能够被预想到(译:使得各种学习方法的用法统一起来)
①类型转换
除非特别指定,输入将被转换为float64
import numpy
from sklearn import random_projection
rng = np.random.RandomState(0)
X = rng.rand(10,2000)
X = np.array(X,dtype ='float32')
print x.dtype
transformer = random_projection.GaussianRandomProjection()
X_new = transformer.fit_transform(X)
print X_new.dtype
在这个例子中,X是float32,被fit_transform(X)转换成float64,回归被转换成float64,分类目标维持不变.
from sklearn import datesets
from sklearn.svm import SVC
iris = datasets.load_iris()
clf =SVC()
clf.fit(iris.data,iris.target)
print list(clf.predict(iris.data[:3]))
clf.fit(iris.data,iris.target_names[iris.target])
print list(clf.predict(iris.data[:3]))
这里第一个predict()返回一个整数数组,是因为iris.target(一个整数数组)被用于拟合。第二个predict()返回一个字符串数组,因为iris.target_names被用于拟合。
②重拟合和更新参数
一个拟合(评估)函数的混合参数(超参数)能够在通过sklearn.pipeline.Pipeline.set_params方法构造之后被更新。多次调用fit()能够覆写之前fit()学习的内容:
import numpy as np
from sklearn.svm import SVC
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)
clf.predict(X_test)
clf.set_params(kernel='rbf').fit(X,Y)
clf.predict(X_test)
这里,用SVC()构造之后,开始拟合(评估)函数默认的'rbf'核被改编成'linear',后来又改回'rbf'去重拟合做第二次的预测。
①digits数据集:一个展示怎样用scikit-learn识别手写数字的样例:绘制数字:
②绘制数字分类 (plot_digits_classification.py)
#针对科学数据处理的统计学习教程
翻译:Tacey Wong
统计学习:
随着科学实验数据的迅速增长,机器学习成了一种越来越重要的技术。问题从构建一个预测函数将不同的观察数据联系起来,到将观测数据分类,或者从未标记数据中学习到一些结构。
本教程将探索机器学习中统计推理的统计学习的使用:将手中的数据做出结论
Scikit-learn&是一个紧密结合Python科学计算库(Numpy、Scipy、matplotlib),集成经典机器学习算法的Python模块。
一、统计学习:scikit-learn中的设置与评估函数对象
(1)数据集
scikit-learn 从二维数组描述的数据中学习信息。他们可以被理解成多维观测数据的列表。如(n,m),n表示样例轴,y表示特征轴。
使用scikit-learn装载一个简单的样例:iris数据集
&&from sklearn import datasets
&&iris = datasets.load_iris()
&&data = iris.data
&&data.shape
它有150个iris观测数据构成,每一个样例被四个特征所描述:他们的萼片、花瓣长度、花瓣宽度,具体的信息可以通过iris》DESCR查看。
当数据初始时不是(n样例,n特征)样式时,需要将其预处理以被scikit-learn使用。
通过数字数据集讲述数据变形
数字数据集由手写数字图片组成
&&&digits = datasets.load_digits()
&&&digits.images.shape
(1797, 8, 8)
&&& import pylab as pl
&&&pl.imshow(digits.images[-1], cmap=pl.cm.gray_r)
&matplotlib.image.AxesImage object at ...&
在scikit-learn中使用这个数据集,我们需要将其每一个8x8图片转换成长64的特征向量
&&&data = digits.images.reshape((digits.images.shape[0],-1))
(2)估计函数对象
拟合数据:scikit-learn实现的主要API是估计函数。估计函数是用以从数据中学习的对象。它可能是分类、回归、聚类算法,或者提取过滤数据特征的转换器。
一个估计函数带有一个fit方法,以dataset作为参数(一般是个二维数组)
&&&estimator.fit(data)
估计函数对象的参数:每一个估测器对象在实例化或者修改其相应的属性,其参数都会被设置。
&&&estimator = Estimator(param1=1, param2=2)
&&&estimator.param1
估测后的参数:
&&&estimator.estimated_param_
二、有监督学习:从高维观察数据预测输出变量
有监督学习解决的问题
有监督学习主要是学习将两个数据集联系起来:观察数据x和我们要尝试预测的外置变量y,y通常也被称作目标、标签。多数情况下,y是一个和n个观测样例对应的一维数组。
scikit-learn中实现的所有有监督学习评估对象,都有fit(X,Y)方法来拟合模型,predict(X)方法根据未加标签的观测数据X
返回预测的标签y。
词汇:分类和回归
如果预测任务是将观测数据分类到一个有限的类别集中,换句话说,给观测对象命名,那么这个任务被称作分类任务。另一方面,如果任务的目标是预测测目标是一个连续性变量,那么这个任务成为回归任务。
用scikit-learn解决分类问题时,y是一个整数或字符串组成的向量
注意:查看[]快速了解用scikit-learn解决机器学习问题过程中的基础词汇。
(1)近邻和高维灾难
iris分类:
iris分类是根据花瓣、萼片长度、萼片宽度来识别三种不同类型的iris的分类任务:
&& import numpy as np
&& from sklearn import datasets
&& iris = datasets.load_iris()
&& iris_X = iris.data
&& iris_y = iris.target
&& np.unique(iris_y)
array([0, 1, 2])
最近邻分类器:
近邻也许是最简的分类器:得到一个新的观测数据X-test,从训练集的观测数据中寻找特征最相近的向量。(【】)
训练集和测试集:
当尝试任何学习算法的时候,评估一个学习算法 的预测精度是很重要的。所以在做机器学习相关的问题的时候,通常将数据集分成训练集和测试集。
KNN(最近邻)分类示例:
高维灾难:
对于一个有效的学习算法,你需要最近n个点之间的距离d(依赖于具体的问题)。在一维空间中,需要平局n1/d各点,在上文中提到的K-NN例子中,如果数据只是有一个0-1之间的特征和n个训练观测数据所表述的画,那么新数据将不会超过1/n。因此,最近邻决策规则非常高效,因为与类间特征变化的范围相比,1/n小的多。
如果特征数是P,你就需要n 1/d^p个点。也就是说,如果我们在一维度情况下需要10个点,在P维度情况下需要10^p个点。当P变大的时候,为获得一个好的预测函数需要的点数将急剧增长。
这被称为高维灾难(指数级增长),也是机器学习领域的一个核心问题。
(2)线性模型:从回归到稀疏性
Diabets数据集(糖尿病数据集)
糖尿病数据集包含442个患者的10个生理特征(年龄,性别、体重、血压)和一年以后疾病级数指标。
diabetes = datasets.load_diabetes()
diabetes_X_train = diabetes.data[:-20]
diabetes_X_test = diabetes.data[-20:]
diabetes_y_train = diabetes.target[:-20]
diabetes_y_test = diabetes.target[-20:]
手上的任务是从生理特征预测疾病级数
线性回归:
【线性回归】的最简单形式给数据集拟合一个线性模型,主要是通过调整一系列的参以使得模型的残差平方和尽量小。
线性模型:y = βX+
from sklearn import linear_model
regr = linear_model.LinearRegression()
regr.fit(diabetes_X_train, diabetes_y_train)
print(regr.coef_)
收缩(Shrinkage):
如果每一维的数据点很少,噪声将会造成很大的偏差影响:
X = np.c_[ .5, 1].T
y = [.5, 1]
test = np.c_[ 0, 2].T
regr = linear_model.LinearRegression()
import pylab as pl
pl.figure()
np.random.seed(0)
for _ in range(6):
this_X = .1*np.random.normal(size=(2, 1)) + X
regr.fit(this_X, y)
pl.plot(test, regr.predict(test))
pl.scatter(this_X, y, s=3)
高维统计学习的一个解决方案是将回归系数缩小到0:观测数据中随机选择的两个数据集近似不相关。这被称为岭回归(Ridge Regression):
regr = linear_model.Ridge(alpha=.1)
pl.figure()
np.random.seed(0)
for _ in range(6):
this_X = .1*np.random.normal(size=(2, 1)) + X
regr.fit(this_X, y)
pl.plot(test, regr.predict(test))
pl.scatter(this_X, y, s=3)
这是一个偏差/方差(bias/variance)的权衡:岭α参数越大,偏差(bias)越大,方差(variance)越小
我们可以选择α以最小化排除错误,这里使用糖尿病数据集而不是人为制造的数据:
alphas = np.logspace(-4, -1, 6)
from __future__ import print_function
print([regr.set_params(alpha=alpha
).fit(diabetes_X_train, diabetes_y_train,
).score(diabetes_X_test, diabetes_y_test) for alpha in alphas])
【注意】扑捉拟合参数的噪声使得模型不能推广到新的数据被称为过拟合。岭回归造成的偏差被称为正则化(归整化,regularization)
只拟合特征1和特征2:
【注意】整个糖尿病数据包含11维数据(10个特征维,一个目标变量),很难对这样的数据直观地表现出来,但是记住那是一个很空的空间也许是有用的。
我们可以看到,尽管特征2在整个模型中占据很大的系数,但是和特征1相比,对结果y造成的影响很小。
为了提升问题的状况(考虑到高维灾难),只选择信息含量较大的(对结果y造成的影响较大的)的特征,不选择信息含量较小的特征会很有趣,如把特征2的系数调到0.岭回归将会减少信息含量较小的系数的值,而不是把它们设置为0.另一种抑制措施——Lasso(最小绝对收缩和选择算子)可以使得一些参数为0.这些方法被称作稀疏方法。系数操作可以看作是奥卡姆的剃刀:模型越简单越好。
regr = linear_model.Lasso()
scores = [regr.set_params(alpha=alpha
).fit(diabetes_X_train, diabetes_y_train
).score(diabetes_X_test, diabetes_y_test)
for alpha in alphas]
best_alpha = alphas[scores.index(max(scores))]
regr.alpha = best_alpha
regr.fit(diabetes_X_train, diabetes_y_train)
print(regr.coef_)
针对相同问题的不同算法:
不同的算法可以被用来解决相同的数学问题。例如scikit-learn中的Lasso对象使用coordinate decent方法解决lasso回归问题,在大数据集上是很有效的。然而,scikit-learn也使用LARS算法提供了LassoLars对象,对于处理权重向量非常稀疏的数据非常有效(数据的观测实例非常少)。
对于分类问题,比如iris标定任务,线性回归不是正确的方法。因为它会给数据得出大量远离决策边界的权重。一个线性方法是你和一个sigmoid函数或者logistic函数:
logistic = linear_model.LogisticRegression(C=1e5)
logistic.fit(iris_X_train, iris_y_train)
这就是有名的logistic回归。
如果你有多个类别需要预测,一个可行的方法是 “一对多”分类,接着根据投票决定最终的决策。
通过Logistic回归进行收缩和稀疏:
在LogisticRegression对象中C参数控制着正则化的数量:C越大,正则化数目越少。penalty= &12& 提供收缩(非稀疏化系数),penalty=&11&提供稀疏化。
尝试使用近邻算法和线性模型对数字数据集进行分类。留出最后的10%作为测试集用来测试预测的精确度。
from sklearn import datasets, neighbors, linear_model
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
【完整代码】
from sklearn import datasets, neighbors, linear_model
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
n_samples = len(X_digits)
X_train = X_digits[:.9 * n_samples]
y_train = y_digits[:.9 * n_samples]
X_test = X_digits[.9 * n_samples:]
y_test = y_digits[.9 * n_samples:]
knn = neighbors.KNeighborsClassifier()
logistic = linear_model.LogisticRegression()
print('KNN score: %f' % knn.fit(X_train, y_train).score(X_test, y_test))
print('LogisticRegression score: %f'
% logistic.fit(X_train, y_train).score(X_test, y_test))
(3)支持向量机(SVMs)
线性SVNs:
支持向量机属于判别模型家族:它们尝试寻找样例的一个组合,构建一个两类之间的最大边缘平面。通过C参数进行正则化:一个较小的C意味着边缘是通过分割线周围的所有观测样例进行计算得到的(更规整化,正则化);一个较大的C意味着边缘是通过邻近分割线的观测样例计算得到的(更少的规整化,正则化):
非正则化SVN:
正则化 SVM(默认):
样例:Plot different SVM分类器 iris数据集
SVMs能够被用于回归——SVR(支持向量回归)—用于分类——SVC(支持向量分类)
from sklearn import svm
svc = svm.SVC(kernel='linear')
svc.fit(iris_X_train, iris_y_train)
【警告】:规格化数据
对于大多数的估测模型,包括SVMs,处理好单位标准偏差对于获得一个好的预测是很重要的。
使用核函数:
在特征空间中类别不经常是线性可分的。解决方案是构建一个非线性但能用多项式代替的决策函数。这要通过核技巧实现:使用核可以被看作通过设置核在观测样例上创建决策力量。
多项式核:
径向基函数核(RBF,Radial Basis Function):
svc = svm.SVC(kernel='rbf')
交互式样例:
参照SVM GUI,下载svm_gui.通过鼠标左右键设置两类数据点,拟合模型并改变参数和数据。
尝试使用SVMs根据iris数据集前两个特征将其分成两类。留出每一类的10%作为测试样例。
【警告】数据集中的数据是按照分类顺序排列的,不要留出最后的10%作为测试样例,要不然你只能测试一种类别。(获取训练集和测试集是注意要进行混淆)
提示:你可以在一个网格上使用decision_function方法获得直观的呈现。
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y != 0, :2]
y = y[y != 0]
完整代码:
================================
SVM Exercise
================================
A tutorial exercise for using different SVM kernels.
This exercise is used in the :ref:`using_kernels_tut` part of the
:ref:`supervised_learning_tut` section of the :ref:`stat_learn_tut_index`.
print(__doc__)
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets, svm
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y != 0, :2]
y = y[y != 0]
n_sample = len(X)
np.random.seed(0)
order = np.random.permutation(n_sample)
X = X[order]
y = y[order].astype(np.float)
X_train = X[:.9 * n_sample]
y_train = y[:.9 * n_sample]
X_test = X[.9 * n_sample:]
y_test = y[.9 * n_sample:]
三、模型选择:选择模型和他们的参数
(1)分数,和交叉验证分数
众所周知,每一个模型会得出一个score方法用于裁决模型在新的数据上拟合的质量。其值越大越好。
from sklearn import datasets, svm
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
svc = svm.SVC(C=1, kernel='linear')
svc.fit(X_digits[:-100], y_digits[:-100]).score(X_digits[-100:], y_digits[-100:])
为了获得一个更好的预测精确度度量,我们可以把我们使用的数据折叠交错地分成训练集和测试集:
import numpy as np
X_folds = np.array_split(X_digits, 3)
y_folds = np.array_split(y_digits, 3)
scores = list()
for k in range(3):
这被称为KFold交叉验证
(2)交叉验证生成器
上面将数据划分为训练集和测试集的代码写起来很是沉闷乏味。scikit-learn为此自带了交叉验证生成器以生成目录列表:
from sklearn import cross_validation
k_fold = cross_validation.KFold(n=6, n_folds=3)
for train_indices, test_indices in k_fold:
print('Train: %s | test: %s' % (train_indices, test_indices))
接着交叉验证就可以很容易实现了:
kfold = cross_validation.KFold(len(X_digits), n_folds=3)
[svc.fit(X_digits[train], y_digits[train]).score(X_digits[test], y_digits[test])
for train, test in kfold]
为了计算一个模型的score,scikit-learn自带了一个帮助函数:
cross_validation.cross_val_score(svc, X_digits, y_digits, cv=kfold, n_jobs=-1)
n_jobs=-1意味着将计算任务分派个计算机的所有CPU.
交叉验证生成器:
KFold(n,k)&交叉分割,K-1上进行训练,生于数据样例用于测试
StratifiedKFold(y,K)&保存每一个fold的类比率/标签分布
leaveOneOut(n)&至预留一个观测样例
leaveOneLabelOut(labels)&采用一个标签数组把观测样例分组
使用digits数据集,绘制使用线性核的SVC进行交叉验证的分数(使用对数坐标轴,1——10)
import numpy as np
from sklearn import cross_validation, datasets, svm
digits = datasets.load_digits()
X = digits.data
y = digits.target
svc = svm.SVC(kernel='linear')
C_s = np.logspace(-10, 0, 10)
完整代码:
(3)网格搜索和交叉验证模型
网格搜索:
scikit-learn提供一个对象,他得到数据可以在采用一个参数的模型拟合过程中选择使得交叉验证分数最高的参数。该对象的构造函数需要一个模型作为参数:
from sklearn.grid_search import GridSearchCV
Cs = np.logspace(-6, -1, 10)
clf = GridSearchCV(estimator=svc, param_grid=dict(C=Cs),
n_jobs=-1)
clf.fit(X_digits[:1000], y_digits[:1000])
clf.best_score_
clf.best_estimator_.C
默认情况下,GridSearchCV使用3-fold交叉验证。然而,当他探测到是一个分类器而不是回归量,将会采用分层的3-fold。
嵌套 交叉验证
cross_validation.cross_val_score(clf, X_digits, y_digits)
两个交叉验证循环是并行执行的:一个GridSearchCV模型设置gamma,另一个使用cross_val_score&度量模型的预测表现。结果分数是在新数据预测分数的无偏差估测。
【警告】你不能在并行计算时嵌套对象(n_jobs不同于1)
交叉验证估测:
在算法by算法的基础上使用交叉验证去设置参数更高效。这也是为什么对于一个特定的模型/估测器引入Cross-validation:评估估测器表现模型去自动的通过交叉验证设置参数。
from sklearn import linear_model, datasets
lasso = linear_model.LassoCV()
diabetes = datasets.load_diabetes()
X_diabetes = diabetes.data
y_diabetes = diabetes.target
lasso.fit(X_diabetes, y_diabetes)
这些模型的称呼和他们的对应模型很相似,只是在他们模型名字的后面加上了'CV'.
使用糖尿病数据集,寻找最佳的正则化参数α
附加:你对选择的α值信任度有多高?
from sklearn import cross_validation, datasets, linear_model
diabetes = datasets.load_diabetes()
X = diabetes.data[:150]
y = diabetes.target[:150]
lasso = linear_model.Lasso()
alphas = np.logspace(-4, -.5, 30)
完整代码:
四、无监督学习:寻找数据的代表
(1)聚类:将观测样例聚集到一起
聚类解决的问题:
比如对于iris数据集,如果我们知道我们知道有三种iris,但是我们没有标签标定他们:我们可以尝试聚类任务:将观测样例分成分离的族群中,这些族群可以被称为簇。
K-mean聚类(K均值聚类)
注意存在很多不同的聚类标准和关联算法。最简的聚类算法是——K均值(K-means)
from sklearn import cluster, datasets
iris = datasets.load_iris()
X_iris = iris.data
y_iris = iris.target
k_means = cluster.KMeans(n_clusters=3)
k_means.fit(X_iris)
print(k_means.labels_[::10])
print(y_iris[::10])
注意:没有绝对的保证能够恢复真实的分类。首先,尽管scikit-learn使用很多技巧来缓和问题的难度,但选择簇的个数还是是很困难的,初始状态下算法是很敏感的,可能会陷入局部最小。
不好的初始状态:
真实情况:
不要“过解释”聚类结果
应用实例:矢量化
K-means和一般的聚类,可以看作是选择少量的示例压缩信息的方式。这个问题被称之为矢量化。例如,这可以被用于分离一个图像:
import scipy as sp
lena = sp.lena()
except AttributeError:
from scipy import misc
lena = misc.lena()
X = lena.reshape((-1, 1))
原始图像:
K-means矢量化:
等段:(Equal bins)
图像直方图:
分层凝聚聚类:Ward
分层聚类方法是一种针对构建一个簇的分层的簇分析。通常它的实现方式有以下两种:
凝聚:自下而上的方法:每一个观测样例开始于他自己的簇,以一种最小连接标准迭代合并。这种方法在观测样例较少的情况下非常有效(有趣)。当簇的数量变大时,计算效率比K-means高的多。分裂:自上而下的方法:所有的观测样例开始于同一个簇。迭代的进行分层。对于预计簇很多的情况,这种方法既慢(由于所有的观测样例作为一个簇开始的,是递归进行分离的)又有统计学行的病态。
连同-驱使聚类(Conectivity-constrained clustering)
使用凝聚聚类,通过一个连通图可以指定某些样例能被聚集在一起。scikit-learn中的图通过邻接矩阵来表示,且通常是一个稀疏矩阵。例如,在聚类一张图片时检索连通区域(有时也被称作连同单元、部件):
from sklearn.feature_extraction.image import grid_to_graph
from sklearn.cluster import AgglomerativeClustering
特征凝聚:
我们已经知道稀疏性可以缓和高维灾难。i.e相对于特征数量观测样例数量不足的情况。另一种方法是合并相似的特征:特征凝聚。这种方法通过在特征方向上进行聚类实现。在特征方向上聚类也可以理解为聚合转置的数据。
digits = datasets.load_digits()
images = digits.images
X = np.reshape(images, (len(images), -1))
connectivity = grid_to_graph(*images[0].shape)
agglo = cluster.FeatureAgglomeration(connectivity=connectivity,
n_clusters=32)
agglo.fit(X)
X_reduced = agglo.transform(X)
X_approx = agglo.inverse_transform(X_reduced)
images_approx = np.reshape(X_approx, images.shape)
transeform&和invers_transeform方法
有些模型带有转置方法。例如用来降低数据集的维度
(2)分解:从一个信号到成分和加载
成分及其加载:
如果X是我们的多变量数据,那么我们要要尝试解决的问题就是在不同的观测样例上复写写它:我们想要学习加载L和其它一系列的成分C,如X = LC。存在不同的标准和条件去选择成分。
主成分分析:PCA
主成分分析(PCA)选择在信号上解释极大方差的连续成分。
上面观测样例的点分布在一个方向上是非常平坦的:三个特征单变量的一个甚至可以有其他两个准确的计算出来。PCA用来发现数据在哪个方向上是不平坦的。
当被用来转换数据的时候,PCA可以通过投射到一个主子空间来降低数据的维度。:
独立成分分析:ICA
独立成分分析(ICA)选择合适的成分使得他们的分布载有最大的独立信息量。可以恢复非高斯独立信号:
五、联合起来
(1)管道(流水线)
我们已经知道了一些估测器(模型)能够转换数据,一些可以预测变量。我们也能够将其结合到一起:
from sklearn import linear_model, decomposition, datasets
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
logistic = linear_model.LogisticRegression()
pca = decomposition.PCA()
pipe = Pipeline(steps=[('pca', pca), ('logistic', logistic)])
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
(2)使用特征联进行人脸识别
该实例使用的数据集是从“Labeled Faces in the Wild”节选预处理得到的。更为熟知的名字是LFW。
===================================================
Faces recognition example using eigenfaces and SVMs
===================================================
The dataset used in this example is a preprocessed excerpt of the
&Labeled Faces in the Wild&, aka LFW_:
http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz (233MB)
.. _LFW: http://vis-www.cs.umass.edu/lfw/
Expected results for the top 5 most represented people in the dataset::
Gerhard_Schroeder
Donald_Rumsfeld
Tony_Blair
Colin_Powell
George_W_Bush
avg / total
from __future__ import print_function
from time import time
import logging
import matplotlib.pyplot as plt
from sklearn.cross_validation import train_test_split
from sklearn.datasets import fetch_lfw_people
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import RandomizedPCA
from sklearn.svm import SVC
print(__doc__)
数据集中最有代表性的五个人脸的期望结果:
precision recall f1-score support
Gerhard_Schroeder 0.91 0.75 0.82 28
Donald_Rumsfeld 0.84 0.82 0.83 33
Tony_Blair 0.65 0.82 0.73 34
Colin_Powell 0.78 0.88 0.83 58
George_W_Bush 0.93 0.86 0.90 129
avg / total
(3)开放性问题:股票市场结构
我们是否可以根据给定的时间帧预测股票的价格变化。
[学习一个图结构]
六、寻求帮助
###(1)项目邮件列表
如果你碰到scikit-learn的BUG或者文档中需要澄清声明的部分,请放心大胆的在邮件列表里询问[maillist]
(2)问答(Q&A)机器学习从业者参与的社区
Metaoptimize/QA:
一个 机器学习、自然语言处理和其他数据分析方面讨论的论坛(类似针对开发者的Stackoverflow):
一个比较容易开始参与的讨论:good freely available textbooks on machine learning(机器学习方面优秀的免费电子书)
Quora 有一个关于机器学习相关的问题主题,也有很多有趣的讨论:
浏览一下最佳问题的部分,例如:What are some good resources for learning about machine learning(关于机器学习的优秀资源有哪些)
---斯坦福的 Andrew Ng教授 教授的 关于机器学习的优秀在线免费课程
{网易公开课有,搜一下机器学习就可以了}
---一个更倾向于人工智能(AI)的优秀在线课程:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:28518次
排名:千里之外
转载:120篇
(1)(3)(2)(9)(14)(3)(39)(1)(3)(1)(1)(1)(2)(3)(3)(5)(10)(13)(8)(3)(3)

我要回帖

更多关于 lammps输出dump文件 的文章

 

随机推荐