• 机器学习算法-java

    2020-06-24 20:39:03
    机器学习算法-java版,是个不错的图书,大家可以下载看一下
  • ...基于Java8实现。 算法目录 常用的标准数据挖掘算法 包名 目录名 算法名 AssociationAnalysis DataMining_Apriori Apriori-关联规则挖掘算法 AssociationAnalysis Da...

    https://python.ctolib.com/article/wiki/95851

    数据挖掘十大类经典算法

    基于Java8实现。

    算法目录

    常用的标准数据挖掘算法

    包名 目录名 算法名
    AssociationAnalysis DataMining_Apriori Apriori-关联规则挖掘算法
    AssociationAnalysis DataMining_FPTree FPTree-频繁模式树算法
    BaggingAndBoosting DataMining_AdaBoost AdaBoost-装袋提升算法
    Classification DataMining_CART CART-分类回归树算法
    Classification DataMining_ID3 ID3-决策树分类算法
    Classification DataMining_KNN KNN-k最近邻算法工具类
    Classification DataMining_NaiveBayes NaiveBayes-朴素贝叶斯算法
    Clustering DataMining_BIRCH BIRCH-层次聚类算法
    Clustering DataMining_KMeans KMeans-K均值算法
    GraphMining DataMining_GSpan GSpan-频繁子图挖掘算法
    IntegratedMining DataMining_CBA CBA-基于关联规则的分类算法
    LinkMining DataMining_HITS HITS-链接分析算法
    LinkMining DataMining_PageRank PageRank-网页重要性/排名算法
    RoughSets DataMining_RoughSets RoughSets-粗糙集属性约简算法
    SequentialPatterns DataMining_GSP GSP-序列模式分析算法
    SequentialPatterns DataMining_PrefixSpan PrefixSpan-序列模式分析算法
    StatisticalLearning DataMining_EM EM-期望最大化算法
    StatisticalLearning DataMining_SVM SVM-支持向量机算法

    其他辅助的数据挖掘算法

    包名 目录名 算法名
    Others DataMining_ACO ACO-蚁群算法
    Others DataMining_BayesNetwork BayesNetwork-贝叶斯网络算法
    Others DataMining_CABDDCC CABDDCC-基于连通图的分裂聚类算法
    Others DataMining_Chameleon Chameleon-两阶段合并聚类算法
    Others DataMining_DBSCAN DBSCAN-基于密度的聚类算法
    Others DataMining_GA GA-遗传算法
    Others DataMining_GA_Maze GA_Maze-遗传算法在走迷宫游戏中的应用算法
    Others DataMining_KDTree KDTree-k维空间关键数据检索算法工具类
    Others DataMining_MSApriori MSApriori-基于多支持度的Apriori算法
    Others DataMining_RandomForest RandomForest-随机森林算法
    Others DataMining_TAN TAN-树型朴素贝叶斯算法
    Others DataMining_Viterbi Viterbi-维特比算法

    数据挖掘算法使用说明

    本项目实现的数据挖掘的经典算法以及代码,涉及到了决策分类,聚类,链接挖掘,关联挖掘,模式挖掘等等方面,后面都是相应算法的参考博文链接。 目前追加了其他的一些经典的DM算法,在others的包中涉及聚类,分类,图算法,搜索算等等,没有具体分类。

    • C4.5

    C4.5算法与ID3算法一样,都是数学分类算法,C4.5算法是ID3算法的一个改进。ID3算法采用信息增益进行决策判断,而C4.5采用的是增益率。详细介绍链接

    • CART

    CART算法的全称是分类回归树算法,他是一个二元分类,采用的是类似于熵的基尼指数作为分类决策,形成决策树后之后还要进行剪枝,我自己在实现整个算法的时候采用的是代价复杂度算法,详细介绍链接

    • KNN

    K最近邻算法。给定一些已经训练好的数据,输入一个新的测试数据点,计算包含于此测试数据点的最近的点的分类情况,哪个分类的类型占多数,则此测试点的分类与此相同,所以在这里,有的时候可以复制不同的分类点不同的权重。近的点的权重大点,远的点自然就小点。详细介绍链接

    • Naive Bayes

    朴素贝叶斯算法。朴素贝叶斯算法是贝叶斯算法里面一种比较简单的分类算法,用到了一个比较重要的贝叶斯定理,用一句简单的话概括就是条件概率的相互转换推导。详细介绍链接

    • SVM

    支持向量机算法。支持向量机算法是一种对线性和非线性数据进行分类的方法,非线性数据进行分类的时候可以通过核函数转为线性的情况再处理。其中的一个关键的步骤是搜索最大边缘超平面。详细介绍链接

    • EM

    期望最大化算法。期望最大化算法,可以拆分为2个算法,1个E-Step期望化步骤,和1个M-Step最大化步骤。他是一种算法框架,在每次计算结果之后,逼近统计模型参数的最大似然或最大后验估计。详细介绍链接

    • Apriori

    Apriori算法是关联规则挖掘算法,通过连接和剪枝运算挖掘出频繁项集,然后根据频繁项集得到关联规则,关联规则的导出需要满足最小置信度的要求。详细介绍链接

    • FP-Tree

    频繁模式树算法。这个算法也有被称为FP-growth算法,这个算法克服了Apriori算法的产生过多侯选集的缺点,通过递归的产生频度模式树,然后对树进行挖掘,后面的过程与Apriori算法一致。详细介绍链接

    • PageRank

    网页重要性/排名算法。PageRank算法最早产生于Google,核心思想是通过网页的入链数作为一个网页好快的判定标准,如果1个网页内部包含了多个指向外部的链接,则PR值将会被均分,PageRank算法也会遭到LinkSpan攻击。详细介绍链接

    • HITS

    HITS算法是另外一个链接算法,部分原理与PageRank算法是比较相似的,HITS算法引入了权威值和中心值的概念,HITS算法是受用户查询条件影响的,他一般用于小规模的数据链接分析,也更容易遭受到攻击。详细介绍链接

    • K-Means

    K-Means算法是聚类算法,k在在这里指的是分类的类型数,所以在开始设定的时候非常关键,算法的原理是首先假定k个分类点,然后根据欧式距离计算分类,然后去同分类的均值作为新的聚簇中心,循环操作直到收敛。详细介绍链接

    • BIRCH

    BIRCH算法利用构建CF聚类特征树作为算法的核心,通过树的形式,BIRCH算法扫描数据库,在内存中建立一棵初始的CF-树,可以看做数据的多层压缩。详细介绍链接

    • AdaBoost

    AdaBoost算法是一种提升算法,通过对数据的多次训练得到多个互补的分类器,然后组合多个分类器,构成一个更加准确的分类器。详细介绍链接

    • GSP

    GSP算法是序列模式挖掘算法。GSP算法也是Apriori类算法,在算法的过程中也会进行连接和剪枝操作,不过在剪枝判断的时候还加上了一些时间上的约束等条件。详细介绍链接

    • PreFixSpan

    PreFixSpan算法是另一个序列模式挖掘算法,在算法的过程中不会产生候选集,给定初始前缀模式,不断的通过后缀模式中的元素转到前缀模式中,而不断的递归挖掘下去。详细介绍链接

    • CBA

    基于关联规则分类算法。CBA算法是一种集成挖掘算法,因为他是建立在关联规则挖掘算法之上的,在已有的关联规则理论前提下,做分类判断,只是在算法的开始时对数据做处理,变成类似于事务的形式。详细介绍链接

    • RoughSets

    粗糙集算法。粗糙集理论是一个比较新颖的数据挖掘思想。这里使用的是用粗糙集进行属性约简的算法,通过上下近似集的判断删除无效的属性,进行规制的输出。详细介绍链接

    • GSpan

    gSpan算法属于图挖掘算法领域。,主要用于频繁子图的挖掘,相较于其他的图算法,子图挖掘算法是他们的一个前提或基础算法。gSpan算法用到了DFS编码,和Edge五元组,最右路径子图扩展等概念,算法比较的抽象和复杂。详细介绍链接

    ##Others目录下的算法:

    • GA

    遗传算法。遗传算法运用了生物进化理论的知识来寻找问题最优解的算法,算法的遗传进化过程分选择,交叉和变异操作,其中选择操是非常关键的步骤,把更适应的基于组遗传给下一代。详细介绍链接

    • DbScan

    基于空间密度聚类算法。dbScan作为一种特殊聚类算法,弥补了其他算法的一些不足,基于空间密,实现聚类效果,可以发现任意形状的聚簇。详细介绍链接

    • GA_Maze

    遗传算法在走迷宫游戏中的应用。将走迷宫中的搜索出口路径的问题转化为遗传算法中的问题通过构造针对此特定问题的适值函数,基因移动方向的定位,巧的进行问题的求解。详细介绍链接

    • CABDDCC

    基于连通图的分裂聚类算法。也是属于层次聚类算法主要分为2个阶段,第一阶段构造连通图。第二个阶段是分裂连通图,最终形成聚类结果。详细介绍链接

    • Chameleon

    两阶段聚类算法。与CABDDCC算法相反,最后是通过对小簇集合的合并,形成最终的结果,在第一阶段主要是通过K近邻的思想形成小规模的连通图,第二阶段通过RI(相对互连性)和RC(相对近似性)来选一个最佳的簇进行合并。详细介绍链接

    • RandomForest

    随机森林算法。算法思想是决策树+boosting.决策树采用的是CART分类回归数,通过组合各个决策树的弱分类器,构成一个最终的强分类器,在构造决策树的时候采取随机数量的样本数和随机的部分属性进行子决策树的构建,避免了过分拟合的现象发生。详细介绍链接

    • KDTree

    K-Dimension Tree。多维空间划分树,数据在多维空间进行划分与查找。主要用于关键信息的搜索,类似于在空间中的二分搜索,大大提高了搜索效率,在寻找目标元素时,使用了DFS深度优先的方式和回溯进行最近点的寻找。详细介绍链接

    • MS-Apriori

    基于多支持度的Apriori算法。是Apriori算法的升级算法,弥补了原先Apriori算法的不足,还增加了支持度差别限制以及支持度计数统计方面的优化,无须再次重新扫描整个数据集,产生关联规则的时候可以根据子集的关系避免一些置信度的计算。详细介绍链接

    • ACO

    蚁群算法。蚁群算法又称为蚂蚁算法。同GA遗传算法类似,也是运用了大自然规律的算法,用于在图中寻找最优路径的概率型算法。灵感来源于蚂蚁在寻找食物时会散播信息素的发现路径行为。详细介绍链接

    • BayesNetwork

    贝叶斯网络算法。弥补了朴素贝叶斯算法中必须要事件独立性的缺点,利用了贝叶斯网络的DAG有向无环图,允许各个事件保留一定的依赖关系,网络结构中的每个节点代表一种属性,边代表相应的条件概率值,通过计算从而能得到精准的分类效果。详细介绍链接

    • TAN

    树型朴素贝叶斯算法。此算法又被称为加强版朴素贝叶斯算法。在满足原有朴素贝叶斯条件的基础上,他允许部条件属性直接的关联性。形成树型的结构。详细介绍链接

    • Viterbi

    维特比算法。给定一个隐马尔科夫模型以及一个观察序列,求出潜在的状态序列信息,每个潜在状态信息又会受到前一个状态信息的影响。

    算法使用方法

    在每个算法中给出了3大类型,主算法程序,调用程序,输入数据,调用方法如下:

    • 将需要数据的测试数据转化成与给定的输入格式相同
    • 然后以Client类的测试程序调用方式进行使用。
    • 也可以自行修改算法程序,来适用于自己的使用场景

     

    展开全文
  • PCA算法 一、算法概述 主成分分析(PCA)是多元统计分析中用来分析数据的一种方法,PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。 PCA方法最...

    PCA算法

    一、算法概述

    主成分分析(PCA)是多元统计分析中用来分析数据的一种方法,PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。

    PCA方法最著名的应用应该是在人脸识别中特征提取及数据维,我们知道输入200*200大小的人脸图像,单单提取它的灰度值作为原始特征,则这个原始特征将达到40000维,这给后面分类器的处理将带来极大的难度。在这种情况下,我们必须对数据进行降维。

    降维当然意味着信息的丢失,不过鉴于实际数据本身常常存在的相关性,我们可以想办法在降维的同时将信息的损失尽量降低。

    例如某淘宝店铺的数据记录为(日期, 浏览量, 访客数, 下单数, 成交数, 成交金额),从经验我们可以知道,“浏览量”和“访客数”往往具有较强的相关关系,而“下单数”和“成交数”也具有较强的相关关系。这里我们非正式的使用“相关关系”这个词,可以直观理解为“当某一天这个店铺的浏览量较高(或较低)时,我们应该很大程度上认为这天的访客数也较高(或较低)”。后面的章节中我们会给出相关性的严格数学定义。
    这种情况表明,如果我们删除浏览量或访客数其中一个指标,我们应该期待并不会丢失太多信息。因此我们可以删除一个,以降低机器学习算法的复杂度。所以,我们可以采用PCA进行降纬。

    二、算法原理

    1、数据准备
    假设有M个样本,每个样本有N个特征,例如第i个(i=1,2,…,M)样本为:
    这里写图片描述
    则M个样本构成了M行N列的数值矩阵A。

    2、数据归一化处理
    通常做法是将每一维的数据都减去该维的均值,使每一维的均值都为0。

    3、计算协方差矩阵
    协方差是一种用来度量两个随机变量关系的统计量,其定义为:
    这里写图片描述
    M*N样本的协方差矩阵为:
    这里写图片描述
    4、求出协方差矩阵的特征值及对应的特征向量
    若AX=λX,则称λ是A的特征值,X是对应的特征向量。实际上可以这样理解:矩阵A作用在它的特征向量X上,仅仅使得X的长度发生了变化,缩放比例就是相应的特征值λ。

    特别地,当A是对称矩阵时,A的奇异值等于A的特征值,存在正交矩阵Q(Q-1=QT),使得:
    这里写图片描述
    对A进行奇异值分解就能求出所有特征值和Q矩阵。

    A∗Q=Q∗DA∗Q=Q∗D,D是由特征值组成的对角矩阵

    由特征值和特征向量的定义知,Q的列向量就是A的特征向量。

    5、将特征向量按对应的特征值大小从上往下按行排列成矩阵,取前k行组成矩阵P,P为k行n列矩阵

    6、Y=AP’ 即为降维到k维后的数据,Y为M行k列矩阵

    三、代码实现

    PCA.class

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.TreeMap;
    
    import Jama.Matrix;
    
    /*
     * 算法步骤:
     * 1)将原始数据按列组成n行m列矩阵X
     * 2)特征中心化。即每一维的数据都减去该维的均值,使每一维的均值都为0
     * 3)求出协方差矩阵
     * 4)求出协方差矩阵的特征值及对应的特征向量
     * 5)将特征向量按对应的特征值大小从上往下按行排列成矩阵,取前k行组成矩阵p
     * 6)Y=PX 即为降维到k维后的数据
     */
    public class PCA {
    
        private static final double threshold = 0.95;// 特征值阈值
    
        /**
         * 
         * 使每个样本的均值为0
         * 
         * @param primary
         *            原始二维数组矩阵
         * @return averageArray 中心化后的矩阵
         */
        public double[][] changeAverageToZero(double[][] primary) {
            int n = primary.length;
            int m = primary[0].length;
            double[] sum = new double[m];
            double[] average = new double[m];
            double[][] averageArray = new double[n][m];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    sum[i] += primary[j][i];
                }
                average[i] = sum[i] / n;
            }
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    averageArray[j][i] = primary[j][i] - average[i];
                }
            }
            return averageArray;
        }
    
        /**
         * 
         * 计算协方差矩阵
         * 
         * @param matrix
         *            中心化后的矩阵
         * @return result 协方差矩阵
         */
        public double[][] getVarianceMatrix(double[][] matrix) {
            int n = matrix.length;// 行数
            int m = matrix[0].length;// 列数
            double[][] result = new double[m][m];// 协方差矩阵
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    double temp = 0;
                    for (int k = 0; k < n; k++) {
                        temp += matrix[k][i] * matrix[k][j];
                    }
                    result[i][j] = temp / (n - 1);
                }
            }
            return result;
        }
    
        /**
         * 求特征值矩阵
         * 
         * @param matrix
         *            协方差矩阵
         * @return result 向量的特征值二维数组矩阵
         */
        public double[][] getEigenvalueMatrix(double[][] matrix) {
            Matrix A = new Matrix(matrix);
            // 由特征值组成的对角矩阵,eig()获取特征值
    //      A.eig().getD().print(10, 6);
            double[][] result = A.eig().getD().getArray();
            return result;
        }
    
        /**
         * 标准化矩阵(特征向量矩阵)
         * 
         * @param matrix
         *            特征值矩阵
         * @return result 标准化后的二维数组矩阵
         */
        public double[][] getEigenVectorMatrix(double[][] matrix) {
            Matrix A = new Matrix(matrix);
    //      A.eig().getV().print(6, 2);
            double[][] result = A.eig().getV().getArray();
            return result;
        }
    
        /**
         * 寻找主成分
         * 
         * @param prinmaryArray
         *            原始二维数组数组
         * @param eigenvalue
         *            特征值二维数组
         * @param eigenVectors
         *            特征向量二维数组
         * @return principalMatrix 主成分矩阵
         */
        public Matrix getPrincipalComponent(double[][] primaryArray,
                double[][] eigenvalue, double[][] eigenVectors) {
            Matrix A = new Matrix(eigenVectors);// 定义一个特征向量矩阵
            double[][] tEigenVectors = A.transpose().getArray();// 特征向量转置
            Map<Integer, double[]> principalMap = new HashMap<Integer, double[]>();// key=主成分特征值,value=该特征值对应的特征向量
            TreeMap<Double, double[]> eigenMap = new TreeMap<Double, double[]>(
                    Collections.reverseOrder());// key=特征值,value=对应的特征向量;初始化为翻转排序,使map按key值降序排列
            double total = 0;// 存储特征值总和
            int index = 0, n = eigenvalue.length;
            double[] eigenvalueArray = new double[n];// 把特征值矩阵对角线上的元素放到数组eigenvalueArray里
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (i == j)
                        eigenvalueArray[index] = eigenvalue[i][j];
                }
                index++;
            }
    
            for (int i = 0; i < tEigenVectors.length; i++) {
                double[] value = new double[tEigenVectors[0].length];
                value = tEigenVectors[i];
                eigenMap.put(eigenvalueArray[i], value);
            }
    
            // 求特征总和
            for (int i = 0; i < n; i++) {
                total += eigenvalueArray[i];
            }
            // 选出前几个主成分
            double temp = 0;
            int principalComponentNum = 0;// 主成分数
            List<Double> plist = new ArrayList<Double>();// 主成分特征值
            for (double key : eigenMap.keySet()) {
                if (temp / total <= threshold) {
                    temp += key;
                    plist.add(key);
                    principalComponentNum++;
                }
            }
            System.out.println("\n" + "当前阈值: " + threshold);
            System.out.println("取得的主成分数: " + principalComponentNum + "\n");
    
            // 往主成分map里输入数据
            for (int i = 0; i < plist.size(); i++) {
                if (eigenMap.containsKey(plist.get(i))) {
                    principalMap.put(i, eigenMap.get(plist.get(i)));
                }
            }
    
            // 把map里的值存到二维数组里
            double[][] principalArray = new double[principalMap.size()][];
            Iterator<Entry<Integer, double[]>> it = principalMap.entrySet()
                    .iterator();
            for (int i = 0; it.hasNext(); i++) {
                principalArray[i] = it.next().getValue();
            }
    
            Matrix principalMatrix = new Matrix(principalArray);
    
            return principalMatrix;
        }
    
        /**
         * 矩阵相乘
         * 
         * @param primary
         *            原始二维数组
         * 
         * @param matrix
         *            主成分矩阵
         * 
         * @return result 结果矩阵
         */
        public Matrix getResult(double[][] primary, Matrix matrix) {
            Matrix primaryMatrix = new Matrix(primary);
            Matrix result = primaryMatrix.times(matrix.transpose());
            return result;
        }
    }

    主函数调用PCA:

    import Jama.Matrix;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class PCAMain {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated catch block
    
            SelectData selectData = new SelectData();
            PCA pca = new PCA();
            //获得样本集
            double[][] primaryArray = selectData.getdatas();
            System.out.println("--------------------------------------------");
            double[][] averageArray = pca.changeAverageToZero(primaryArray);
            System.out.println("--------------------------------------------");
            System.out.println("均值0化后的数据: ");
            System.out.println(averageArray.length + "行,"
                    + averageArray[0].length + "列");
    
            System.out.println("---------------------------------------------");
            System.out.println("协方差矩阵: ");
            double[][] varMatrix = pca.getVarianceMatrix(averageArray);
    
            System.out.println("--------------------------------------------");
            System.out.println("特征值矩阵: ");
            double[][] eigenvalueMatrix = pca.getEigenvalueMatrix(varMatrix);
    
            System.out.println("--------------------------------------------");
            System.out.println("特征向量矩阵: ");
            double[][] eigenVectorMatrix = pca.getEigenVectorMatrix(varMatrix);
    
            System.out.println("--------------------------------------------");
            Matrix principalMatrix = pca.getPrincipalComponent(primaryArray, eigenvalueMatrix, eigenVectorMatrix);
            System.out.println("主成分矩阵: ");
    //        principalMatrix.print(6, 3);
    
            System.out.println("--------------------------------------------");
            System.out.println("降维后的矩阵: ");
            Matrix resultMatrix = pca.getResult(primaryArray, principalMatrix);
    //        resultMatrix.print(6, 3);
            int c = resultMatrix.getColumnDimension(); //列数
            int r = resultMatrix.getRowDimension();//行数
            System.out.println(resultMatrix.getRowDimension() + "," + resultMatrix.getColumnDimension());
        }
    }
    展开全文
  • 成为一名合格的开发工程师不是一件简单的事情,需要掌握从开发到调试到优化等一...而要成为一名合格的机器学习算法工程师(以下简称算法工程师)更是难上加难,因为在掌握工程师的通用技能以外,还需要掌握一张不

    https://sdk.cn/news/7843?utm_source=tuicool&utm_medium=referral

    成为一名合格的开发工程师不是一件简单的事情,需要掌握从开发到调试到优化等一系列能力,这些能力中的每一项掌握起来都需要足够的努力和经验。

    而要成为一名合格的机器学习算法工程师(以下简称算法工程师)更是难上加难,因为在掌握工程师的通用技能以外,还需要掌握一张不算小的机器学习算法知识网络。

    下面我们就将成为一名合格的算法工程师所需的技能进行拆分,一起来看一下究竟需要掌握哪些技能才能算是一名合格的算法工程师。


    图1 机器学习算法工程师技能树

    基础开发能力

    所谓算法工程师,首先需要是一名工程师,那么就要掌握所有开发工程师都需要掌握的一些能力。有些同学对于这一点存在一些误解,认为所谓算法工程师就只需要思考和设计算法,不用在乎这些算法如何实现,而且会有人帮你来实现你想出来的算法方案。这种思想是错误的,在大多数企业的大多数职位中,算法工程师需要负责从算法设计到算法实现再到算法上线这一个全流程的工作。

    笔者曾经见过一些企业实行过算法设计与算法实现相分离的组织架构,但是在这种架构下,说不清楚谁该为算法效果负责,算法设计者和算法开发者都有一肚子的苦水,具体原因不在本文的讨论范畴中,但希望大家记住的是,基础的开发技能是所有算法工程师都需要掌握的。

    基础开发所涉及到的技能非常的多,在这里只挑选了两个比较重要的点来做阐述。

    单元测试

    在企业应用中,一个问题的完整解决方案通常包括很多的流程,这其中每个环节都需要反复迭代优化调试,如何能够将复杂任务进行模块划分,并且保证整体流程的正确性呢?最实用的方法就是单元测试。单元测试并不只是简单的一种测试技能,它首先是一种设计能力。并不是每份代码都可以做单元测试,能做单元测试的前提是代码首先是可以划分为多个单元——也就是模块的。在把项目拆解成可独立开发和测试的模块之后,再加上对每个模块的独立的、可重复的单元测试,就可以保证每个模块的正确性,如果每个模块的正确性都可以保证,那么整体流程的正确性就可以得到保证。

    对于算法开发这种流程变动频繁的开发活动来讲,做好模块设计和单元测试是不给自己和他人挖坑的重要保证。也是能让自己放心地对代码做各种改动优化的重要前提。

    逻辑抽象复用

    逻辑的抽象复用可以说是所有软件开发活动中最为重要的一条原则,衡量一个程序员代码水平的重要原则之一就是看他代码中重复代码和相似代码的比例。大量重复代码或相似代码背后反映的是工程师思维的懒惰,因为他觉得复制粘贴或者直接照着抄是最省事的做法。这样做不仅看上去非常的丑陋,而且也非常容易出错,更不用提维护起来的难度。

    算法开发的项目中经常会有很多类似逻辑的出现,例如对多个特征使用类似的处理方法,还有原始数据ETL中的很多类似处理方法。如果不对重复逻辑做好抽象,代码看上去全是一行行的重复代码,无论是阅读起来还是维护起来都会非常麻烦。

    概率和统计基础

    概率和统计可以说是机器学习领域的基石之一,从某个角度来看,机器学习可以看做是建立在概率思维之上的一种对不确定世界的系统性思考和认知方式。学会用概率的视角看待问题,用概率的语言描述问题,是深入理解和熟练运用机器学习技术的最重要基础之一。

    概率论内容很多,但都是以具体的一个个分布为具体表现载体体现出来的,所以学好常用的概率分布及其各种性质对于学好概率非常重要。对于离散数据,伯努利分布、二项分布、多项分布、Beta分布、狄里克莱分布以及泊松分布都是需要理解掌握的内容;对于离线数据,高斯分布和指数分布族是比较重要的分布。这些分布贯穿着机器学习的各种模型之中,也存在于互联网和真实世界的各种数据之中,理解了数据的分布,才能知道该对它们做什么样的处理。

    此外,假设检验的相关理论也需要掌握。在这个所谓的大数据时代,最能骗人的大概就是数据了,掌握了假设检验和置信区间等相关理论,才能具备分辨数据结论真伪的能力。例如两组数据是否真的存在差异,上线一个策略之后指标是否真的有提升等等。这种问题在实际工作中非常常见,不掌握相关能力的话相当于就是大数据时代的睁眼瞎。

    在统计方面,一些常用的参数估计方法也需要掌握,典型的如最大似然估计、最大后验估计、EM算法等。这些理论和最优化理论一样,都是可以应用于所有模型的理论,是基础中的基础。

    机器学习理论

    虽然现在开箱即用的开源工具包越来越多,但并不意味着算法工程师就可以忽略机器学习基础理论的学习和掌握。这样做主要有两方面的意义:

    • 掌握理论才能对各种工具、技巧灵活应用,而不是只会照搬套用。只有在这个基础上才能够真正具备搭建一套机器学习系统的能力,并对其进行持续优化。否则只能算是机器学习搬砖工人,算不得合格的工程师。出了问题也不会解决,更谈不上对系统做优化。

    • 学习机器学习的基础理论的目的不仅仅是学会如何构建机器学习系统,更重要的是,这些基础理论里面体现的是一套思想和思维模式,其内涵包括概率性思维、矩阵化思维、最优化思维等多个子领域,这一套思维模式对于在当今这个大数据时代做数据的处理、分析和建模是非常有帮助的。如果你脑子里没有这套思维,面对大数据环境还在用老一套非概率的、标量式的思维去思考问题,那么思考的效率和深度都会非常受限。

    机器学习的理论内涵和外延非常之广,绝非一篇文章可以穷尽,所以在这里我列举了一些比较核心,同时对于实际工作比较有帮助的内容进行介绍,大家可在掌握了这些基础内容之后,再不断探索学习。

    基础理论

    所谓基础理论,指的是不涉及任何具体模型,而只关注“学习”这件事本身的一些理论。以下是一些比较有用的基础概念:

    • VC维。VC维是一个很有趣的概念,它的主体是一类函数,描述的是这类函数能够把多少个样本的所有组合都划分开来。VC维的意义在哪里呢?它在于当你选定了一个模型以及它对应的特征之后,你是大概可以知道这组模型和特征的选择能够对多大的数据集进行分类的。此外,一类函数的VC维的大小,还可以反应出这类函数过拟合的可能性。

    • 信息论。从某种角度来讲,机器学习和信息论是同一个问题的两个侧面,机器学习模型的优化过程同时也可以看作是最小化数据集中信息量的过程。对信息论中基本概念的了解,对于机器学习理论的学习是大有裨益的。例如决策树中用来做分裂决策依据的信息增益,衡量数据信息量的信息熵等等,这些概念的理解对于机器学习问题神本的理解都很有帮助。这部分内容可参考《Elements of Information Theory》这本书。

    • 正则化和bias-variance tradeoff。如果说现阶段我国的主要矛盾是“人民日益增长的美好生活需要和不平衡不充分的发展之间的矛盾”,那么机器学习中的主要矛盾就是模型要尽量拟合数据和模型不能过度拟合数据之间的矛盾。而化解这一矛盾的核心技术之一就是正则化。正则化的具体方法不在此讨论,但需要理解的,是各种正则化方法背后透露出的思想:bias-variance tradoff。在不同利益点之间的平衡与取舍是各种算法之间的重要差异,理解这一点对于理解不同算法之间的核心差异有着非常重要的作用。

    • 最优化理论。绝大多数机器学习问题的解决,都可以划分为两个阶段:建模和优化。所谓建模就是后面我们会提到的各种用模型来描述问题的方法,而优化就是建模完成之后求得模型的最优参数的过程。机器学习中常用的模型有很多,但背后用到的优化方法却并没有那么多。换句话说,很多模型都是用的同一套优化方法,而同一个优化方法也可以用来优化很多不同模型。对各种常用优化方法的和思想有所有了解非常有必要,对于理解模型训练的过程,以及解释各种情况下模型训练的效果都很有帮助。这里面包括最大似然、最大后验、梯度下降、拟牛顿法、L-BFGS等。

    机器学习的基础理论还有很多,可以先从上面的概念学起,把它们当做学习的起点,在学习过程中还会遇到其他需要学习的内容,就像一张网络慢慢铺开一样,不断积累自己的知识。这方面基础理论的学习,除了Andrew Ng的著名课程以外,《Learning from Data》这门公开课也非常值得大家学习,这门课没有任何背景要求,讲授的内容是在所有模型之下的基础中的基础,非常地靠近机器学习的内核本质。这门课的中文版本叫做《机器学习基石》,也可以在网上找到,其讲授者是上面英文版本讲授者的学生。

    有监督学习

    在了解了机器学习的基本概念之后,就可以进入到一些具体模型的学习中了。在目前的工业实践中,有监督学习的应用面仍然是最广泛的,这是因为我们现实中遇到的很多问题都是希望对某个事物的某个属性做出预测,而这些问题通过合理的抽象和变换,都可以转化为有监督学习的问题。

    在学习复杂模型之前,我建议大家都先学习几个最简单的模型,典型的如朴素贝叶斯。朴素贝叶斯有很强的假设,这个假设很多问题都不满足,模型结构也很简单,所以其优化效果并不是最好的。但也正是由于其简单的形式,非常利于学习者深入理解整个模型在建模和优化过程中的每一步,这对于搞清楚机器学习是怎么一回事情是非常有用的。同时,朴素贝叶斯的模型形式通过一番巧妙的变换之后,可以得到和逻辑回归形式上非常统一的结果,这无疑提供了对逻辑回归另外一个角度的解释,对于更加深刻理解逻辑回归这一最常用模型有着非常重要的作用。

    在掌握了机器学习模型的基础流程之后,需要学习两种最基础的模型形式:线性模型和树形模型,分别对应着线性回归/逻辑回归和决策回归/分类树。现在常用的模型,无论是浅层模型还是深度学习的深层模型,都是基于这两种基础模型形式变幻而来。而学习这两种模型的时候需要仔细思考的问题是:这两种模型的本质差异是什么?为什么需要有这两种模型?他们在训练和预测的精度、效率、复杂度等方面有什么差异?了解清楚这些本质的差异之后,才可以做到根据问题和数据的具体情况对模型自如运用。

    在掌握了线性模型和树形模型这两种基础形式之后,下一步需要掌握的是这两种基础模型的复杂形式。其中线性模型的复杂形式就是多层线性模型,也就是神经网络。树模型的复杂形式包括以GDBT为代表的boosting组合,以及以随机森林为代表的bagging组合。这两种组合模型的意义不仅在于模型本身,boosting和bagging这两种组合思想本身也非常值得学习和理解,这代表了两种一般性的强化方法:boosting的思想是精益求精,不断在之前的基础上继续优化;而bagging的思想是“三个臭裨将顶一个诸葛亮”,是通过多个弱分类器的组合来得到一个强分类器。这两种组合方法各有优劣,但都是在日常工作中可以借鉴的思想。例如在推荐系统中所我们经常会使用多个维度的数据做召回源,从某个角度来看就是一种bagging的思想:每个单独召回源并不能给出最好表现,但是多个召回源组合之后,就可以得到比每个单独召回源都要好的结果。所以说思想比模型本身更重要。

    无监督学习

    有监督学习虽然目前占了机器学习应用的大多数场景,但是无监督学习无论从数据规模还是作用上来讲也都非常的重要。无监督学习的一大类内容是在做聚类,做聚类的意义通常可以分为两类:一类是将聚类结果本身当做最终的目标,另一类是将聚类的结果再作为特征用到有监督学习中。但这两种意义并不是和某种聚类方法具体绑定,而只是聚类之后结果的不同使用方式,这需要在工作中不断学习、积累和思考。而在入门学习阶段需要掌握的,是不同聚类算法的核心差异在哪里。例如最常用的聚类方法中,kmeans和DBSCAN分别适合处理什么样的问题?高斯混合模型有着什么样的假设?LDA中文档、主题和词之间是什么关系?这些模型最好能够放到一起来学习,从而掌握它们之间的联系和差异,而不是把他们当做一个个孤立的东西来看待。

    除了聚类以外,近年来兴起的嵌入表示(embedding representation)也是无监督学习的一种重要方法。这种方法和聚类的差异在于,聚类的方法是使用已有特征对数据进行划分,而嵌入表示则是创造新的特征,这种新的特征是对样本的一种全新的表示方式。这种新的表示方法提供了对数据全新的观察视角,这种视角提供了数据处理的全新的可能性。此外,这种做法虽然是从NLP领域中兴起,但却具有很强的普适性,可用来处理多种多样的数据,都可以得到不错的结果,所以现在已经成为一种必备的技能。

    机器学习理论方面的学习可以从《An Introduction to Statistical Learning with Application in R》开始,这本书对一些常用模型和理论基础提供了很好的讲解,同时也有适量的习题用来巩固所学知识。进阶学习可使用上面这本书的升级版《Elements of Statistical Learning》和著名的《Pattern Recognition and Machine Learning》。

    开发语言和开发工具

    掌握了足够的理论知识,还需要足够的工具来将这些理论落地,这部分我们介绍一些常用的语言和工具。

    开发语言

    近年来Python可以说是数据科学和算法领域最火的语言,主要原因是它使用门槛低,上手容易,同时具有着完备的工具生态圈,同时各种平台对其支持也比较好。所以Python方面我就不再赘述。但是在学习Python以外,我建议大家可以再学习一下R语言,主要原因有以下几点:

    • R语言具有最完备的统计学工具链。我们在上面介绍了概率和统计的重要性,R语言在这方面提供的支持是最全面的,日常的一些统计方面的需求,用R来做可能要比用Python来做还要更快。Python的统计科学工具虽然也在不断完善,但是R仍然是统计科学最大最活跃的社区。

    • 向量化、矩阵化和表格化思维的培养。R中的所有数据类型都是向量化的,一个整形的变量本质上是一个长度为一的一维向量。在此基础上R语言构建了高效的矩阵和(DataFrame)数据类型,并且在上面支持了非常复杂而又直观的操作方法。这套数据类型和思考方式也在被很多更现代化的语言和工具所采纳,例如Numpy中的ndarray,以及Spark最新版本中引入的DataFrame,可以说都是直接或间接从R语言得到的灵感,定义在上面的数据操作也和R中对DataFrame和向量的操作如出一辙。就像学编程都要从C语言学起一样,学数据科学和算法开发我建议大家都学一下R,学的既是它的语言本身,更是它的内涵思想,对大家掌握和理解现代化工具都大有裨益。

    除了R以外,Scala也是一门值得学习的语言。原因在于它是目前将面向对象和函数式两种编程范式结合得比较好的一种语言,因为它不强求你一定要用函数式去写代码,同时还能够在能够利用函数式的地方给予了足够的支持。这使得它的使用门槛并不高,但是随着经验和知识的不断积累,你可以用它写出越来越高级、优雅的代码。

    开发工具

    开发工具方面,Python系的工具无疑是实用性最高的,具体来说,Numpy、Scipy、sklearn、pandas、Matplotlib组成的套件可以满足单机上绝大多数的分析和训练工作。但是在模型训练方面,有一些更加专注的工具可以给出更好的训练精度和性能,典型的如LibSVM、Liblinear、XGBoost等。

    大数据工具方面,目前离线计算的主流工具仍然是Hadoop和Spark,实时计算方面Spark Streaming和Storm也是比较主流的选择。近年来兴起的新平台也比较多,例如Flink和Tensorflow都是值得关注的。值得一提的是,对于Hadoop和Spark的掌握,不仅要掌握其编码技术,同时还要对其运行原理有一定理解,例如,Map-Reduce的流程在Hadoop上是如何实现的,Spark上什么操作比较耗时,aggregateByKey和groupByKey在运行原理上有什么差异,等等。只有掌握了这些,才能对这些大数据平台运用自如,否则很容易出现程序耗时过长、跑不动、内存爆掉等等问题。

    架构设计

    最后我们花一些篇幅来谈一下机器学习系统的架构设计。所谓机器学习系统的架构,指的是一套能够支持机器学习训练、预测、服务稳定高效运行的整体系统以及他们之间的关系。

    在业务规模和复杂度发展到一定程度的时候,机器学习一定会走向系统化、平台化这个方向。这个时候就需要根据业务特点以及机器学习本身的特点来设计一套整体架构,这里面包括上游数据仓库和数据流的架构设计,以及模型训练的架构,还有线上服务的架构等等。这一套架构的学习就不像前面的内容那么简单了,没有太多现成教材可以学习,更多的是在大量实践的基础上进行抽象总结,对当前系统不断进行演化和改进。但这无疑是算法工程师职业道路上最值得为之奋斗的工作。在这里能给的建议就是多实践,多总结,多抽象,多迭代。

    机器学习算法工程师领域现状

    现在可以说是机器学习算法工程师最好的时代,各行各业对这类人才的需求都非常旺盛。典型的包括以下一些细分行业:

    • 推荐系统。推荐系统解决的是海量数据场景下信息高效匹配分发的问题,在这个过程中,无论是候选集召回,还是结果排序,以及用户画像等等方面,机器学习都起着重要的作用。

    • 广告系统。广告系统和推荐系统有很多类似的地方,但也有着很显著的差异,需要在考虑平台和用户之外同时考虑广告主的利益,两方变成了三方,使得一些问题变复杂了很多。它在对机器学习的利用方面也和推荐类似。

    • 搜索系统。搜索系统的很多基础建设和上层排序方面都大量使用了机器学习技术,而且在很多网站和App中,搜索都是非常重要的流量入口,机器学习对搜索系统的优化会直接影响到整个网站的效率。

    • 风控系统。风控,尤其是互联网金融风控是近年来兴起的机器学习的又一重要战场。不夸张地说,运用机器学习的能力可以很大程度上决定一家互联网金融企业的风控能力,而风控能力本身又是这些企业业务保障的核心竞争力,这其中的关系大家可以感受一下。

    但是所谓“工资越高,责任越大”,企业对于算法工程师的要求也在逐渐提高。整体来说,一名高级别的算法工程师应该能够处理“数据获取→数据分析→模型训练调优→模型上线”这一完整流程,并对流程中的各种环节做不断优化。一名工程师入门时可能会从上面流程中的某一个环节做起,不断扩大自己的能力范围。

    除了上面列出的领域以外,还有很多传统行业也在不断挖掘机器学习解决传统问题的能力,行业的未来可谓潜力巨大。

    参考文献 

    朴素贝叶斯和逻辑回归之间的关系可参考:http://www.cs.cmu.edu/~tom/mlbook/NBayesLogReg.pdf 

    《learning_from_data》 

    《An Introduction to Statistical Learning with Application in R》: 

    英文版下载:http://www-bcf.usc.edu/~gareth/ISL/; 

    中译版名为《统计学习导论》,前七章的视频课程可见:http://edu.csdn.net/huiyiCourse/series_detail/13。 

    《Elements of Statistical Learning》 

    《Elements of Information Theory》


    展开全文
  • 虽然在机器学习中,Python是人工智能从业者使用最多的编程语言,但是,Java 在项目开发中仍然发挥着不可替代的作用,而且许多流行的机器学习框架本身就是 Java编写的。Python 的资料到处都是,而 Java 相关的资料就...

    导读:机器学习是目前盛行于世的技术之一,这几年一时风头无两。虽然在机器学习中,Python是人工智能从业者使用最多的编程语言,但是,Java 在项目开发中仍然发挥着不可替代的作用,而且许多流行的机器学习框架本身就是 Java编写的。Python 的资料到处都是,而 Java 相关的资料就相对少了很多。今天我们翻译了 Fatema Patrawala> 撰写的《六大最常用的 Java 机器学习库一览》。

    MLOSS.org 网站上,列出了 70 多个基于 Java 的开源机器学习项目,可能还有更多未列出的项目,存于大学里的服务器、GitHub 或 Bitbucket 中。我们将在本文中回顾 Java 中的主流机器学习库和平台,它们能够解决的问题类型,支持的算法以及可以使用的数据类型。

    本文节选自 Machine learning in Java,由 Bostjan Kaluza 编写,Packt Publishing Ltd. 出版

    Weka

    Weka 是 Waikato Environment for Knowledge Analysis(Waikato 智能分析环境)的缩写,是新西兰 Waikato 大学开发的机器学习库,也可能是最为有名的 Java 库。Weka 是一个通用的库,能够解决各种机器学习任务,如分类、回归和聚类。它具有丰富的图形用户界面、命令行界面和 Java API。有关 Weka 更多详情,请参阅:http://www.cs.waikato.ac.nz/ml/weka/

    截止到本书写作之时,Weka 总共包含 267 个算法,其中:数据预处理(82),属性选择(33),分类和回归(133),聚类(12),关联规则挖掘(7)。图形界面非常适合用于探索数据,而 Java API 可以让你开发新的机器学习方案并在应用中使用这些算法。
    在这里插入图片描述
    Weka 是在 GNU 通用公共许可证(GNU GPL)下发布的,这意味着你可以复制、分发和修改它,只要你跟踪源文件中的更改并将其保存在 GNU GPL 下。你甚至可以进行商业分发,但前提是你必须公开源代码或获得商业许可证。

    除了几种支持的文件格式外,Weka 还提供了自己的默认数据格式 ARFF,用于通过属性 - 数据对描述数据。它由两部分组成:第一部分包含标题头,它指定所有属性(即特性)及其类型;例如,标称、数字、日期和字符串。第二部分包含数据,其中每行对应于一个实例。标题头中的最后一个属性隐式地被视为目标变量,缺失的数据用问号标记。例如,用 ARFF 文件格式编写的 Bob 实例如下:

        @RELATION person_dataset
        
        @ATTRIBUTE `Name`  STRING
        @ATTRIBUTE `Height`  NUMERIC
        @ATTRIBUTE `Eye color`{blue, brown, green}
        @ATTRIBUTE `Hobbies`  STRING
        
        @DATA
        'Bob', 185.0, blue, 'climbing, sky diving'
        'Anna', 163.0, brown, 'reading'
        'Jane', 168.0, ?, ?
    

    该文件由三个部分组成。第一部分以 @relation 关键字开始,指定数据集名称。下一部分以 @ATTRIBUTE 关键字开始,后面是属性名和类型。可用的类型是 STRING(字符串)、NUMERIC(数字)、DATE(日期)和一组分类值。最后一个属性被隐式假设为我们想要预测的目标变量。最后一部分以 @DATA 关键字开始,每行后面跟着一个实例。实例值用逗号分隔,并且必须遵循与第二部分中的属性相同的顺序。

    Weka 的 Java API 由以下的顶层包组成:

    • weka.associations:这些是关联规则学习的数据结构和算法,包括 Apriori、 predictive apriori、FilteredAssociator、FP-Growth、Generalized Sequential Patterns (GSP)、Hotspot 和 Tertius。

    • weka.classifiers:这些是监督学习算法、评估期和数据结构。该包由以下几个部分组成:

      • weka.classifiers.bayes:它实现了贝叶斯(Bayesian)方法,包括朴素贝叶斯、贝式网络、贝叶斯逻辑回归等。

      • weka.classifiers.evaluation:这些是评价统计、混淆矩阵、ROC 曲线等标称和数值预测的监督评价算法。

      • weka.classifiers.functions:这些是回归算法,包括线性回归、保序回归、高斯过程、支持向量机、多层感知器、表决感知器等。

      • weka.classifiers.lazy:这些是基于实例的算法,比如 k- 最近邻、K*,惰性贝叶斯规则。

      • weka.classifiers.meta:这些是监督学习元算法,包括 AdaBoost、bagging、加性回归、随机委员会(random committee)等。

      • weka.classifiers.mi:这些是多实例算法,如 Citation-KNN、多样性密度、MI AdaBoost 等。

      • weka.classifiers.rules:这些是基于变治法(separate-and-conquer)、Ripper、Part、Prism 的决策表和决策规格。

      • weka.classifiers.trees:这些是各种决策树算法,包括 ID3、C4.5、M5、功能树、逻辑树、随机森林等。

    • weka.clusterers:这些是聚类算法,包括 k-means、Clope、Cobweb、DBSCAN 层次聚类、Farthest 等

    • weka.core:这些是各种实用类、数据表示、配置文件等。

    • weka.datagenerators:这些是用于分类、回归和聚类算法的数据生成器。

    • weka.estimators:这些是用于离散 / 标称域、条件概率估计等的各种数据分布估计。

    • weka.experiment:这是一组类,支持运行实验所需的配置、数据集、模型设置和统计信息。

    • weka.filters:这些是基于属性和基于实例的选择算法,用于监督和非监督数据预处理。

    • weka.gui:这些是实现 Explorer、Experimenter、和 Knowledge Flow 的图形界面。Explorer 允许你调查数据集、算法及其参数,并使用散点图和其他可视化的形式对数据集进行可视化。Experimenter 用于设计批量实验,但它只能用于分类和回归问题。Knowledge Flow 实现了可视化的拖放式用户界面来构建数据流,如:加载数据、应用过滤器、构建分类器和评估。

    用于机器学习的 Java-ML

    Java 机器学习库(Java-ML)是一组机器学习算法的集合,具备用于相同类型的算法的公共接口。它只提供 Java API,因此,它主要面向的是软件工程师和程序员。Java-ML 包含用于数据预处理、特征选择、分类和聚类的算法。此外,它还提供了几个 Weka 桥来直接通过 Java-ML API 访问 Weka 的算法。Java-ML 可从 http://java-ml.sourceforge.net 下载,截至本书完成之际,最近版本发布于 2012 年。
    在这里插入图片描述
    Java-ML 也是一个通用机器学习库。与 Weka 相比,它提供了更为一致的接口和最新算法的实现,在其他包中不存在这些算法,如一系列最先进的相似性度量和特征选择技术等,这些包含动态时间规整、随机森林属性评估等等。Java-ML 也可以在 GNU GPL 许可证下使用。

    Java-ML 支持任何类型的文件,只要它每行包含一个数据样本,并且特征用逗号、分号和制表符分隔。

    Java-ML 库由以下顶层包组成:

    • net.sf.javaml.classification:这些是分类算法,包括朴素贝叶斯、随机森林、Bagging、自组织映射、k- 最近邻等。

    • net.sf.javaml.clustering:这些是聚类算法,包括 kmeans、自组织映射、空间聚类、Cobweb、AQBC 等。

    • net.sf.javaml.core:这些表示实例和数据集。

    • net.sf.javaml.distance:这些是测量实例距离和相似度的算法,如切比雪夫距离(Chebyshev distance)、余弦距离 / 相似度、欧几里得距离(Euclidian distance)、杰卡德距离(Jaccard distance)/ 相似度、马氏距离(Mahalanobis distance)、曼哈顿距离(Manhattan distance)、明氏距离(Minkowski distance)、皮尔逊积矩相关系数(Pearson correlation coefficient)、斯皮尔曼简捷距离(Spearman’s footrule distance)、动态时间规整(dynamic time wrapping,DTW)等。

    • net.sf.javaml.featureselection:这些是用于特征评估、评分、选择和排名的算法,如增益比、ReliefF、Kullback-Liebler 散度、对称不确定性等。

    • net.sf.javaml.filter:这些是通过过滤、删除属性、设置类或属性值等操作实例的方法。

    • net.sf.javaml.matrix:实现内存或基于文件的数组。

    • net.sf.javaml.sampling:实现选择数据集子集的采样算法。net.sf.javaml.tools:这些是关于数据集、实例操作、序列化、Weka API 接口等的使用方法。

    • net.sf.javaml.utils:这些是算法的实用方法,如统计、数学方法、列联表等表等。

    Apache Mahout

    Apache Mahout 项目旨在构建可扩展的机器学习库。它是在可扩展分布式体系结构(如 Hadoop)上构建的,实用 MapReduce 范例,这是一种实用服务器集群处理和生成具有并行分布式算法的大型数据及的方法。
    在这里插入图片描述
    Mahout 提供了控制台界面和 Java API,可用于聚类、分类和写作过滤的可扩展算法。它可以解决这三个业务问题:项目推荐,如向喜欢某部电影的人推荐其他可能喜欢的电影;聚类,如将文本文档分组与主题相关的文档组中归档;分类,如学习将哪个主题分配给未标记的文档。

    Mahout 是在商业化的 Apache 许可证下分发的,这意味着只要你保留 Apache 许可证并将其显示在程序的版权声明中,你就可以使用它。

    Mahout 提供了以下库:
    org.apache.mahout.cf.taste:这些是基于用户和基于项目的协同过滤算法,及基于 ALS 的矩阵分解算法。

    • org.apache.mahout.classifier:这些是内存和分布式实现,包括逻辑回归、朴素贝叶斯、随机森林、隐马尔科夫模型(hidden Markov models,HMM)和多层感知器。

    • org.apache.mahout.clustering:这些是聚类算法,例如 Canopy 聚类、k-means、模糊 k-means、流式 K-means 和谱聚类。

    • org.apache.mahout.common:这些是算法的实用方法,包括距离、MapReduce 操作、迭代器等。

    • org.apache.mahout.driver:实现了通用驱动程序来运行其他类的主要方法。

    • org.apache.mahout.ep:这是使用记录步骤突变的进化优化。

    • org.apache.mahout.math:这些是 Hadoop 中的各种数据额实用方法和实现。

    • org.apache.mahout.vectorizer:这些是用于数据表示、操作和 MapReduce 任务的类。

    Apache Spark

    Apache Spark(或简称 Spark)是在 Hadoop 上构建大规模数据处理的平台,但与 Mahout 不同的是,它与 MapReduce 范式无关。相反,它使用内存缓存提取工作数据集,对其进行处理并重复查询。据报道,Spark 直接处理磁盘存储数据的速度是 Mahout 实现的十倍。可从 https://spark.apache.org 下载。
    在这里插入图片描述
    在 Spark 之上构建了许多模块,例如用于图形处理的 GraphX、用于处理实时数据流的 Spark Streaming 和用于机器学习库的 MLlib,这些模块具有分类、回归、协同过滤、聚类、降维和优化。

    Spark 的 MLlib 可以使用基于 Hadoop 的数据源,例如 Hadoop 分布式文件系统(HDFS)或 HBase,以及本地文件。支持的数据类型包括以下几种:

    • 局部向量存储在一台机器上。稠密向量表示为双类型值数组,如 (2.0,0.0,10.,0.0);而稀疏向量由向量的大小、索引数组和值数组表示,如 [4, (0, 2), (2.0, 1.0)]。

    • 标记点用于监督学习算法,由局部向量组成,用双类型的类值标记。标签可以是类索引、二进制结果或多个类索引的列表(多类分类)。例如,标记的稠密向量表示为 [1.0, (2.0, 0.0, 1.0, 0.0)]。

    • 局部矩阵在单台机器上存储稠密矩阵。它由矩阵维数和以列主序排列的单个双数组定义。

    • 分布式矩阵对存储在 Spark 的弹性分布式数据集(Resilient Distributed Dataset,RDD)中的数据进行操作,RDD 表示可以并行操作的元素集合。有三种表示:行矩阵,其中每一行都是可以存储在一台机器上的局部向量,但行索引没有意义;索引行矩阵,类似于行矩阵,但行索引是有意义的,即可以识别行并执行行连接;坐标矩阵,当行不能存储在一台机器上,且矩阵非常稀疏时才使用。

    Spark 的 MLlib API 库提供了各种学习算法和实用工具的接口,如下所示:

    • org.apache.spark.mllib.classification:这些是二元和多类分类算法,包括线性 SVM、逻辑回归、决策树和朴素贝叶斯。

    • org.apache.spark.mllib.clustering:这些是 k-means 聚类。

    • org.apache.spark.mllib.linalg:这些是数据表示,包括稠密向量、稀疏向量和矩阵。

    • org.apache.spark.mllib.optimization:这是 MLlib 中作为低级基元的各种优化算法,包括梯度下降、随机梯度下降、分布式 SGD 的更新方案和有限内存 BFGS。

    • org.apache.spark.mllib.recommendation:这些是基于模型的协同过滤,通过交替最小二乘矩阵分解来实现。

    • org.apache.spark.mllib.regression:这些是回归学习算法,如线性最小二乘、决策树、Lasso 和 Ridge 回归。

    • org.apache.spark.mllib.stat:这些是稀疏或稠密向量格式的样本的统计函数,用于计算均值、方差、最小值、最大值、计数和非零计数。org.apache.spark.mllib.tree:实现了分类和回归决策树的算法。

    • org.apache.spark.mllib.util:这些是用于加载、保存、预处理、生成和验证数据的方法的集合。

    Deeplearning4j

    DeepLearning4j(或称 DL4J),是一个用 Java 编写的深度学习库。它具有分布式和单机深度学习框架,包括并支持各种神经网络结构,如前馈神经网络、RBM(Restricted Boltzmann Machine,受限玻尔兹曼机)、卷积神经网络、深度信念网络、自动编码器等。DL4J 可以解决不同的问题,比如识别面孔、声音、垃圾邮件和电子商务欺诈。

    Deeplearning4j 也是在 Apache 2.0 许可下分发的,可从 http://deeplearning4j.org 下载。该库由以下组成:

    • org.deeplearning4j.base:这些是加载类。

    • org.deeplearning4j.berkeley:这些是数学使用方法。

    • org.deeplearning4j.clustering:k-means 的聚类实现。

    • org.deeplearning4j.datasets:这是数据集的操作,包括导入、创建、迭代等。

    • org.deeplearning4j.distributions:这是用于分发的实用方法。

    • org.deeplearning4j.eval:这些是评估类,包括混淆矩阵。

    • org.deeplearning4j.exceptions:实现异常处理程序。

    • org.deeplearning4j.models:这些是监督学习算法,包括深度信念网络、堆叠式自动编码器、堆叠去噪式自动编码器和 RBM。

    • org.deeplearning4j.nn:这些是基于神经网络的组件和算法的实现,例如神经网络、多层网络、卷积多层网络等。

    • org.deeplearning4j.optimize:这些是神经网络优化算法,包括反向传播、多层优化、输出层优化等。

    • org.deeplearning4j.plot:这些是用于呈现数据的各种方法。

    • org.deeplearning4j.rng:这是一个随机数据生成器。

    • org.deeplearning4j.util:这些是帮助和实用方法。

    MALLET

    机器学习语言工作包(Machine Learning for Language Toolkit,MALLET),是一个包含自然语言处理算法和实用程序的大型库。它可以用于各种任务,如文档分类、分档聚类、信息提取和主题建模。MALLET 提供了命令行界面和 Java API,适用于多种算法,如朴素贝叶斯、HMM(Hidden Markov Model,隐马尔可夫模型)、隐含狄利克主题模型(Latent Dirichlet topic model)、逻辑回归和条件随机域(conditional random fields)。
    在这里插入图片描述
    MALLET 可以在通用公共许可证 1.0 下使用,这意味着你甚至可以在商业应用程序中使用它。可以从 http://mallet.cs.umass.edu 下载。MALLET 实例由名称、标签、数据和源表示。但是,有两种方法可以将数据导入到 MALLET 格式中,如下所示:

    • Instance per file:每个文件(即文档)对应一个实例,MALLET 接受输入的目录名。

    • Instance per line:每行对应一个实例,假设使用以下格式:instance_name 标签令牌。数据将是一个特征向量,由作为标记出现的不同单词和它们出现次数组成。

    该库由以下包组成:

    • cc.mallet.classify:这些是用于训练和分类实例的算法,包括 AdaBoost、Bagging、C4.5、以及其他决策树模型、多元逻辑回归、朴素贝叶斯和 Winnow2。

    • cc.mallet.cluster:这些是无监督聚类算法,包括贪心凝聚( greedy agglomerative)、爬山算法(hill climbing)、k-best 和 k-means 聚类。

    • cc.mallet.extract:实现分词器(tokenizers)、文档提取器、文档查看器和清理器等。

    • cc.mallet.fst: 实现了序列模型,包括条件随机域、HMM、最大熵马尔科夫模型(maximum entropy Markov models),以及相应的算法和评估器。

    • cc.mallet.grmm:实现了如推理算法、学习和测试的图形模型和因子图。例如环状信念传播(loopy belief propagation)、吉布斯采样(Gibbs sampling)等。

    • cc.mallet.optimize:这些是用于寻找函数最大值的优化算法,例如梯度上升、有限内存 BFGS、随机元上升(stochastic meta ascent)等。

    • cc.mallet.pipe:这些方法是将数据处理为 MALLET 实例中的管道。cc.mallet.topics:这些是主题建模算法,例如隐含狄利克分布(Latent Dirichlet allocation)、四级弹球分布(four-level pachinko allocation)、分层 PAM、DMRT 等。

    • cc.mallet.types:实现了基本数据类型,如数据集、特征向量、实例和标签。

    • cc.mallet.util:这些是各种实用工具功能,如命令行处理、搜索、数学、测试等。

    如果你想利用关键的 Java 机器学习库进行设计、构建和部署你自己的机器学习应用,请查阅 Packt Publishing 出版社出版的《Java 机器学习》(Machine Learning in Java)一书。

    转载自:https://hub.packtpub.com/most-commonly-used-java-machine-learning-libraries/#

    下一步阅读:

    5 JavaScript machine learning libraries you need to know

    A non programmer’s guide to learning Machine learning

    Why use JavaScript for machine learning?

    展开全文
  • KNN人工智能机器学习算法JAVA实现文本的读取和情感分类 包含测试数据集和训练数据集
  • 1、算法基本原理: 对于K个类别的数据选取K个质心 距离第 个质心最近的点归为 类 2、算法具体步骤: - 选取K个随机点,将其标注为K个类别 - 计算样本点到这K个随机点的距离,根据距离最近的第i个点将其分类i类 ...

    1、算法基本原理:

    • 对于K个类别的数据选取K个质心
    • 距离第 个质心最近的点归为 类

    2、算法具体步骤:
    - 选取K个随机点,将其标注为K个类别
    - 计算样本点到这K个随机点的距离,根据距离最近的第i个点将其分类i类
    - 根据分类的结果,计算新的质心,质心计算公式如下:

    xinew=1nj=1nxj

    - 根据新的质心重复(1)(2)(3)步骤直到达到停止条件:
    ||xnewixoldi||<ξ,ξ

    下列数据使用R软件生成,Java处理

    R程序语言:
    X<-matrix(1:200,nrow=100,ncol=2)
    Y<-matrix(0,nrow=100,ncol=1)
    for (i in 1:100){
       if (runif(1)<0.5){
       X[i,1]=exp(runif(1))*1.3  
       X[i,2]=exp(runif(1))*3
       Y[i]=0
    }
       else{
       X[i,1]=exp(runif(1))*3
       X[i,2]=exp(runif(1))*3
       Y[i]=1
    }
    }
    data<-cbind(Y,X)
    write.table(data,"C:/Users/CJH/Desktop/R程序运行/Kmeanstest.txt",row.names=FALSE,
    col.names=FALSE)
    #生成数据
    
    Eclipse程序语言:
    package kmeans;
    
    import java.io.*;
    import java.util.*;
    
    public class InputData{
        public void loadData(double [][]x,double[]y,String trainfile)throws IOException{
           File file = new File("C:\\Users\\CJH\\Desktop\\R程序运行",trainfile);
           RandomAccessFile raf= new RandomAccessFile(file,"r");
           StringTokenizer tokenizer;   
           int i=0,j=0;
           while(true){
               String line = raf.readLine();
               if(line==null)break;
               tokenizer= new StringTokenizer(line);
               y[i]=Double.parseDouble(tokenizer.nextToken());
               while(tokenizer.hasMoreTokens()){
               x[i][j]=Double.parseDouble(tokenizer.nextToken());
               j++;
               }
               j=0;i++;
           }
           raf.close();
        }
    
    }
    //读入数据
    
    package kmeans;
    
    public class Kmean {
        public static double[] classfy(double[] u0,double[] u1,double[][] X){
            double[] y1=new double[100];
            double[] u=new double[2];
            for (int i=0;i<100;i++){
            y1[i]=0;
            u[0]=X[i][0];
            u[1]=X[i][1];
            if(euclid(minus(u,u0))>euclid(minus(u,u1))){
                y1[i]=1;
            }
    
        }
            for (int i=0;i<100;i++){
                System.out.println(y1[i]+" ");
            }
            return y1;
    
    }
        public static double[] newu(double[] y1,int k,double[][] X){
            double[] u=new double[2];
            double[] u1=new double[2];
            double[] u2=new double[2];
            double[] a=new double[2];
            u1[0]=0;
            u1[1]=0;
            u2[0]=0;
            u2[1]=0;
            int t1=0;
            int t2=0;
            for (int i=0;i<100;i++){
                    if(k==1){
                        if(y1[i]==1){
                            a[0]=X[i][0];
                            a[1]=X[i][1];
                            u1=plus(u1,a);
                            t1=t1+1;
                     }
                 u=dividV(u1,t1);
                    }
                    if(k==0){
                       if(y1[i]==0){
                            a[0]=X[i][0];
                            a[1]=X[i][1];
                            u2=plus(u2,a);
                            t2=t2+1;
                    }
                 u=dividV(u2,t2);
                  }
            }
                return u;
        }
    
        private static double[] dividV(double[] u, int t) {
            double[] temp=new double[2];
            for (int i=0;i<2;i++){
                temp[i]=u[i]/t;
            }
            return temp;
        }
        private static double[] plus(double[] u, double[] ds) {
            double[] temp=new double[2];
            for (int i=0;i<2;i++){
                temp[i]=u[i]+ds[i];
            }
            return temp;
        }
        private static double euclid(double[] x) {
            double sum=0;
            for (int i=0;i<2;i++){
                sum=sum+Math.pow(x[i], 2);
            }
            double euclid=Math.sqrt(sum);
            return euclid;
        }
    
        private static double[] minus(double[] x,double[] y) {
            double[] temp=new double[2];
            for (int i=0;i<2;i++){
                temp[i]=x[i]-y[i];
            }
            return temp;
    //Kmeans程序
    
    package kmeans;
    
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Kmain {
    public static void main(String[]arg) throws IOException{
        double[][] X=new double[100][2];
        double[] Y=new double[100];
        InputData d=new InputData();
        try {
            d.loadData(X, Y, "data.txt");
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        for(int i=0;i<100;i++){
            for (int j=0;j<2;j++){
                System.out.print(X[i][j]+" ");
            }
            System.out.println(Y[i]);
        }
        int[] U0=new int[2];
        U0[0]=(int)(Math.random()*X.length);
        U0[1]=(int)(Math.random()*X.length);
        while(U0[1]==U0[0]){
            U0[1]=(int)(Math.random()*X.length);
        }
        System.out.println(X[U0[0]][0]+" "+X[U0[0]][1]+"\n"+" "+X[U0[1]][0]+" "+X[U0[1]][1]);
        double[] u0=new double[2];
        double[] u1=new double[2];
        double[] u2=new double[2];
        double[] u3=new double[2];
        double[] y1=new double[100];
        u0[0]=X[U0[0]][0];
        u0[1]=X[U0[0]][1];
        u1[0]=X[U0[1]][0];
        u1[1]=X[U0[1]][1];
        System.out.println(u0[0]+" "+u0[1]);
        System.out.println(u1[0]+" "+u1[1]);
        y1=Kmean.classfy(u0,u1,X);
        u2=Kmean.newu(y1,0,X);
        u3=Kmean.newu(y1,1,X);
        for (int i=0;i<100;i++){
            System.out.println(y1[i]+" ");
        }
        while(euclid(minus(u2,u0))+euclid(minus(u3,u1))>0.000001){
            u0=u2;
            u1=u3;
            y1=Kmean.classfy(u0,u1,X);
            u2=Kmean.newu(y1,0,X);
            u3=Kmean.newu(y1, 1, X);
        }
        System.out.println(u2[0]+" "+u2[1]);
        System.out.println(u3[0]+" "+u3[1]);
        FileWriter fw=new FileWriter("C:\\Users\\CJH\\Desktop\\R程序运行\\class.txt");
        for(int i=0;i<100;i++){
            fw.write((int) y1[i]+" ");
        }
        fw.close();
    }
    private static double euclid(double[] x) {
        double sum=0;
        for (int i=0;i<2;i++){
            sum=sum+Math.pow(x[i], 2);
        }
        double euclid=Math.sqrt(sum);
        return euclid;
    }
    
    private static double[] minus(double[] x,double[] y) {
        double[] temp=new double[2];
        for (int i=0;i<2;i++){
            temp[i]=x[i]-y[i];
        }
        return temp;
      }
    }
    //主程序部分
    

    这里写图片描述

    原始数据

    这里写图片描述

    分类结果

    如上图所示,点2和点3为质心点的位置。上图显示Kmeans对该组数据分类结果十分好,达到了百分之百。

    展开全文
  • 可用于学习机器学习算法时的实验与实现 最好是在了解了机器学习相关基本理论后再看这个。
  • 雷锋网按:机器学习与人工智能变得越来越热。大数据原本在工业界中就已经炙手可热,而基于大数据的机器学习则更加流行,...跟我们生活息息相关的最常见机器学习算法包括电影推荐算法、图书推荐算法。这些算法都是基
  • 人工智能机器学习Java也可以 用于Java的5大机器学习库盘点 机器学习是目前最热门的技能之一,许多公司都在争先恐后的寻找能够编写ML和深度学习代码的程序员,本文将为大家盘点5个针对Java的首选ML库 #WEKA ...
  • 机器学习算法比较

    2016-05-31 09:42:37
    本文主要回顾下几个常用算法的适应场景及其优缺点!...机器学习算法太多了,分类、回归、聚类、推荐、图像识别领域等等,要想找到一个合适算法真的不容易,所以在实际应用中,我们一般都是采用启
  • 本列表总结了25个Java机器学习工具&库: Weka集成了数据挖掘工作的机器学习算法。这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用。Weka包括一系列的工具,如数据预处理、分类、回归、聚类、关联...
  • 而要成为一名合格的机器学习算法工程师(以下简称算法工程师)更是难上加难,因为在掌握工程师的通用技能以外,还需要掌握一张不算小的机器学习算法知识网络。下面我们就将成为一名合格的算法工程师所需的技能进行...
  • opencv提供了非常多的机器学习算法用于研究。这里对这些算法进行分类学习和研究,以抛砖引玉。这里使用的机器学习算法包括:人工神经网络,boost,决策树,最近邻,逻辑回归,贝叶斯,随机森林,SVM等算法等。机器...
  • a bytes-like object is required, not 'str'Python机器学习核心预测算法第2章 通过理解数据来了解问题2.1 解剖一个新问题2.1.1 属性和标签的不同类型决定模型的选择2.1.2 新数据集的注意事项2.2 分类问题:用声呐...
  • 机器学习及flinkML算法 机器学习概念 机器学习算法根据训练数据(training data)使得表示算法行为的数学目标最大化,并以此来进行预测或者做出决定。机器学习分为分类、回归、聚类等,每种都有不一样的目标。 应用...
  • 机器学习简介 1、机器学习 运用学习算法,利用所给的数据进训练,生成相应的模型。在面对新情况时,根据模型,给出正确的判断。 2、学习的定义 针对经验E (experience) 和一系列的任务 T (tasks) 和一定表现的...
  • 机器学习算法可以分为三个大类:监督学习、无监督学习、强化学习。其中: 监督学习对于有标签的特定数据集(训练集)是非常有效的,但是它需要对于其他的距离进行预测。 无监督学习对于在给定未标记的数据集...
  • 1、Weka集成了数据挖掘工作的机器学习算法。这些算法可以直接应用于一个数据集上或者你可以自己编写代码来调用。Weka包括一系列的工具,如数据预处理、分类、回归、聚类、关联规则以及可视化。 2.Massive Online ...
  • 摘要: 你是一名希望开始或者正在学习机器学习Java程序员吗? 利用机器学习编写程序是最佳的学习方式。你可以从头开始编写算法,但是利用现有的开源库,你可以取得更大的进步。 本文介绍了主要的平台和开放源码的...
1 2 3 4 5 ... 20
收藏数 82,099
精华内容 32,839