精华内容
下载资源
问答
  • 第2001列是类标识,他是一个代号,我用整数表示,但是weka默认给我弄成了小数 解决方法:在arff文件中 @attribute 999 numeric @attribute 1000 numeric %%@attribute 2001 numeric将这一行改成下面,用选择的...

    第2001列是类标识,他是一个代号,我用整数表示,但是weka默认给我弄成了小数

    解决方法:在arff文件中

    @attribute 999 numeric
    @attribute 1000 numeric

    %%@attribute 2001 numeric将这一行改成下面,用选择的形式,先把可能的值列出来

    @attribute 2001 {1,2,3,4,5,6,7,8,9,10,11。。}

    有图有真相


    更改后



    展开全文
  • Weka数据预处理

    千次阅读 2019-04-08 09:01:44
    Weka数据预处理(一) 对于数据挖掘而言,我们往往仅关注实质性的挖掘算法,如分类、聚类、关联规则等,而忽视待挖掘数据的质量,但是高质量的数据才能产生高质量的挖掘结果,否则只有"Garbage in garbage out"了。...

    Weka数据预处理(一)

    对于数据挖掘而言,我们往往仅关注实质性的挖掘算法,如分类、聚类、关联规则等,而忽视待挖掘数据的质量,但是高质量的数据才能产生高质量的挖掘结果,否则只有"Garbage in garbage out"了。保证待数据数据质量的重要一步就是数据预处理(Data Pre-Processing),在实际操作中,数据准备阶段往往能占用整个挖掘过程6~8成的时间。本文就weka工具中的数据预处理方法作一下介绍。

    Weka 主要支持一种ARFF格式的数据,含有很多数据过滤方法。关于ARFF格式文件,可以在此处了解详情。

    Weka的数据预处理又叫数据过滤,他们可以在weka.filters中找到。根据过滤算法的性质,可以分为有监督的(SupervisedFilter)和无监督的(UnsupervisedFilter)。对于前者,过滤器需要设置一个类属性,要考虑数据集中类的属性及其分布,以确定最佳的容器的数量和规模;而后者类的属性可以不存在。同时,这些过滤算法又可归结为基于属性的(attribute)和基于实例的(instance)。基于属性的方法主要是用于处理列,例如,添加或删除列;而基于实例的方法主要是用于处理行,例如,添加或删除行。

    数据过滤主要解决以下问题(老生常谈的):

    数据的缺失值处理、标准化、规范化和离散化处理。

    数据的缺失值处理:weka.filters.unsupervised.attribute.ReplaceMissingValues。对于数值属性,用平均值代替缺失值,对于nominal属性,用它的mode(出现最多的值)来代替缺失值。

    标准化(standardize):类weka.filters.unsupervised.attribute.Standardize。标准化给定数据集中所有数值属性的值到一个0均值和单位方差的正态分布。

    规范化(Nomalize):类weka.filters.unsupervised.attribute.Normalize。规范化给定数据集中的所有数值属性值,类属性除外。结果值默认在区间[0,1],但是利用缩放和平移参数,我们能将数值属性值规范到任何区间。如:但scale=2.0,translation=-1.0时,你能将属性值规范到区间[-1,+1]。

    离散化(discretize):类weka.filters.supervised.attribute.Discretizeweka.filters.unsupervised.attribute.Discretize。分别进行监督和无监督的数值属性的离散化,用来离散数据集中的一些数值属性到分类属性。

    下文将详细介绍一下Weka数据过滤类。

    Weka数据预处理(二)

    首先来看一下,有关属性—有监督过滤器。

    AddClassification

    该过滤器使用给定的分类器对原始数据添加分类标签,并给出类的分布以及关于原始数据集的错误分类标记。

    其实就是利用分类算法对原始数据集进行预分类,其结果与在classify阶段得到的结果基本一致,同样包括分类的正确率等信息。

    AttributeSelection

    该过滤器,用于进行属性选择。根据给定的挖掘任务,利用合适的评估器,选择最有利于当前挖掘任务的属性。

    ClassOrder

    该过滤器用于改变的数据对象顺序,适用于binary对象和nominal对象。

    Discretize

    离散化过滤器,用于将连续属性离散化。使用频率非常高的一个过滤器,在实际应用当中,离散化也是很常见的数据预处理步骤。

    NorminalToBinary

    标称值转化为二分值。举个例子吧,看官请看下图,一目了然。

    Nominal value

    Binary value

    下面谈到的是实例—有监督过滤器

    Resample

    让人又爱又恨的抽样过滤器。利用放回或者不放回方法抽取特定大小的随机样本。

    抽样方法有很多种,基于水库的、链式抽样、分层抽样等等。

    SMOTE

    同样是抽样过滤器,叫综合少数过采样技术。他要求被采样的原始数据集必须全部存储在内存中。详细内容可以参考Synthetic Minority Over-sampling Technique

    SpreadSubsamp

    该分类器需要得知类标是属性中的哪一个.当获得了类标之后,他会计算出类标属性的分布,同时,按照参数M,指定类标分布的最大差距,比如当给出参数W时,调整数据实例的权重。

    注意,M参数设定值为l时,那么就认为是均匀分布,当设定为0的时候,那么不进行类标分布的拓展(SPread);如果设定大于l,那么这个值就表示了分布最大的类标属性(类标属性最为常见的值)和分布最小的属性(类标属性最为稀少的值)的分布的比例。

    StratfiedRemoveFold

    该过滤器简单的使用n重交叉验证的方法,将数据集进行分割,并返回按照参数指定的子集。

    关于无监督方法的过滤器,可以参考:http://www.cnblogs.com/htynkn/archive/2012/04/02/weka_3.html

    参考:

    http://www.pluscn.net/?p=1394

    http://www.pluscn.net/?p=1400

    输入数据与ARFF文件--数据挖掘学习和weka使用(二)

    数据预处理和weka.filters的使用--数据挖掘学习和weka使用(三)

    weka数据预处理的更多相关文章

    1. 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率

      原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...

    2. R语言进行数据预处理wranging

      R语言进行数据预处理wranging li_volleyball 2016年3月22日 data wrangling with R packages:tidyr dplyr Ground rules ...

    3. Scikit-Learn模块学习笔记——数据预处理模块preprocessing

      preprocessing 模块提供了数据预处理函数和预处理类,预处理类主要是为了方便添加到 pipeline 过程中. 数据标准化 标准化预处理函数: preprocessing.scale(X, ...

    4. Deep Learning 11_深度学习UFLDL教程:数据预处理(斯坦福大学深度学习教程)

      理论知识:UFLDL数据预处理和http://www.cnblogs.com/tornadomeet/archive/2013/04/20/3033149.html 数据预处理是深度学习中非常重要的一 ...

    5. R语言--数据预处理

      一.日期时间.字符串的处理 日期 Date: 日期类,年与日 POSIXct: 日期时间类,精确到秒,用数字表示 POSIXlt: 日期时间类,精确到秒,用列表表示 Sys.date(), date( ...

    6. 对数据预处理的一点理解[ZZ]

      数据预处理没有统一的标准,只能说是根据不同类型的分析数据和业务需求,在对数据特性做了充分的理解之后,再选择相关的数据预处理技术,一般会用到多种预处理技术,而且对每种处理之后的效果做些分析对比,这里面经 ...

    7. Python数据预处理—归一化,标准化,正则化

      关于数据预处理的几个概念 归一化 (Normalization): 属性缩放到一个指定的最大和最小值(通常是1-0)之间,这可以通过preprocessing.MinMaxScaler类实现. 常用的 ...

    8. sklearn数据预处理-scale

      对数据按列属性进行scale处理后,每列的数据均值变成0,标准差变为1.可通过下面的例子加深理解: from sklearn import preprocessing import numpy as ...

    9. 第七篇:数据预处理(四) - 数据归约(PCA/EFA为例)

      前言 这部分也许是数据预处理最为关键的一个阶段. 如何对数据降维是一个很有挑战,很有深度的话题,很多理论书本均有详细深入的讲解分析. 本文仅介绍主成分分析法(PCA)和探索性因子分析法(EFA),并给 ...

    展开全文
  • 这篇博客主要讲解Weka的数据格式 Weka数据格式Weka的专有数据格式ARFF及与其他格式文件之间的转换。

    上一篇博客主要讲解了Weka开发环境的搭建,从本博客开始就正式进入Weka开发。
    进行数据挖掘,首先要关注的是数据,这篇博客主要讲解Weka的数据格式和在Weka中如何操作数据。

    • Weka数据格式

      Weka的专有数据格式是ARFF,下面是Weka自带的data文件夹里的一个ARFF文件

    % ARFF file for the weather data with some numric features
    %
    
    @relation weather
    
    @attribute outlook {sunny, overcast, rainy}
    @attribute temperature real
    @attribute humidity real @attribute windy {TRUE, FALSE} @attribute play {yes, no}
    @data
    
    %
    % 14 instances
    %
    sunny,85,85,FALSE,no
    sunny,80,90,TRUE,no
    overcast,83,86,FALSE,yes
    rainy,70,96,FALSE,yes
    rainy,68,80,FALSE,yes
    rainy,65,70,TRUE,no
    overcast,64,65,TRUE,yes
    sunny,72,95,FALSE,no
    sunny,69,70,FALSE,yes
    rainy,75,80,FALSE,yes
    sunny,75,70,TRUE,yes
    overcast,72,90,TRUE,yes
    overcast,81,75,FALSE,yes
    rainy,71,91,TRUE,no

    其实不难看出,Weka的专有数据格式和CSV文件非常相似,CSV即为逗号分隔符文件,最大的区别在于,Weka头部有每列数据的属性标识。常见的包头如下所示:

       @RELATION iris
    
       @ATTRIBUTE sepallength  NUMERIC
       @ATTRIBUTE sepalwidth   NUMERIC
       @ATTRIBUTE petallength  NUMERIC
       @ATTRIBUTE petalwidth   NUMERIC
       @ATTRIBUTE class        {Iris-setosa,Iris-versicolor,Iris-virginica}
    • Weka数据格式分析

    ① 其中@RELATION后面是关系名,如果你只打开一个文件,就是该文件的文件名。

    @relation <relation-name> 
    <relation-name>一个字符串
    如果这个字符串包含空格,它必须加上引号(指英文标点的单引号或双引号)

    ② @ATTRIBUTE指的是该列的属性,包括NUMERIC指的是数值型变量等以下四种变量类型:

    numeric                           数值型 
    <nominal-specification>           分类(nominal)型 
    string                            字符串型 
    date [<date-format>]              日期和时间型 

    其中NUMERIC一般用于连续型数值变量,nominal一般是离散型类别变量。

    ③ 对于@class类型。指的是类别变量,其所有的取值被大括号包括,如下所示:

    由<nominal-specification>组成的类别名放在花括号中:
    {<nominal-name1>, <nominal-name2>, <nominal-name3>, ...} 
    实际数据类别只能是花括号中的某一个

    ④@date指的是日期型变量,在数据挖掘中,日期型变量可以直接相加减以获取时间间隔,

    @attribute <name> date [<date-format>] 
    <name>是属性的名称
    <date-format>是一个字符串来规定该怎样解析和显示日期或时间的格式
    默认的字符串格式是ISO-8601所给的日期时间组合格式“yyyy-MM-ddTHH:mm:ss”。 

    ⑤除此之外,还有@data标识符,用来表明数据的具体内容:

    @data 
    sunny,85,85,FALSE,no 
    ?,78,90,?,yes 
    
    每个实例占一行
    实例的各属性值用逗号“,”隔开
    缺失值(missing value)用问号“?”表示

    ⑥ Weka中针对稀疏数据也有更加方便的表示,即稀疏变量格式:有的时候数据集中含有大量的0值,这个时候用稀疏格式的数据存贮更加省空间。
    如对于下述数据:

    @data 
        0, X, 0, Y, "class A" 
        0, 0, W, 0, "class B" 

    可以使用稀疏格式表达为:

    @data 
        {1 X, 3 Y, 4 "class A"} 
        {2 W, 4 "class B"} 
    实例中每一个非0的属性值用<index> <空格> <value>表示

    Weka官方关于ARFF文件格式的介绍可以在下面地址找到:
    http://weka.wikispaces.com/ARFF+%28book+version%29

    Weka专有格式和其他格式之间的相互转换
    有时候我们可能有其他格式的数据,想转化为ARFF格式的文件,或者想把ARFF格式的文件转化成其他文件格式,Weka也可以很好的支持。
    一种方式是使用GUI,打开文件后另存为,另一种方式是在代码中使用Weka的ConverterUtils工具类直接实现,下面贴出我自己写的JAVA的代码:

       public static void fileTypeConverter(String inputFile, String outputFile) {
            File input = new File(inputFile);
            File output = new File(outputFile);
            AbstractFileLoader loader = ConverterUtils.getLoaderForFile(input);
            AbstractFileSaver saver = ConverterUtils.getSaverForFile(output);
            try {
                loader.setSource(input);
                Instances data = loader.getDataSet();
                System.out.println(data);
                saver.setInstances(data);
                saver.setFile(output);
                saver.setDestination(output);
                saver.writeBatch();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    需要注意的是,在使用转换功能之前,应该使用Weka的Filter指定每一列的属性类别,免得所有列都按照默认的NUMRIC类型处理。对于Filter和Instances的介绍将在接下来几篇博客里面继续讲解。

    CSV和LibSVM格式互转JAVA代码:

    1. LIBSVM to CSV
      加上了错误行处理,可以自己写正则表达式匹配不对的行并抓出来:
    public static void libsvmToCsv(String inputFile, String outputFile, int numOfAttributes, ArrayList indexOfNominal) {
            BufferedReader br = null;
            BufferedWriter bw = null;
            String s;
            Pattern patternIsNum = Pattern.compile("[0-9.]*");
            Pattern patternIsSciNotation = Pattern.compile("^((\\d+.?\\d+)[E]{1}(\\d+))$");
            long lineNum = 0;
    
            try {
                br = new BufferedReader(new FileReader(inputFile));
                bw = new BufferedWriter(new FileWriter(outputFile));
                int errorCount = 0;
                do {
                    s = br.readLine();
                    lineNum++;
                    boolean errorFlag = false;
                    if (s == null)
                        break;
                    String[] result = new String[numOfAttributes + 1];
                    StringBuffer sb = new StringBuffer();
                    for (int i = 0; i < numOfAttributes; i++) {
                        result[i] = "0,";
                    }
    
                    String temp[] = s.split(" ");
                    result[numOfAttributes] = temp[0];
                    for (int i = 1; i < temp.length; i++) {
                        String[] innerTemp = temp[i].split(":");
                        char[] indexArray = innerTemp[0].toCharArray();
                        if (innerTemp.length > 1) {
                            int attributesIndex = Integer.parseInt(innerTemp[0]);
                            Matcher isSciNotation = patternIsSciNotation.matcher(innerTemp[1]);
                            Matcher isNum = patternIsNum.matcher(innerTemp[1]);
    
                            if (isSciNotation.matches()) {
                                result[attributesIndex - 1] = new BigDecimal(innerTemp[1]).toPlainString() + ",";
                            } else if (isNum.matches() || indexOfNominal.contains(attributesIndex)) {
                                result[attributesIndex - 1] = innerTemp[1] + ",";
                            } else {
                                errorFlag = true;
                            }
                        }
                    }
                    if (errorFlag) {
                        errorCount++;
                        System.out.println("第" + errorCount + "条-----第 " + lineNum + "行------ " + s);
                    }
                    else {
                        for (int j = 0; j < numOfAttributes + 1; j++) {
                            sb.append(result[j]);
                        }
                        bw.write(sb.toString());
                        bw.newLine();
                    }
                } while (s != null);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    br.close();
                    bw.flush();
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    展开全文
  • 本篇博客讲解下Weka数据的属性Attribute。

    本篇博客讲解下Weka中数据的属性Attribute。

    • 什么是Attribute?

    attribute指的是Weka中数据的属性,一般就是表明数据集信息,数据每一列的性质等。之前讲过的Weka数据格式ARFF其实头信息包含的就是数据的Attribute信息。之前讲的Weka的数据存储方式Instances也有Attribute属性。
    Attribute属性主要分以下几类,上一篇博客也有具体分析,这节再温习一下:

    numeric: This type of attribute represents a floating-point number. 
             就是代表连续的,浮点数变量,如气温。
    nominal: This type of attribute represents a fixed set of nominal values. 
             指的是离散的,刻意被划分为几类的变量,如户口类型。
    string: This type of attribute represents a dynamically expanding set of nominal values. Usually used in text classification. 
             指的该列内容是文本,一般用于文本挖掘。
    date: This type of attribute represents a date, internally represented as floating-point number storing the milliseconds since January 1, 1970, 00:00:00 GMT. The string representation of the date must be ISO-8601 compliant, the default is yyyy-MM-dd'T'HH:mm:ss. 
             指的该列数据代表日期,要按照规范格式写。
    relational: This type of attribute can contain other attributes and is, e.g., used for representing Multi-Instance data. (Multi-Instance data consists of a nominal attribute containing the bag-id, then a relational attribute with all the attributes of the bag, and finally the class attribute.) 
            用来实现其他类型的数据。
    • Attribute用法

    Attribute既然是数据的属性,那它只有和数据绑定才有意义。一般来讲,如果读入的文件来自标准格式,如ARFF/CSV,文件头就包含了特征属性名等信息,如果读入txt/libSVM,则Weka要么提示你缺少属性名,要么就会直接把第一条数据当成属性。这样会导致错误。所以加载数据前务必手动添加属性名,无法添加的话就必须手动指定或者修改属性。
    下面是官方给的Examlpe:

    // Create numeric attributes "length" and "weight" 
    Attribute length = new Attribute("length"); 
    Attribute weight = new Attribute("weight"); 
    // Create list to hold nominal values "first", "second", "third" 
    List my_nominal_values = new ArrayList(3); 
    my_nominal_values.add("first"); 
    my_nominal_values.add("second"); 
    my_nominal_values.add("third"); 
    // Create nominal attribute "position" 
    Attribute position = new Attribute("position", my_nominal_values);

    上面的例子告诉了你如何创建一个Numeric和Nominal属性。一般来说,除非是做文本挖掘项目,一般这两个属性就够了。所以掌握这两个属性的创建方法在使用中已经足够。
    另外,当Instances被创建时,你也可以随时使用Attribute方法获取属性信息。如下面的简单打印。

     for(int j=0;j<data.numAttributes();j++) {
                    Attribute attribute = data.attribute(j);
                    System.out.println(attribute);
                }
    • Attribute和Instance/Instances

      这里需要注意的一点是,当你创建一个Instance时,必须要为之指定Attribute,如何创建instance之前的一篇博客有讲过,在此不在赘述。
      如果想创建一个新的Instances又不想输入属性,可以直接从已有的数据直接获取Attribute信息,方法是

    DataSource source = new DataSource("/some/where/data.arff");
    
    Instances A = source.getDataSet();
    Instances blank = new Instances(A,0
    展开全文
  • WEKA数据

    千次阅读 2018-09-30 15:21:46
    WEKA数据集: WEKA所处理的数据集是一个.arff(attribute relation file)为后缀名的二维表。这是一种ASCII文本文件。以%开始的行是注释。 表中具体的内容: @relation+文件名称 @attribute+属性名和具体的属性值 @...
  • 本博客讲解以下Weka运行时数据的存储对象Instances和Instance。
  • weka数据格式转换程序

    2008-12-05 13:23:26
    该matlab程序用于数据格式转换,能将mat数据转换为weka所需的数据类型.
  • weka数据挖掘分析

    千次阅读 2017-05-16 08:07:36
    基于Weka 数据聚类分析银行用户的购买力 通过分析对银行储户信息的分析,进行cluster分类,最终找到合适的消费 人群。 实验基本原理及目的 聚类分析中的“类”(cluster)和前面分类的“类”(class)是不同的,对...
  • Weka数据挖掘

    千次阅读 2013-09-07 14:23:35
    WEKA的全名是怀卡托智能分析环境(Waikato Environment for Knowledge Analysis),它...同时weka也是新西兰的一种鸟名,而WEKA的主要开发者来自新西兰。 详见 http://www.china-pub.com/computers/common/info.as
  • DBLP数据集用weka数据挖掘 xml转csv格式文件写在前面xml转csv格式文件数据预处理weka数据挖掘 写在前面 之前做了中国科学院大学的一门研讨课《数据挖掘技术与应用》,老师讲的非常好,这门课的几个大项目真的让我学...
  • weka类型映射

    2019-10-01 19:59:30
    weka只支持4个数据类型,跟数据库对不上号,所以需要自己手动将数据库读出来的数据映射成weka支持的类型才能进行处理 配置文件位置在/src/weka/experiment/DatabaseUtils.props # General information on database...
  • 其实有些整数型字段是nominal类型,我更改了DatabaseUtils.props中配置,想把int和smallint区分开来以此区分numeric和nominal,但是并没有什么作用,weka加载数据时还会把所有整型识别成numeric类型。请问我应该如何...
  • weka数据集预处理

    千次阅读 2016-09-27 17:52:58
    1. 利用有监督的离散算法对数据集的属性进行离散,并保存离散后的数据集; import java.io.File; import weka.filters.SupervisedFilter; import java.io.IOException; import weka.core.Instances; import ...
  • weka进行数据预处理

    万次阅读 2015-04-06 14:27:09
    Weka同时也具有读入“.csv”格式文件的能力,在做数据挖掘中,很多时候数据是存储在excel的电子表格中,打开Excel文件,从File(文件)下拉菜单下选择Save As(另存为),在弹出的对话框中,最下边会有Save As type...
  • weka 数据定义

    千次阅读 2013-12-23 18:27:21
    数据挖掘:概念与技术(原书第3版) 2.1.2 标称属性 标称意味“与名称相关”。标称属性(nominal attribute)的值是一些符号或事物的名称。每个值代表某种类别、编码或状态,因此标称属性又被看做是分类的...
  • 初试weka数据挖掘

    2013-09-07 13:26:00
    偶然间在网上看到了一篇关于weka好的博文,就记录了下来…… weka下载地址为http://www.cs.waikato.ac.nz/ml/weka/downloading.html 读者有时候看到两个图片... 数据挖掘、机器学习这些字眼,在一些人看来,是...
  • weka数据挖掘入门

    2013-09-07 20:05:48
    weka下载地址为http://www.cs.waikato.ac.nz/ml/weka/downloading.html   读者有时候看到两个图片并列,其中一个是原文的,另一个是我实验时打开的。 一.引入  数据挖掘、机器学习这些字眼,在一些人...
  • [转] 有关weka数据格式

    2014-06-28 11:35:24
    摘自:... Weka简介 (http://www.china-pub.com/computers/common/info.asp?id=29304) WEKA的全名是怀卡托智能分析环境(Walkato Environment for Knowledge An...
  • 使用Weka进行数据挖掘

    千次阅读 2015-04-17 10:04:43
    使用Weka进行数据挖掘 1.简介数据挖掘、机器学习这些字眼,在一些人看来,是门槛很高的东西。诚然,如果做算法实现甚至算法优化,确实需要很多背景知识。但事实是,绝大多数数据挖掘工程师,不需要去做算法层面...
  • weka数据集学习

    2021-02-22 20:05:27
    每次先选定数据集,才可以继续选择上方的分类、...Weka数据集格式-ARFF Weka处理的数据集通常是存放在一种叫ARFF格式的文件中的。那么,什么是ARFF呢? 以weather.nominal.arff数据集为例,完整的数据集如下表示:.
  • Weka介绍--使用Weka进行数据挖掘

    千次阅读 2015-03-06 21:50:17
    1.简介 数据挖掘、机器学习这些字眼,在一些人看来,是门槛很高的东西。诚然,如果做算法实现甚至算法优化,确实需要很多背景...而weka,便是数据挖掘工具中的佼佼者。 Weka的全名是怀卡托智能分析环境(Waikato En
  • 应用WEKA进行数据分类

    2009-05-31 10:20:45
    为了实现这一目的,我们需要有一个训练数据集,这个数据集中每个实例的输入和输出都是已知的。观察训练集中的实例,可以建立起预测的模型。有了这个模型,我们就可以对新的输出未知的实例进行预测了。衡量模型的好坏...
  • 如何使用Weka进行数据分类,模型学习和构建,模型评价与预测

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,540
精华内容 1,016
关键字:

weka数据类型