Python机器学习(十)经典算法大全

开通VIP,畅享免费电子书等14项超值服

首页

好书

留言交流

下载APP

联系客服

2021.12.12

由于knn算法涉及到距离的概念,KNN算法需要先进行归一化处理

fromsklearn.preprocessingimportStandardScalerstandardScaler=StandardScaler()standardScaler.fit(X_train)X_train_standard=standardScaler.transform(X_train)X_test_standard=standardScaler.transform(X_test)归一化之后送入模型进行训练

fromsklearn.neighborsimportKNeighborsClassifierknn_clf=KNeighborsClassifier(n_neighbors=8)knn_classifier.fit(X_train_standard,y_train)y_predict=knn_clf.predict(X_test_standard)#默认的预测指标为分类准确度knn_clf.score(X_test,y_test)1.2网格搜索GridSearchCV使用网格搜索来确定KNN算法合适的超参数

fromsklearn.neighborsimportKNeighborsClassifierknn_clf=KNeighborsClassifier(n_neighbors=8)knn_classifier.fit(X_train_standard,y_train)y_predict=knn_clf.predict(X_test_standard)#默认的预测指标为分类准确度knn_clf.score(X_test,y_test)1.3交叉验证defcv_score_train_test(model):num_cv=5score_list=["accuracy","f1","neg_log_loss","roc_auc"]forscoreinscore_list:print(score,"\ttrain:",cross_val_score(model,X_train,y_train,cv=num_cv,scoring=score).mean())print(score,"\ttest:",cross_val_score(model,X_test,y_test,cv=num_cv,scoring=score).mean())2.线性回归2.1简单线性回归fromsklearn.linear_modelimportLinearRegressionlinreg=LinearRegression()linreg.fit(X_train,y_train)#查看截距和系数printlinreg.intercept_printlinreg.coef_lin_reg.score(X_test,y_test)y_predict=linreg.predict(X_test)2.2多元线性回归在更高维度的空间中的“直线”,即数据不只有一个维度,而具有多个维度

代码和上面的简单线性回归相同

使用梯度下降法之前,需要对数据进行归一化处理

回到顶部

SGD_reg

fromsklearn.linear_modelimportSGDRegressorsgd_reg=SGDRegressor(max_iter=100)sgd_reg.fit(X_train_standard,y_train_boston)sgd_reg.score(X_test_standard,y_test_boston)3.2确定梯度下降计算的准确性以多元线性回归的目标函数(损失函数)为例

比较使用数学推导式(得出具体解析解)的方法和debug的近似方法的比较

PCA算法不能在前处理进行归一化处理,否则将会找不到主成分

#对于二维的数据样本来说fromsklearn.decompositionimportPCApca=PCA(n_components=1)#指定需要保留的前n个主成分,不指定为默认保留所有pca.fit(X)比如,要使用KNN分类算法,先进行数据的降维操作

fromsklearn.decompositionimportPCApca=PCA(n_components=2)#这里也可以给一个百分比,代表想要保留的数据的方差占比pca.fit(X_train)#训练集和测试集需要进行相同降维处理操作X_train_reduction=pca.transform(X_train)X_test_reduction=pca.transform(X_test)#降维完成后就可以送给模型进行拟合knn_clf=KNeighborsClassifier()knn_clf.fit(X_train_reduction,y_train)knn_clf.score(X_test_reduction,y_test)4.2降维的维数和精度的取舍指定的维数,能解释原数据的方差的比例

pca.explained_variance_ratio_#指定保留所有的主成分pca=PCA(n_components=X_train.shape[1])pca.fit(X_train)pca.explained_variance_ratio_#查看降维后特征的维数pca.n_components_把数据降维到2维,可以进行scatter的可视化操作

先使用pca降维,之后再反向,升维

fromsklearn.decompositionimportPCApca=PCA(0.7)pca.fit(X)pca.n_components_X_reduction=pca.transform(X)X_inversed=pca.inverse_transform(X_reduction)5.多项式回归与模型泛化多项式回顾需要指定最高的阶数,degree

拟合的将不再是一条直线

如果非要把上两者写在一起,应该把指定好param_grid参数的grid_search作为成员,传递给Pipeline

