# DolphinDB教程:机器学习 DolphinDB实现了一系列常用的机器学习算法,例如最小二乘回归、随机森林、K-平均等,使用户能够方便地完成回归、分类、聚类等任务。这篇教程会通过具体的例子,介绍用DolphinDB脚本语言进行机器学习的流程。本文的所有例子都基于DolphinDB 1.10.11。 - [1. 第一个例子:对小样本数据进行分类](#1-第一个例子对小样本数据进行分类) - [2. 分布式机器学习](#2-分布式机器学习) - [3. 使用PCA为数据降维](#3-使用pca为数据降维) - [4. 使用DolphinDB插件进行机器学习](#4-%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E4%BB%A5%E5%8F%8Aridgelassoelasticnet%E5%9B%9E%E5%BD%92) - [附录:DolphinDB机器学习函数](#附录dolphindb机器学习函数) ## 1. 第一个例子:对小样本数据进行分类 我们用[UCI Machine Learning Repository](http://archive.ics.uci.edu/ml/)上的[wine](http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data)数据,用来完成第一个随机森林分类模型的训练。 ### 1.1 加载数据 将数据下载到本地后,在DolphinDB中用`loadText`导入: ``` wineSchema = table( `Label`Alcohol`MalicAcid`Ash`AlcalinityOfAsh`Magnesium`TotalPhenols`Flavanoids`NonflavanoidPhenols`Proanthocyanins`ColorIntensity`Hue`OD280_OD315`Proline as name, `INT`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE as type ) wine = loadText("D:/dataset/wine.data", schema=wineSchema) ``` ### 1.2 数据预处理 DolphinDB的`randomForestClassifier`函数要求类的标签的取值是[0, classNum)之间的整数。下载得到的wine数据的分类标签为1, 2, 3,需要更新为0, 1, 2: ``` update wine set Label = Label - 1 ``` 将数据按7:3分为训练集和测试集。本例编写了一个`trainTestSplit`函数以便划分。 ``` def trainTestSplit(x, testRatio) { xSize = x.size() testSize = xSize * testRatio r = (0..(xSize-1)).shuffle() return x[r > testSize], x[r <= testSize] } wineTrain, wineTest = trainTestSplit(wine, 0.3) wineTrain.size() // 124 wineTest.size() // 54 ``` ### 1.3 使用`randomForestClassifier`进行随机森林分类 对训练集调用`randomForestClassifier`函数进行随机森林分类。该函数有四个必选参数,分别是: - ds: 输入的数据源,本例中用`sqlDS`函数生成。 - yColName: 数据源中因变量的列名。 - xColNames: 数据源中自变量的列名。 - numClasses: 类的个数。 ``` model = randomForestClassifier( sqlDS().transDS!(preprocess) ``` ### 2.2 调用`logisticRegression`函数训练 函数`logisticRegression`有三个必选参数: - ds: 输入的数据源。 - yColName: 数据源中因变量的列名。 - xColNames: 数据源中自变量的列名。 上一节已经生成了输入的数据源,可以直接用作参数。 ``` model = logisticRegression(ds, `Target, `Open`High`Low`Close`OpenClose`OpenOpen`S_10`RSI`Corr) ``` 用训练的模型对一支股票的数据进行预测并计算分类准确率: ``` aapl = preprocess(select * from ohlc where Ticker = `AAPL) predicted = model.predict(aapl) score = sum(predicted == aapl.Target) \ aapl.size() // 0.756522 ``` ## 3. 使用PCA为数据降维 主成分分析(Principal Component Analysis, 简称PCA)是机器学习中的常用分析。如果数据的维度太高,学习算法的效率可能很低下,通过PCA,将高维数据映射到低维空间,同时尽可能最小化信息损失,可以解决维度过多的问题。PCA的另一个应用是数据可视化,二维或三维的数据能便于用户理解。 以[对wine数据进行分类](#1-第一个例子对小样本数据进行分类)为例,输入的数据集有13个因变量,对数据源调用`pca`函数,观察各主成分的方差权重。将normalize参数设为true,以对数据进行归一化处理。 ``` xColNames = `Alcohol`MalicAcid`Ash`AlcalinityOfAsh`Magnesium`TotalPhenols`Flavanoids`NonflavanoidPhenols`Proanthocyanins`ColorIntensity`Hue`OD280_OD315`Proline pcaRes = pca( sqlDS() ds.transDS!(principalComponents{, components, `Class, xColNames}) model = randomForestClassifier(ds, yColName=`Class, xColNames=`col0`col1`col2, numClasses=3) ``` 对测试集进行预测时,也需要提取测试集的主成分: ``` model.predict(wineTest.principalComponents(components, `Class, xColNames)) ``` ## 4. 线性回归以及Ridge、Lasso、ElasticNet回归 DolphinDB提供了ols和olsEx函数进行最小二乘回归(线性回归),一般在维度较低的数据上比较有效,维度比较大时会出现过拟合的现象。 Ridge,Lasso以及ElasticNet回归,是在最小二乘回归的基础上的改进,他们在不同的方面改进了这个问题。 Lasso在目标函数中加上L1正则,会使得部分学习到的特征权值为0,从而达到稀疏化和特征选择的目的。Ridge在目标函数中加上L2惩罚项,使得系数的绝对值变小。ElasticNet则是同时加上L1和L2惩罚项。 在DolphinDB中,这三个函数的接口分别是: ``` elasticNet(ds, yColName, xColNames, [alpha=1.0], [l1Ratio=0.5], [intercept=true], [normalize=false], [maxIter=1000], [tolerance=0.0001], [positive=false]) lasso(ds, yColName, xColNames, [alpha=1.0], [intercept=true], [normalize=false][maxIter=1000], [tolerance=0.0001], [positive=false]) ridge(ds, yColName, xColNames, [alpha=1.0], [intercept=true], [normalize=false], [maxIter=1000], [tolerance=0.0001], [solver='svd']) ``` 三个函数的都有必选参数: - ds: 数据源或者内存表 - yColName: 标签列的列名 - xColNames: 数据列的列名 lasso是elasticNet 在 l1Ratio = 1时的特例,用的是相同的实现方法,使用坐标下降法求参数。ridge使用的是解析解,solver可以是svd或者cholesky。 训练模型: ``` model = lasso(sqlDS(