首先明确:

fromsklearn.linear_modelimportRidgefromsklearn.preprocessingimportPolynomialFeaturesfromsklearn.preprocessingimportStandardScalerfromsklearn.pipelineimportPipelinedefRidgeRegression(degree,alpha):returnPipeline([("poly",PolynomialFeatures(degree=degree)),("std_scaler",StandardScaler()),("ridge_reg",Ridge(alpha=alpha))])ridge_reg=RidgeRegression(degree=20,alpha=0.0001)ridge_reg.fit(X_train,y_train)y_predict=ridge_reg.predict(X_test)mean_squared_error(y_test,y_predict)代码中:

alpha为L2正则项前面的系数,代表的含义与LASSO回归相同

Ridge回归、LASSO回归的区别

fromsklearn.linear_modelimportLassofromsklearn.preprocessingimportPolynomialFeaturesfromsklearn.preprocessingimportStandardScalerfromsklearn.pipelineimportPipelinedefLassoRegression(degree,alpha):returnPipeline([("poly",PolynomialFeatures(degree=degree)),("std_scaler",StandardScaler()),("lasso_reg",Lasso(alpha=alpha))])lasso_reg=LassoRegression(3,0.01)lasso_reg.fit(X_train,y_train)y_predict=lasso_reg.predict(X_test)mean_squared_error(y_test,y_predict)6.逻辑回归将样本特征与样本发生的概率联系起来。

plot_decision_boundary(poly_log_reg,axis=[-4,4,-4,4])plt.scatter(X[y==0,0],X[y==0,1])plt.scatter(X[y==1,0],X[y==1,1])plt.show()6.3逻辑回归中的正则化项和惩罚系数C公式为:

C*J(θ)+L1

C*J(θ)+L2

上式中:

scikit封装了OvOOvR这两个类,方便其他二分类算法,使用这两个类实现多分类

例子中:log_reg是已经创建好的逻辑回归二分类器

fromsklearn.multiclassimportOneVsRestClassifierovr=OneVsRestClassifier(log_reg)ovr.fit(X_train,y_train)ovr.score(X_test,y_test)fromsklearn.multiclassimportOneVsOneClassifierovo=OneVsOneClassifier(log_reg)ovo.fit(X_train,y_train)ovo.score(X_test,y_test)7.支撑向量机SVM注意

支撑向量机要满足的优化目标是:

使“最优决策边界”到与两个类别的最近的样本的距离最远

即,使得margin最大化

分为:

为了改善SVM模型的泛化能力,需要进行正则化处理,同样有L1、L2正则化

正则化即弱化限定条件,使得某些样本可以不再Margin区域内

惩罚系数C是乘在正则项前面的

min12||w||2+C∑i=1mξi,L1正则项min12||w||2+C∑i=1mξi,L1正则项

min12||w||2+C∑i=1mξ2i,L2正则项min12||w||2+C∑i=1mξi2,L2正则项

变化规律:

fromsklearn.preprocessingimportStandardScalerstandardScaler=StandardScaler()standardScaler.fit(X)X_standard=standardScaler.transform(X)fromsklearn.svmimportLinearSVCsvc=LinearSVC(C=1e9)svc.fit(X_standard,y)简洁起见,可以用Pipeline包装起来

fromsklearn.preprocessingimportStandardScalerfromsklearn.svmimportLinearSVCfromsklearn.pipelineimportPipelinedefLinear_svc(C=1.0):returnPipeline([("std_scaler",StandardScaler()),("linearSVC",LinearSVC(C=C))])linear_svc=Linear_svc(C=1e5)linear_svc.fit(X,y)7.3多项式特征SVM明确:使用多项式核函数的目的都是将数据升维,使得原本线性不可分的数据变得线性可分

在SVM中使用多项式特征有两种方式

fromsklearn.preprocessingimportStandardScalerfromsklearn.svmimportSVCfromsklearn.pipelineimportPipelinedefRBFkernelSVC(gamma=1.0):returnPipeline([("std_standard",StandardScaler()),("svc",SVC(kernel="rbf",gamma=gamma))])svc=RBFkernelSVC(gamma=1.0)svc.fit(X,y)超参数gammaγγ规律:

若gamma太大,会造成过拟合

若gamma太小,会造成欠拟合,决策边界变为直线

指定margin区域垂直方向上的距离epsilon

通用可以分为线性SVR和多项式SVR

fromsklearn.preprocessingimportStandardScalerfromsklearn.svmimportLinearSVRfromsklearn.svmimportSVRfromsklearn.pipelineimportPipelinedefStandardLinearSVR(epsilon=0.1):returnPipeline([("std_scaler",StandardScaler()),("linearSVR",LinearSVR(epsilon=epsilon))])svr=StandardLinearSVR()svr.fit(X_train,y_train)svr.score(X_test,y_test)#可以使用cross_val_score来获得交叉验证的成绩,成绩更加准确8.决策树非参数学习算法、天然可解决多分类问题、可解决回归问题(取叶子结点的平均值)、非常容易产生过拟合

可以考虑使用网格搜索来寻找最优的超参数

划分的依据有基于信息熵、基于基尼系数(scikit默认用gini,两者没有特别优劣之分)

ID3、C4.5都是使用“entropy"评判方式

CART(ClassificationandRegressionTree)使用的是“gini"评判方式

常用超参数:

fromsklearn.treeimportDecisionTreeClassifierdt_clf=DecisionTreeClassifier(max_depth=2,criterion="gini")#dt_clf=DecisionTreeClassifier(max_depth=2,criterion="entropy")dt_clf.fit(X,y)8.2回归fromsklearn.treeimportDecisionTreeRegressordt_reg=DecisionTreeRegressor()dt_reg.fit(X_train,y_train)dt_reg.score(X_test,y_test)#计算的是R2值9.集成学习和随机森林9.1HardVotingClassifier把几种分类模型包装在一起,根据每种模型的投票结果来得出最终预测类别

可以先使用网格搜索把每种模型的参数调至最优,再来Voting

所以,每种模型都应该能估计结果的概率

(2)这类集成学习方法需要指定一个baseestimator

(3)放回取样,会存在oob(outofbag)的样本数据,比例约37%,正好作为测试集

obb_score=True/False,是否使用oob作为测试集

(4)产生差异化的方式:

random_subspaces_clf=BaggingClassifier(DecisionTreeClassifier(),n_estimators=500,max_samples=500,bootstrap=True,oob_score=True,n_jobs=-1,max_features=1,bootstrap_features=True)random_subspaces_clf.fit(X,y)random_subspaces_clf.oob_score_random_patches_clf=BaggingClassifier(DecisionTreeClassifier(),n_estimators=500,max_samples=100,bootstrap=True,oob_score=True,n_jobs=-1,max_features=1,bootstrap_features=True)random_patches_clf.fit(X,y)random_patches_clf.oob_score_参数解释:

max_samples:如果和样本总数一致,则不进行样本随机采样

max_features:指定随机采样特征的个数(应小于样本维数)

bootstrap_features:指定是否进行随机特征采样

oob_score:指定是都用oob样本来评分

bootstrap:指定是否进行放回取样

随机森林是指定了BaseEstimator为DecisionTree的Bagging集成学习模型

已经被scikit封装好,可以直接使用

特点:

决策树在结点划分上,使用随机的特征和阈值

提供了额外的随机性,可以抑制过拟合,但会增大Bias(偏差)

具有更快的训练速度

fromsklearn.ensembleimportExtraTreesRegressoret_clf=ExtraTreesClassifier(n_estimators=500,bootstrap=True,oob_score=True,random_state=666)et_clf.fit(X,y)et_clf.oob_score_9.5AdaBoosting每个子模型模型都在尝试增强(boost)整体的效果,通过不断的模型迭代,更新样本点的权重

AdaBoosting没有oob的样本,因此需要进行train_test_split

需要指定BaseEstimator

fromsklearn.ensembleimportAdaBoostClassifierfromsklearn.treeimportDecisionTreeClassifierada_clf=AdaBoostClassifier(DecisionTreeClassifier(max_depth=2),n_estimators=500)ada_clf.fit(X_train,y_train)ada_clf.score(X_test,y_test)9.6GradientBoosting训练一个模型m1,产生错误e1

针对e1训练第二个模型m2,产生错误e2

针对e2训练第二个模型m3,产生错误e3

......

最终的预测模型是:m1+m2+m3+...m1+m2+m3+...

GradientBoosting是基于决策树的,不用指定BaseEstimator

fromsklearn.ensembleimportGradientBoostingClassifiergb_clf=GradientBoostingClassifier(max_depth=2,n_estimators=30)gb_clf.fit(X_train,y_train)gb_clf.score(X_test,y_test)总结上述提到的集成学习模型,不仅可以用于解决分类问题,也可解决回归问题

fromsklearn.ensembleimportBaggingRegressorfromsklearn.ensembleimportRandomForestRegressorfromsklearn.ensembleimportExtraTreesRegressorfromsklearn.ensembleimportAdaBoostRegressorfromsklearn.ensembleimportGradientBoostingRegressor例子:决策树和AdaBoosting回归问题效果对比

本例的notebook笔记文件:git仓库

实例代码:

frommatplotlibimportpyplotaspltfromsklearn.metricsimportaccuracy_scoreimportnumpyasnpimportseabornassns;sns.set()%matplotlibinline10.1传统K-means聚类构造数据集

fromsklearn.datasets.samples_generatorimportmake_blobsX,y_true=make_blobs(n_samples=300,centers=4,cluster_std=0.60,random_state=0)plt.scatter(X[:,0],X[:,1],s=50)fromsklearn.clusterimportKMeanskmeans=KMeans(n_clusters=4)kmeans.fit(X)y_kmeans=kmeans.predict(X)绘制聚类结果,画出聚类中心

构造数据

fromsklearn.datasetsimportmake_moonsX,y=make_moons(200,noise=0.05,random_state=0)传统kmeans聚类失败的情况

fromsklearn.datasetsimportload_digitsdigits=load_digits()进行聚类

kmeans=KMeans(n_clusters=10,random_state=0)clusters=kmeans.fit_predict(digits.data)kmeans.cluster_centers_.shape(10,64)可以将这些族中心点看做是具有代表性的数字

通过流形学习

投影到低维空间

且k-means算法只对简单的,分离性能好的,并且是圆形分布的数据有比较好的效果

本例中所有代码的实现已上传至git仓库

通过实例来观察K-means算法的缺陷

半径是根据最远的点与族中心点的距离算出

下面用一个函数将这个聚类圆圈可视化

在默认参数设置的、数据简单可分的情况下,

GMM的分类效果与k-means基本相同

probs=gmm.predict_proba(X)print(probs[:5].round(3))[[0.0.4690.0.531][1.0.0.0.][1.0.0.0.][0.0.0.1.][1.0.0.0.]]编写绘制gmm绘制边界的函数

一个GMM拟合的结果并不是一个聚类模型,而是描述数据分布的生成概率模型。

分布函数的生成模型可以生成新的,与输入数据类似的随机分布函数(生成新的数据点)

用GMM拟合原始数据获得的16个成分生成的400个新数据点

常用指标选择方式

平衡分类问题:

分类准确度、ROC曲线

类别不平衡问题:

精准率、召回率

对于二分类问题,常用的指标是f1、roc_auc

多分类问题,可用的指标为f1_weighted

一般用于平衡分类问题(每个类比的可能性相同)

fromsklearn.metricsimportaccuracy_scoreaccuracy_score(y_test,y_predict)#(真值,预测值)2.混淆矩阵、精准率、召回率#先真实值,后预测值fromsklearn.metricsimportconfusion_matrixconfusion_matrix(y_test,y_log_predict)fromsklearn.metricsimportprecision_scoreprecision_score(y_test,y_log_predict)fromsklearn.metricsimportrecall_scorerecall_score(y_test,y_log_predict)多分类问题中的混淆矩阵

fromsklearn.metricsimportprecision_scoreprecision_score(y_test,y_predict,average="micro")fromsklearn.metricsimportconfusion_matrixconfusion_matrix(y_test,y_predict)cfm=confusion_matrix(y_test,y_predict)row_sums=np.sum(cfm,axis=1)err_matrix=cfm/row_sumsnp.fill_diagonal(err_matrix,0)plt.matshow(err_matrix,cmap=plt.cm.gray)plt.show()3.F1-scoreF1-score是精准率precision和召回率recall的调和平均数

fromsklearn.metricsimportf1_scoref1_score(y_test,y_predict)4.精准率和召回率的平衡可以通过调整阈值,改变精确率和召回率(默认阈值为0)

但是,这个最大的threshold没有对应的值

因此thresholds会少一个

绘制ROC曲线

fromsklearn.metricsimportroc_curvefprs,tprs,thresholds=roc_curve(y_test,decision_scores)plt.plot(fprs,tprs)plt.show()计算ROC曲线下方的面积的函数

roc_area_under_curve_score

fromsklearn.metricsimportroc_auc_scoreroc_auc_score(y_test,decision_scores)曲线下方的面积可用于比较两个模型的好坏

总之,上面提到的decision_score是一个概率值,如01二分类问题,应该是将每个样本预测为1的概率,

如某个样本的y_test为1,y_predict_probablity为0.875

每个测试样本对应一个预测的概率值

通常在模型fit完成之后,都会有相应的得到概率的函数,如

model.predict_prob(X_test)

model.decision_function(X_test)

fromsklearn.metricsimportmean_squared_errormean_squared_error(y_test,y_predict)2.平均绝对值误差MAEfromsklearn.metricsimportmean_absolute_errormean_absolute_error(y_test,y_predict)3.均方根误差RMSEscikit中没有单独定于均方根误差,需要自己对均方误差MSE开平方根

fromsklearn.metricsimportr2_scorer2_score(y_test,y_predict)5.学习曲线观察模型在训练数据集和测试数据集上的评分,随着训练数据集样本数增加的变化趋势。

THE END
1.高中数学127个快速解题公式!赶紧收藏!!(4)热爱数学, 喜欢钻研探讨数学问题;和学生一起思考数学问题,解决问题是我最大的快乐。 用数学锻炼思维,用数学开启智慧 今天收集到了127个高中数学快速解题公式,希望对高中的同学们学习有用。 声明:本文来自网络 贵在分享,版权归原作者及原出处所有,若涉及版权等问题请联系删除。 https://zhuanlan.zhihu.com/p/10047406595
2.小学数学简便运算定律与简便计算知识讲解大盘点!交换律分配律注意:加法结合律有着广泛的应用,如果其中有两个加数的和刚好是整十、整百、整千的话,那么就可以利用加法交换律将原式中的加数进行调换位置,再将这两个加数结合起来先运算。例1.用简便方法计算下式:(1)63+16+84 (2)76+15+24 (3)140+639+860举一反三:(1)46+67+54 (2)680+485+120 (3)155+657+https://m.163.com/dy/article/JJN99GMG05566S5I.html
3.10大计算机经典算法「建议收藏」腾讯云开发者社区10大计算机经典算法「建议收藏」 大家好,又见面了,我是你们的朋友全栈君。 算法一:快速排序法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,https://cloud.tencent.com/developer/article/2089934
4.计算机10大经典算法计算机经典算法尽管存在最坏情况时间复杂度较高的风险,但由于其优秀的平均性能和较低的空间复杂度,快速排序仍然是许多实际应用中的首选排序算法。 归并排序 归并排序是一种经典的分治算法,其优雅的设计体现了算法设计中的智慧。这种排序方法的核心思想是将一个大问题分解为多个小问题来解决,然后再将小问题的解合并为大问题的解。 https://blog.csdn.net/2401_86544677/article/details/143141716
5.(PDF)经典算法大全YiHuaQin解法字串搜寻本身不难,使用暴力法也可以求解,但如何快速搜寻字串就不简单了,传统的字串搜寻是从关键字与字串的开头开始比对,例如 Knuth-Morris-Pratt 演算法 字串搜寻,这个方法也不错,不过要花时间在公式计算上;Boyer-Moore字串核对改由关键字的后面开始核对字串,并制作前进表,如果比对不符合则依前进表中的值https://www.academia.edu/35548539/%E7%BB%8F%E5%85%B8%E7%AE%97%E6%B3%95%E5%A4%A7%E5%85%A8
6.经典算法大全.pdf数据结构与算法经典算法大全.pdf 129页内容提供方:188***8634 大小:1.09 MB 字数:约10.44万字 发布时间:2019-05-10发布于浙江 浏览人气:1065 下载次数:仅上传者可见 收藏次数:0 需要金币:*** 金币 (10金币=人民币1元)经典算法大全.pdf 关闭预览 想预览更多内容,点击免费在线预览全文 免费在线预览https://max.book118.com/html/2019/0510/6202231235002030.shtm
7.c语言经典算法合集C 语言经典算法大全 老掉牙 河内塔 费式数列 巴斯卡三角形 三色棋 老鼠走迷官一 老鼠走迷官二 骑士走棋盘 八个皇后 八枚银币 生命游戏 字串核对 双色三色河内塔 背包问题 Knapsack Problem 数运算 蒙地卡罗法求 PI Eratosthenes 筛选求质数 超长整数运算大数运算 长PI 最大公因数最小公倍数因式分解 完美数 阿姆https://wenku.baidu.com/aggs/15d2a38102d276a200292ee7.html
8.PID控制算法大全(经典)PID控制算法大全(经典),以前开发四轴飞行器时,收集整理的,很不错点赞(0) 踩踩(0) 反馈 所需:1 积分 电信网络下载 模拟退火算法 Python代码 2024-12-15 19:36:07 积分:1 python基础九大数据类型汇总-超详细 2024-12-15 19:26:46 积分:1 https://www.coder100.com/index/index/content/id/1370149
9.178个经典c语言源代码+算法大全简介:C语言178个经典代码,学习C必备参考文档。 算法C语言代码 声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。举报投诉 https://www.elecfans.com/soft/Mec/2023/202311212315595.html
10.C语言经典算法100例中文pdf版2.80MB电子书下载c语言经典算法大全pdf 投诉报错 书籍大小:2.80MB 书籍语言:简体中文 书籍类型:国产软件 书籍授权:免费软件 书籍类别:C/C++ 应用平台:PDF 更新时间:2016-06-18 购买链接:京东异步社区 网友评分: 360通过腾讯通过金山通过 2.80MB 广告 商业广告,理性选择广告 商业广告,理性选择广告 商业广告,理性选择广告 商业广告,理https://www.jb51.net/books/469720.html
11.java经典100例算法题java经典100例算法题.pdf阅读:32次|页数:34页|上传:2020-07-12 09:31 【程序【程序【程序111】】】 题目:有题目:有题目:有111、、、222、、、333、、、444个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?个数字,能组成多少个互https://www.docin.com/touch/detail.do?id=2402905646
12.十大经典预测算法理想股票技术论坛探讨股票领域中最具影响力的十大经典预测算法,帮助投资者了解如何利用数据科学模型预测市场走势,提高投资决策的准确性和效率。 ,理想股票技术论坛https://www.55188.com/tag-7329966.html
13.经典算法大全(各类算法解析)经典算法大全(各类算法解析) 评分: 经典算法大全各类算法解析 1.河内之塔 2.Algorithm Gossip: 费式数列 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官 算法 2010-09-12 上传 大小:1313KB 所需: 41积分/C币 立即下载 常见各类算法的教程https://www.iteye.com/resource/xyz97965-2690257
14.wantdeeptester/CS超过1000本的计算机经典书籍、个人笔记资料以及本人在各平台发表文章中所涉及的资源等。书籍资源包括C/C++、Java、Python、Go语言、数据结构与算法、操作系统、后端架构、计算机系统知识、数据库、计算机网络、设计模式、前端、汇编以及校招社招各种面经~ - wantdeehttps://github.com/wantdeeptester/CS-Books
15.算法竞赛入门经典第二版+训练指南第2版算法艺术与信息学竞赛《算法竞赛入门经典(第2版)》是一本算法竞赛的入门与提高教材,把c/c++语言、算法和解题有机地结合在一起,淡化理论,注重学习方法和实践技巧。全书内容分为12 章,包括程序设计入门、循环结构程序设计、数组和字符串、函数和递归、c++与stl入门、数据结构基础、暴力求解法、高效算法设计、动态规划初步、数学概念与方法http://product.dangdang.com/641939543.html