关于数据
数据是一切的根本。
一.获取数据
1.我们实质是获取所需信息,再把这些信息转为可以字面表示的数据
2.可以使用爬虫scrapy获取数据,但是更一般的是自家数据库中的数据
3.可以获得公用数据集:http://www.kaggle.com/datasets等网站,也可以自己收集数据
4.人工合成数据:自己创造、扩充数据(添加失真)、数据变换,模型方法...
5.注意:1)数据量尽可能多、利于训练;(2)数据内容尽可能有效,能对预测产生作用(有用的特征);(3)数据尽可能要均匀(分类),即全面
6.注意:无论是数据获取还是处理,都要注意多做备份,有能力每步都要备份,数据的价值难以想象
1 # 一.获取数据:tf.keras.utils.get_file根据url下载数据到指定文件夹, 2 DATAS_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv" 3 datas_path = tf.keras.utils.get_file(r"E:\python_work\machine_learning\datas\datas.csv", DATAS_URL) 4 5 # 二.读取数据:把文件中的数据转为dataset类型进行使用,有时要指定标签 6 # 1.读取csv文件 7 # (1)若csv第一行不为列名,则需要给定列名;若csv第一行为列名,则可直接读取, 8 CSV_COLUMNS = ['survived', 'sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone'] 9 dataset = tf.data.experimental.make_csv_dataset(datas_path, column_names=CSV_COLUMNS, 10 batch_size=1,LABEL_COLUMN = 'survived') 11 12 # 2.读取numpy文件 。.npz 13 # 也是从路径读取,先把文件转为np数组类型,在转换为dataset 14 data = np.load('https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz') 15 train_examples = data['x_train'] 16 train_labels = data['y_train'] 17 train_dataset = tf.data.Dataset.from_tensor_slices((train_examples, train_labels)) 18 19 # 3.将pandas文件中df数据转为data类型 20 csv_file = tf.keras.utils.get_file('heart.csv', 'https://storage.googleapis.com/applied-dl/heart.csv') 21 df = pd.read_csv(csv_file) 22 target = df.pop('target') 23 dataset = tf.data.Dataset.from_tensor_slices((df.values, target.values)) 24 # dataset = tf.data.Dataset.from_tensor_slices((dict(df), target)) 25 26 # 4.读取图片 27 # (1)获得图片 28 import pathlib 29 data_dir = tf.keras.utils.get_file(origin='https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz', 30 fname='flower_photos', untar=True) 31 data_dir = pathlib.Path(data_dir) 32 # # (2)生成图片方法1 33 image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255) #rescale指定将图像张量的数字缩放 34 image_count = len(list(data_dir.glob('*/*.jpg'))) 35 CLASS_NAMES = np.array([item.name for item in data_dir.glob('*') if item.name != "LICENSE.txt"]) 36 train_data_gen = image_generator.flow_from_directory(directory=str(data_dir), 37 batch_size=32, 38 shuffle=True, 39 target_size=(224, 224), 40 classes = list(CLASS_NAMES)) 41 # (3)方法2 (推荐) 42 #######首先将图片进行解码,将图片的标签和图片本身的张量表示提取出来 43 list_ds = tf.data.Dataset.list_files(str(data_dir/'*/*')) #把图片文件转换为数据集 44 def get_label(file_path): #从文件路径中获得标签 45 parts = tf.strings.split(file_path, os.path.sep) 46 return parts[-2] == CLASS_NAMES 47 def decode_img(img): #把图片解码为一个三维张量,并设定张量的大小,和图片的大小 48 img = tf.image.decode_jpeg(img, channels=3) 49 img = tf.image.convert_image_dtype(img, tf.float32) 50 return tf.image.resize(img, [224, 224]) 51 def process_path(file_path): 52 label = get_label(file_path) 53 img = tf.io.read_file(file_path) 54 img = decode_img(img) 55 return img, label 56 ####################### 57 # 其次用map函数 58 AUTOTUNE = tf.data.experimental.AUTOTUNE 59 labeled_ds = list_ds.map(process_path, num_parallel_calls=AUTOTUNE) #设定能自动加载多个图片 60 61 # 5.读取文本:将文本转为字符串,再将字符串转为数字列表,为每个单次映射到唯一的整数
---将信息转为数据形式后,先进行数据预处理---
二.数据预处理
1.数据清洗(Data cleaning)
(1)数据清洗是为了对原始数据进行重新审查和校验,目的在于删除重复信息、纠正存在的错误,并提供数据一致性
(2)不符合要求的数据主要是有不完整的数据、错误的数据、重复的数据三大类
【1】缺失数据(数据为空Null):如果缺失数据的记录占比较小,可以直接剔除(主要包括删除样本或删除特征两种,具体看哪个更多地保证数据的完整性),若缺失的数据很关键,则可以进行手动填充或者按某一个公式自动填充(填充公式有:均值,中位数,众数,0值,无穷,固定值,最大最小值,,概率分布,概率估计.....)
【2】重复的数据:通过判断记录间的属性值是否相等来检测记录是否相等,相等的记录合并为一条记录(即合并/清除)
【3】错误的数据:包括格式上、内容上、或逻辑上错误【比如获取的数据与常识不符(年龄大于200)等】,
【【1】】检测方法:用统计分析的方法识别可能的错误值或异常值,如偏差分析、识别不遵守分布或回归方程的值,也可以用简单规则库( 常识性规则、业务特定规则等)检查数据值,或使用不同属性间的约束、外部的数据来检测和清理数据。
【【2】】解决方法:去除或修改
(3)一致性检查:根据每个变量的合理取值范围和相互关系,检查数据是否合乎要求,发现超出正常范围、逻辑上不合理或者相互矛盾的数据。
2.数据数字化
(1)原始数据有很多种:数字、文字、图片....,而计算机能接收和进行处理的只能是数字,因此要把文字等数据转换为数字
(2)对于一条数据(或者说‘记录’/‘样本’)来说(比如一张图片),它所包含的信息是众多的(比如包含背景、颜色、时间....),所以就有了特征的概念,特征是反映事件或对象在某方面的表现(比如背景就是一种特征),因此要把数据数字化就是要把每一条样本数字化,实质上是对数据中的每个特征对应的数据进行数字化
(3)我们可以用一般的方法把原始数据转为数字,比如把非数字型特征映射为数字型特征;也可以根据经验把原始数据转换为数字,比如把图片转化为矩阵的形式、设置词典表示文本等
3.特征转换---为了建模
(1)由于我们要用数据进行建模,这本质上是对特征的数学运算,因此我们在保证数据数字化的同时也要保证特征的数学运算是合理的,主要体现在两个方面(1)数字的大小要反映特征本身的大小关系,(比如数字2>1,但2代表的特征是否大于数字1代表的特征?这是不一定的)(2)模型特征间的四则运算要有意义(比如2-1=1,在机器学习的模型中,2代表的特征减去1代表的特征等于1代表的特征,这是不一定的),因此要对数据特征进行转化而不是单纯地作数字映射
(2)按特征的性质,我们可以将特征分为以下两类,作相应的数据转换使得特征在建模时有意义:
【1】定量特征:数值型特征。特征的取值一般在实数空间,比如身高179.2cm。数值型特征包括离散型(温度...)和连续型(身高、体重...)
【2】定性特征:类别型特征。特征的取值一般为利用某个数字代表类别,比如1代表男性。类别型特征包括有序类别(大-3,中-2,小-1)和无序类别(红(1,0,0),黄(0,1,0),蓝(0,0,1))
(3)独热编码:即 One-Hot 编码,又称一位有效编码,比如:红(1,0,0),黄(0,1,0),蓝(0,0,1)
【1】优点:1)将离散特征的取值扩展到了欧式空间,离散特征的某个取值就对应欧式空间的某个点;2) 机器学习算法中,特征之间的距离或相似度的常用计算方法都是基于欧式空间的;3) 将离散型特征使用独热编码,会让特征之间的距离计算更加合理
(4)定性变量处理:由于定性特征在模型中存在数学运算不合理的缺点,(比如男表示1,女表示0,而1-0是毫无意义的)所以我们要找到方法处理它
【1】虚拟变量法:
【【1】】主要思想:把该定性特征中每个类别在模型中设置为变量,这些变量(类别)也被称为虚拟变量,虚拟变量为0/1型特征【0...1...0】
【【2】】优点:把每个类别作为变量,因此他们是不会直接进行数学运算的,也就避免了数学运算不合理,比如x1作为男,x2作为女,模型:y=ax1+bx2+c
【【3】】缺点:虚拟变量陷进:类别变量之和的概率为1,这会引起多重共线性问题,使得模型变得不稳定。
【【4】】改进1:设定一个类为基准变量,其他n-1个类与基准变量之间的差异作为虚拟变量,比如上面改进后模型为y=(b-a)x2+c
【【5】】改进1后的优点:解决了多重共线性的问题,而且变量前面的系数表示了改变量与基准变量之间的差距,如果该系数不显著(近0),则我们可以剔除它,即把它和基准类作为同一类别
【【6】】改进1后的缺点:遇到高维的类别型特征时,建模变量会急剧上升,给建模带来困难,而且每个虚拟变量能够给模型带来的信息量很小(比如类别间的顺序信息不能体现)
【【7】】改进2:选择占比最大的类别作为基准类别能最大地减少多重共线性
【2】多重共线性:我们很难得出y的变化来源于哪个自变量。在线性模型中,比如y=ax1+bx2+c,因变量的变动会导致预测值的变动,我们一般的假设是因变量之间相互独立,即特征间不相关,那么每个因变量的变动导致预测值的变动方向是明显的(把预测值看做一个球,每个因变量的变动会导致球在不同方向上突出)。但是如果因变量之间相关,即变量间能用线性表示,则我们不能衡量出被预测值的变化有多少来自变量1,有多少来自变量2(球在两个变量的作用下朝着一个方向凸起,但是我们不能判断导致凸起中有多少是变量1的作用,有多少是变量2的作用)
【【1】】检测:对于两个变量来说,如果他们都是定量变量,则可以用相关系数;如果一个定量一个定性,则可以用ANOVA;如果都为定性变量,可以用卡方检验。如果有多个变量,则可以用假设检验或者方差膨胀因子法。
【【2】】分类:1)数据型:由数据自身分布引发的共线性;2)结构型:由特征转换引起的共线性,比如x和x^2
【【3】】危害:增大了模型参数的估计值的方差,使得假设检验变得不灵敏-----增大数据量
【【4】】解决:1)数据型:增加数据量/减少变量/降维/加入惩罚项/鸵鸟政策(不作为);2)结构型共线性:变量归一化
【3】类别型特征到数值型特征的转变有利于保留类别特征的信息(比如有序):
【【1】】ridit_scoring(针对有序类别特征,二分类问题):假设类别变量x有t个可能的取值:x1...xt,各个类别在整体中所占比例为p1...pt,其他变量相同,x从1到t,用y=1的概率减少,则第i类的值为小于类别i所占的比例减去大于类别i所占的比例,类别型特征转为数值型特征的取值为-1到1:
(5)定量变量处理:
【1】边际效益恒定:对于纯线性模型来说,如果定量变量前面的系数大于0,则预测值随着定性变量的增加而增加,这会导致边际效益恒定。(如果事实是预测值随着变量的变化是波动变化的,则使用定量变量明显是错误的,所以我们进行定量变量离散化)
【2】变量离散化:定量变量转换为定性变量:区间法:把数值型变量划分区间转化为类别型变量
【【1】】问题1:怎么划分?划分太粗:模型效果欠佳;划分太细:过拟合风险上升
【【2】】解决1:基于卡方检验的划分法:用于度量两个类别变量的相关性。使用贪心算法来解决这个问题,直至卡方统计量小于某一个阈值
【【3】】卡方检验:评估某个定量变量和预测变量的卡方值,即(把定量变量区间化为定性变量,预测变量也为定性变量)卡方统计量越大,实际观测值与理论推断值之间的偏差越大,则这两个变量之间的相关性越大,说明x变量的划分对于预测值y是有意义的,该定性变量对预测值越相关越好,更重要。因为如果这两个变量独立无关,则预测值和理论值的差距应该越小。
【【4】】one-way-ANOVA方法:多组数据的均值是否显著不同
【【5】】方差膨胀因子
1 # 三.观测数据信息 2 df = pd.read_csv('E:\python_work\machine_learning\datas\iris\iris_test.csv', 3 names=['SepalLength', 'SepalWidth', 'PetalLength', 'PetalWidth', 'Species'] 4 ,header=0) 5 # 1.数据基本信息 6 print(df.head(), # 数据(头部)前几行 7 df.dtypes, # 数据中各列的类型 8 df.describe(), #数据各列基本信息:最大最小,均值等 9 sep='\n') 10 11 # 2.数据可视化 12 # (1)折线图:表明数据变化趋势 13 df.plot() 14 df.plot(x="SepalWidth", y="PetalWidth") 15 #(2)柱状图:对比值 16 df.plot(kind="bar") #竖向 17 df.plot(kind="barh") #横向 18 df.PetalLength.value_counts().plot(kind='barh') 19 df.plot(kind="bar",x="Species",y=["SepalWidth","PetalLength"]) 20 df.plot(kind="bar",stacked=True) #堆叠条形图 21 22 #直方图:展示数据频数/率 23 df.plot(kind="hist") 24 df.plot(kind="hist",bins=15) 25 df.SepalWidth.hist(bin=20) 26 # 箱线图:展示分位数,具体包括上四分位数、下四分位数、中位数以及上下5%的极值 27 df.plot(kind="box") 28 #区域图: 29 df.abs().plot(kind="area") 30 df.plot(kind="area", stacked=False) #不堆积的区域图,设置参数 stacked=False 31 #散点图:数据大致分布规律 32 df.plot(kind="scatter", x="PetalLength", y="Species") 33 df.plot(kind="scatter", x="PetalLength", y="Species", c="SepalWidth") 34 #饼图:占比 35 df.abs().plot.pie(subplots=True,autopct="%.2f") 36 # 容器图:左边坐标表示的是值的分布,右边坐标表示的是数据量大小与颜色的对比 37 df.plot(kind="hexbin", x="PetalLength", y="Species", gridsize=10) 38 plt.show()
4.数据采样
(1)一般来说,整体的样本数据会具有某种概率分布,若数据集很大,则我们不可能使用到所有数据进行建模,否则效率低下,因此我们会从整个样本集中抽取一部分具有近似总体分布特点的子集作为训练集,这可以达到提高效率,信息降维,简化问题的效果
(2)数据采样是根据某种规则从整个数据集中挑选样本数据。
(3)采样方法:
【1】随机采样:从数据集中随机的抽取特定数量的数据,分为有放回和无放回两种
【2】系统采样:一般是无放回抽样,又称等距采样,先将总体数据集按顺序分成n小份,再从每小份抽取第k个数据
【3】分层采样:就是先将数据分成若干个类别,再从每一层内随机抽取一定数量的样本,然后将这些样本组合起来。
(4)类别不平衡问题:分类任务中不同类别的训练样例数目差别很大
【1】欠采样(下采样):减少大数量的类别的数量
【2】过采样(上采样):增加小数量类别的数量
-----数据可使用不仅要使单个特征可以在模型中使用(特征转换),也要满足多个特征可以在模型中体现,主要是特征间的可比较性----
三.特征归一化
1.问题:【1】由于数据中每个特征的含义不同,导致特征之间的单位不一样,导致它们的取值范围不同(比如收入1000-100000的取值,工作年数1-10的取值),很明显,这会导致模型有计算时,尺度大的特征会起决定性作用,而尺度小的特征其作用可能会被忽略,不利于我们观测不同特征对于该问题的影响程度 ;【2】特征取值的差异会到导致代价函数的等高线图成剧烈的椭圆,这会导致使用梯度下降法时迭代的反复,速度会很慢
2.特征归一化是把所有特征都映射一个大致区间,使不同特征间能进行加权和比较,从而消除数据特征之间的量纲影响,使不同指标之间具有可比性。做法是对单个数字特征作映射,包括线性的映射规则以及非线性的规则,但是是为了让不同特征能比较或加权,映射方法主要分为数据的归一化和标准化:
(1)数据归一化:把不同特征映射到相同或相近的确定区间中,一般这个确定区间为【0,1】或【-1,1】,是对整个原区间进行映射,适用于在不涉及距离度量、协方差计算、数据不符合正太分布、无过分离群点、不同特征间取值范围相差巨大的时候
【1】最大最小归一化(0-1归一化):对原始数据等比例缩放到【0,1】区间,y=(x-min)/(max-min) --------依赖于最大最小值稳定
【2】0均值归一化:均值为0---y=(x-均值)/(max-min) ----把数据映射到【-1,1】,数据范围以原点对称
【3】非线性归一化:sigmod归一化、log函数、正切函数...----适用在数据分化比较大的场景,有些数值很大,有些很小。
(2)数据标准化(规范化):对数据进行映射,使之能够尽量保持数据的整体特点,标准化更符合统计假设(数据符合正态分布),一般是使它呈现稳定的标准正太分布,一般用于在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维
【1】Z-score标准化:使经过处理的数据符合标准正态分布(0-1正态分布)---y=(x-均值)/标准差;------适用于最大值和最小值未知的情况、或有超出取值范围的离群数据、或有很多异常值的情况
3.优点:提高梯度下降法的收敛速度,提升模型精度,提高模型特征的可解释性
4.适用模型:适用于svm、线性回归、神经网络、Kmeans,KNN之类的涉及到梯度下降的最优化问题,这些模型关心变量取值;像决策树之类的概率模型则不需要,因为它们不关心变量的值,而是关心变量的分布和变量之间的条件概率
5.补充
(1)正则和标准化:如果你不用正则,那么,标准化并不是必须的,如果你用正则,那么标准化是必须的。因为正则化是用来度量参数的,而参数值的大小是与特征的数值范围相关的。如果不加入正则,进行标准化后,我们得出的参数值的大小可以反应出不同特征对样本的贡献度,方便我们进行特征筛选
(2)注意:分别在训练集和测试集做标准化,因为训练和测试的数据要区别开来
1 # 四.数据处理 2 # raw_df = pd.read_csv('https://storage.googleapis.com/download.tensorflow.org/data/creditcard.csv') 3 file = tf.keras.utils 4 df = pd.read_csv('https://storage.googleapis.com/download.tensorflow.org/data/creditcard.csv') 5 6 # 数据概率分布 7 import seaborn as sns 8 sns.pairplot(train_dataset[["MPG", "Cylinders", "Displacement", "Weight"]], diag_kind="kde") 9 10 #选择数据 11 print(df['A']) # print(df.A)(某一列) 12 print(df.loc[:, ['A', 'B']]) #loc按值索引 13 print(df.iloc[:,3]) #iloc按序索引 14 print(df[df.A > 0]) #条件筛选 15 16 #修改数据:索引之后直接赋值,若没有则新添 17 df['E'] = np.nan #空列 18 19 #删除数据 20 df.pop('Time') #去除某一列 21 df.drop('成交数量',axis=1) #删除某一列 22 23 #去重 24 pd.drop_duplicates(subset = None,keep ='first',inplace=True) 25 #subset=None表示考虑所有列,inplace=True表示直接在原来的DataFrame上删除重复项 26 27 #去除缺失数据 28 df.isna().sum() 29 df = df.dropna() 30 31 #标准化######### 32 from sklearn.preprocessing import StandardScaler 33 scaler = StandardScaler() 34 X_train = scaler.fit_transform(X_train) # fit_transform()先拟合数据,再标准化 35 X_test = scaler.transform(X_test) # transform()数据标准化 36 # ########################################## 37 38 ## 数据整体处理,包括归一化等######### 39 def norm(x): 40 return (x - train_stats['mean']) / train_stats['std'] 41 normed_train_data = norm(train_dataset) 42 normed_test_data = norm(test_dataset) 43 ##################### 44 45 ############# 46 # 数字化: 比如将 sex 列(数据帧(dataframe)中的 object )转换为离散数值 47 df['sex'] = pd.Categorical(df['sex']) 48 df['sex'] = df.sex.cat.codes 49 ################ 50 51 #####分类数据的处理2###################### 52 CATEGORIES = { 53 'sex': ['male', 'female'], 54 'class' : ['First', 'Second', 'Third'], 55 'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], 56 'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'], 57 'alone' : ['y', 'n'] 58 } 59 categorical_columns = [] 60 for feature, vocab in CATEGORIES.items(): 61 cat_col = tf.feature_column.categorical_column_with_vocabulary_list( 62 key=feature, vocabulary_list=vocab) 63 categorical_columns.append(tf.feature_column.indicator_column(cat_col)) 64 categorical_layer = tf.keras.layers.DenseFeatures(categorical_columns) 65 print(categorical_layer(example_batch).numpy()[0]) 66 ##################################### 67 68 ########其他函数###################### 69 #.concat和.merge合并两个df;.append添加df; 70 #tf.cast(x, dtype, name=None)数据类型转换 71 train_features = np.clip(train_features, -5, 5) #限定最大最小值,所有值不会超过 72 # map:接收一个函数,Dataset中的每个元素都会被当作这个函数的输入,并将函数返回值作为新的Dataset, 73 # 比如对所有数据进行平方,也可自己编写函数 74 train_set = train_set.map(tf.square) 75 # batch:在每次梯度下降的时候取batch-size的数据量做平均来获取梯度下降方向 76 train_set = train_set.batch(batch_size=3) # 每次训练的样本数 77 # shuffle:打乱dataset中的元素, 它会维持一个固定大小的buffer,并从该buffer中随机均匀地选择下一个元素 78 train_set = train_set.shuffle(2) # 取出2个组件,对这两个组件乱序(数据量) 79 # repeat:将整个序列重复多次 80 train_set = train_set.repeat(count=3) # 重复3次 81 # Dataset.zip((d1,d2)) #把两个数据集合并 82 ################################ 83 84 ###特征工程######################################## 85 feature_columns = [] 86 # 对于数字特征,先声明其为数值特征 87 for header in ['survived','age','sex']: 88 feature_columns.append(tf.feature_column.numeric_column(header)) 89 # 对于定量特征,可以特征离散化,根据数值范围将其值分成不同的类别,one-hot 90 age = tf.feature_column.numeric_column('age') 91 age_buckets = tf.feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65]) 92 feature_columns.append(age_buckets) 93 # 对于定性特征,把类别编码,先将它们映射到数值, 94 clas = tf.feature_column.categorical_column_with_vocabulary_list( 95 'class', ['First', 'Second', 'Third']) 96 # 当某个特征类别较少时,用one_hot编码 97 class_one_hot = tf.feature_column.indicator_column(clas) 98 feature_columns.append(class_one_hot) 99 # 当某个特征类别很多时,用集成特征(值不在为0或1,而是给定条件的实数) 100 # thal_embedding = tf.feature_column.embedding_column(clas, dimension=8) 101 # feature_columns.append(thal_embedding) 102 # 组合特征,它让模型能够为每种特征组合学习单独的权重 103 crossed_feature = tf.feature_column.crossed_column([age_buckets, clas], hash_bucket_size=1000) 104 crossed_feature = tf.feature_column.indicator_column(crossed_feature) 105 feature_columns.append(crossed_feature) 106 # 新建特征层 107 feature_layer = tf.keras.layers.DenseFeatures(feature_columns) 108 ########################################
四.特征工程
1.简介:我们的目标是对于数据进行建模,而且模型要尽可能高效(简单而且精度高),因此要选择部分特征进行建模(为了简单),选择适当的特征进行建模(为了高精度)。数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。特征工程主要有特征构建、特征提取和特征选择
2.特征构建:从原始数据中人工地挑选或者特征变形构建有意义的特征,是对原有特征的补充
(1)x1...xn---------x1...xn x(n+1)...
(2)特征变形:【1】特征转换(把一个特征转为另一个特征,比如把定量变量转为定性变量);【2】特征组合(把不同的特征变成一个特征,比如两个特征交叉相乘);【3】特征分割(把一个特征化为几个特征,比如把时间分割成年、月、日)
(3)注意:特征构建的特征要尽可能具有现实的可解释性,即要符合问题(头脑风暴,需要对问题、对模型、对数据有深刻认识)
3.特征提取:把特征转换成对工程有用的特征,本质是把原始特征转换成一组具有明显物理意义(Gabor、几何特征[角点、不变量]、纹理[LBP HOG])或者统计意义或核的特征,但是解释性要比原有特征差,偏理论
(1)x1...xn------------f(x1...xn)
(2)PCA(Principal component analysis)主成分分析
【1】思想:本质是一种非监督的降维方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分,即找到一个低维平面,将数据映射上去,并使投影误差最小
【【1】】背景:对于一个数据点来说,它可以用n个属性来表示,这n个属性也被称为n个特征,他们所有取值的集合组成的空间也就是特征空间,可以说一个数据点是特征空间中的一个点(向量)
【【2】】问题1:若特征的数量过大,则会导致维度灾难(随着维数的增加,计算量呈指数倍增长),所以我们要从所有特征中选取部分特征,即降维。
【【3】】问题2:这些特征之间可能有关联(比如生日和年龄这两个特征),显然这些特征包含有重复的信息,这也和我们建模时假设的特征间相互独立矛盾,所以我们最好要删除重复信息,用一组线性无关的特征来表示数据点,但是也要保证存留的信息尽可能多。
【【4】】补充背景:1)向量内积ab=|a||b|cos(θ)为a到b的投影长度乘以b的模,若b的模为1,即b为单位向量,则向量内积为a向b所在直线投影的矢量长度;2)任何一个向量都是在坐标系中存在的,它的表示本质上是终点的坐标减去起始点的坐标,若起始点坐标为原点0,则任何一个n维向量可以用n维空间的一组起始于原点的正交基向量来表示,也就是在起始原点下,任何一个向量是一组正交基的线性表示,则若正交基的选择不同,则向量的表示也不同;3)矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去,则我们可以用一个正交的投影矩阵把样本从n维空间投影到k维空间。4)任意的 N×N 的实对称矩阵都有 N 个线性无关的特征向量,并且这些特征向量都可以正交单位化而得到一组正交且模为 1 的向量。故实对称矩阵 A 可被分解成A=Q*λ*Q-1,其中Q为正交矩阵,其中每一列为A的特征向量,λ为实对角矩阵,其对角线上的元素为对应的特征值,由大到小排列,Q第i列的特征向量对应对角阵的第i个特征值。
【【5】】解决2:样本的协方差矩阵反映特征间总体误差的方差,其中每个值表示特征之间的相关性,越大越相关,很明显,协方差矩阵为对称矩阵,我们的目标是使不同特征间的相关性越低越好,最好为0,即对称矩阵变为一个对角矩阵(除对角线外,其余位置为0),已知一个实对称阵相似于一个对角阵,即该对称阵可以通过某个矩阵的变换变为对角阵,这个矩阵也就是我们的投影矩阵,投影矩阵实质上是对原有的正交基进行变换,投影矩阵乘以数据集就是对数据点进行转换但是最大化保留信息且又尽量区分不同的数据点,因为投影矩阵是正交基组成,也就是特征间互不相关,此时整个数据集的点到该投影矩阵形成的超平面的距离尽可能小,即保证了信息的损失尽可能小,投影后数据点之间的距离尽可能大,此时投影后总体数据的方差尽可能大。
【【6】】解决1:对应选择最大k个特征值对应的特征向量组成的投影矩阵从而实现降维。
【【7】】补充: 特征向量和特征值的定义Ax=λx,x为一个A的特征向量,A为一个矩阵,λ为一个实值,一个向量x在矩阵的作用下,保持方向不变,进行比例为λ的伸缩,向量x可以用一组正交基来表示,则可以有某个矩阵可以在该正交基组成的空间中找到某些向量进行转换使得这些向量只发生长度上的改变而非方向上的改变,又可以理解为某个有一组正交基表示的向量可以在某个矩阵的作用下由另一组正交基进行表示(即矩阵的作用是对正交基进行伸缩和旋转)。特征值表示伸缩的大小,特特征向量表示伸缩的方向,则在数据挖掘中,通过特征值分解可以得到特征值与特征向量,特征值表示的是对应特征向量方向上包含的信息量,而特征向量表示这个特征是什么。对于实对称矩阵,我们进行特征值分解得到特征值和特征向量,选取其中最大的k个组合成投影矩阵(n*k),则保证了特征包含信息量尽可能多和降维两个目的,而选取的特征向量之间本身表示的不相关性。包含的信息量多又代表方差大。特征向量可以理解为坐标转换中新坐标轴的方向,特征值表示在对应特征向量上的方差,特征值越大,方差越大,信息量也就越大。
【【8】】http://blog.codinglabs.org/articles/pca-tutorial.html
【2】降的维度数量选择:若原始点与投影点之间的距离之和 比上 数据中总的方差 <= 0.01 则表示降维后的数据能保留99%的信息(方差)
【3】与线性回归的不同,pca计算的是点到超平面的距离,而线性模型则是真实值到预测值之间的距离
【4】优点:使得数据集更易使用;降低算法的计算开销;去除噪声;使得结果容易理解;无参数限制,仅仅需要以方差衡量信息量,不受数据集以外的因素影响
【5】缺点:变换的矩阵必须是方阵; 在非高斯分布情况下,PCA方法得出的主元可能并不是最优的,解释性弱
【6】应用:降维、去燥、提取特征、数据处理
(3)LDA(Linear Discriminant Analysis)线性判别分析
【1】思想:本质是一种监督的分类方法。将数据投影到一条直线上,使得同类样例的投影尽可能接近,异类样例的投影点尽可能原理;在对新的样本进行分类时,将其投影到同样的这条直线上,再根据投影点的位置来确定新样本的类别。
【2】区别:PCA和LDA都是讲数据投影到新的相互正交的坐标轴上,两者在降维时均使用了矩阵特征分解的思想;两者都假设数据符合高斯分布,但pca主要用于降维,选择样本点投影具有最大方差的方向;lda主要用于分类,选择分类性能最好的投影方向
【3】优点:更能反映样本间的差异,可以使用类别的先验知识
【4】缺点:它的降维到的维度最大值为n-1,LDA在样本分类信息依赖方差而不是均值时,降维效果不好,LDA可能过度拟合数据,LDA 对数据的分布做出了很强的假设,比如每个类别数据都是高斯分布、各个类的协方差相等
(4)ICA独立成分分析:ICA算法本质寻找一个线性变换z = Wx,使得z的各个特征分量之间的独立性最大
5.特征选择:从给定特征集中选择部分作为最终的特征集进行建模,要求尽量少的无关特征,尽量多的相关特征,尽可能合适的特征数量
(1)x1...xn---------x1'...xk'
(2)描述:特征是用来建模的,我们不知道那些好用,那些不好用,唯一能做的是选择一个特征子集进行建模,然后使用某个标准来评估,不断重复该过程,直到找到最好的子集。特征的选择关注两个方面:如何选择子集以及如何评价子集,而对于某个特征的关注在于该特征的离散型和该特征的重要性
(3)过滤式(filter):关注的是单个特征与预测值之间的关系,先对数据集进行特征选择,其过程与后续学习器无关,即设计一些统计量来过滤特征,并不考虑后续学习器问题
【1】思想:通过某个标准取衡量所有特征的重要性(特征与预测变量之间的相关性),从而对特征进行排名,然后设定条件选择排名靠前的特征
【2】评价标准:分类问题(卡方检验,f_classif, mutual_info_classif,互信息)回归问题(皮尔森相关系数,f_regression, mutual_info_regression,最大信息系数),相似性度量,方差...
【3】优点:计算时间上比较高效,而且对过拟合问题有较高的鲁棒性
【4】缺点:倾向于选择冗余特征,即没有考虑到特征之间的相关性
(4)包装法(Wrapper):关注的是特征子集对模型的影响,直接把最终将要使用的学习器的性能作为特征子集的评价原则。其目的就是为给定学习器选择最有利于其性能、量身定做的特征子集。
【1】思想:通过某个标准来选择特征子集,利用在模型上的表现,使用交叉验证,选择表现最好的子集,迭代地选择特征子集再进行评价
【2】选择子集:逐步回归、向前选择(贪心法扩充子集)和向后选择(贪心法缩小子集)、完全搜索、启发式搜索、随机搜索
【3】优点:直接针对特定学习器进行优化,考虑到特征之间的关联性,因此通常包裹式特征选择比过滤式特征选择能训练得到一个更好性能的学习器,
【4】缺点:当观测数据较少时容易过拟合,由于特征选择过程需要多次训练学习器,故计算开销要比过滤式特征选择要大得多
(5)集成方法(Embedded):利用学习器自动选择特征。将特征选择与学习器训练过程融为一体,两者在同一个优化过程中完成的
【1】思想:结合特征选择和训练器,自动得出比较好的子集
【2】方法:正则化(L_1, L_2
范数)、决策树、深度学习、回归模型,SVM,随机森林
【3】优点:结合前两者优点
【4】缺点:必须事先知道什么是好的选择
(6)验证:在验证数据集上验证选出来的特征子集的有效性
五.划分数据集
1.划分数据集的步骤:
(1)设定训练集和测试集。我们的目的是从已有的数据中学习某种规律,用模型来表现这种规律,进而使用模型对未知数据进行预测。则我们至少需要两个数据集,我们收集已有的数据作为训练集来训练模型,用户提供的数据作为测试集来验证模型的优劣
(2)划分测试集为开发集和测试集。由于我们不知道数据的真实规律,所以我们也就不知道哪种模型能最有效地学习数据信息,于是我们一般而言选择几种模型框架来对数据进行学习,通过比较这几种模型的效果,我们选择其中表现最好的模型作为最终的模型假设。此时,因为我们的测试集被用作各个模型的评估,而我们又要求模型在未知数据上进行预测,所以我们把测试集划分为开发集和测试集。其中开发集(development set)又被称为保留交叉验证集(hold-out cross validation set),是用来评估各个模型的效果并进行比较选择,测试集是用来作为未知数据,来评估最终模型的性能
(3)划分训练集为训练集和训练/开发集。一般而言,我们的训练集是从各处收集来的,而开发集和测试集是用户真实上传的数据,两者有时候不是同一分布,这就会导致模型在训练集上表现良好,但是在开发集上表现'差',而且这种‘差’不是由偏差和方差引起的,而是由两个数据集不为同一分布引起的,这就是分布不一致导致的数据不匹配问题(比如:模型训练时用的是高清图片,用户上传的是模糊图片,这可能导致模型的测试误差大,而且这种大是因为训练集和开发集数据分布不一致)。我们为了能够识别这种错误,把训练集分为训练集和训练/开发集,明显两个数据集都是同分布的。于是,在训练集上表现好的模型,若它在训练-测试集上表现好,在开发集上表现不好,则可判定这种不好是由数据不匹配引起的,而不是方差。也就是说,我们不必使用所有的训练数据,可以预留一部分备用于误差分析
2.划分数据集的要求:
(1)划分比例:一般而言,训练数据越多,模型最终的效果越好,若数据量小,我们划分数据集为训练集+开发集+测试集,比例一般为6:2:2;若数据量大,则没必要测试集和开发集占这么大的比例,因为两者的目的是为了评估测试模型,只要达到一定的量就可以了,因此我们一般把数据集划分为训练集+训练/开发集+开发集+测试集的比例为98%、1%、1%、1%,而这1%的数据量大概能达到10000条样本,够用就行
(2)注意1:开发集和测试集是用来对模型进行评价的,尽量要能反映了模型在真实应用下的性能,所以我们的数据也应尽量是未来实际会用到的数据,以这些数据为目标训练得来的模型才最符合我们的要求,而且这两个数据集必须满足同一分布,表明所建立的模型的目的一致。若不为同一分布,也就代表模型的预期目的不同,在开发集上表现好的模型很大概率不会在测试集上表现好,此时模型毫无意义
(3)注意2:训练集和训练-开发集必须满足同一分布,设定训练-开发集的目的是为了分析某些误差是不是由数据不匹配引起的(分布不一致)
【1】数据不平衡问题:由于我们训练的数据来自各方,而测试数据来自用户本身,两者一般而言都会有分布不一致的问题。我们不能完全避免这种数据不平衡,但是我们可以采取措施来削弱数据不平衡带来的影响
【【1】】方法一:我们可以把开发集和训练集组合起来打乱,再重新划分数据集(随机分配),这种方法虽然统一了分布,但是测试集和真实数据有了差距,一般不用
【【2】】方法二:从测试集或开发集中取出一部分放入训练集,相当于把训练集的分布往真实集的分布靠近,有效
【【3】】方法三:我们可以人工地进行误差分析,来了解训练集和开发集的具体差异,而且为了避免对测试集过拟合,我们不应该关注测试集,通过弄明白训练和开发集有不同,我们可以收集更多想开发集的训练数据,或者通过人工合成训练数据或其他方法使得训练集更像开发集,比如人工合成训练数据 。注意:人工合成方法,若在所有可能的空间只选很小一部分去模拟数据,可能过拟合
3.各个数据集的作用:首先划分数据集并设置相应的评估指标,若你有很多思路,则用训练集训练不同的模型框架,然后用开发集来评估不同的思路,选择表现最好的模型,然后进行模型的偏差-方差分析和误差分析,决定下一步怎么对模型进行改进,其间可以使用训练/开发集来判断是否有数据不平衡问题,最后得到一个满意的最终模型,用测试集来评估优劣,把最终的模型在整个数据集上重新训练,得到最终的系统
(1)训练集:用来训练模型。训练集应该尽量大,还应均匀,比如类别要均衡。我们会先快速选择一些模型框架(模型超参数已确定),此时模型参数并没有确定,通过训练集计算梯度更新参数,从而迭代更新得到一些训练完的模型
(2)训练/开发集:训练集中预留出的子集,用于误差分析时,判别数据不平衡问题。和训练集同分布,足够大就行
(3)开发集:用于评估所有已经学习完成的模型(此时每种模型都会有验证误差),选择验证误差最小的算法模型作为最终学得的模型。而且在模型确定选择后,我们可以调整模型的超参数,再通过验证误差来选择最好的超参数,这个过程其实是对开发集拟合,若开发集足够大,则不会过拟合得太厉害,使能够以高置信评估系统的整体性能。与测试集应同分布,以至于我们的学习目标不会偏离实际。
(4)测试集:用来评估最终的模型(测试误差常被用来作为泛化误差的近似),检验我们的模型是否有泛化能力,对模型做无偏估计。测试集中的数据必须是模型从未见过的、未来真正要使用到的数据,而且测试集不应该参与模型的训练拟合,不参与模型的调参,不参与模型的选择,只对最终的系统进行测试。若开发集很大,则不会过拟合得太厉害,此时测试集没有也可以,但有了测试集更安心。
4.多次划分数据集,交叉验证评估不同模型:当数据集较小时,由于不同模型对于训练集的偏向不同(得到的所谓的好的模型A可能只在我们划分的特定训练集上表现良好,而未必在整个数据集上表现好,差的模型也不一定差),所以我们提出:对一个数据集多次划分出不同的训练集和验证集,在这些训练集和验证集上多次对一个模型进行训练评估,可以得到一个模型的多个评估结果,取平均作为该模型最终的较为公正的评估结果,由此得到一些模型较为公正的结果从而进行比较和选择。由于多次划分数据集使得不同训练集和验证集的数据互相交叉(这次训练时在训练集中的数据可能在下次训练时出现在验证集中),所以被称作‘交叉验证’,主要数据集划分方法如下:
(1)留出法(hold-out):把数据集划分为两个互斥集合,一个用作训练,一个用作测试
【1】划分要尽可能保持数据分布的一致性,分层采样(stratified sampling)(保持类别比例的采样)
【2】采用若干次随机划分,重复试验,取平均值作为评估结果
【3】一般将2/3~4/5的样本用于训练,其余用于测试
(2)k折交叉验证法(cross validation):将数据集划分为k个大小相似的互斥集合
【1】每个子集都尽可能保持数据分布的一致性,即分层采样得到
【2】将k-1个子集作训练集,剩下那个作测试集,即进行k次训练和测试
【3】k次试验的k个结果取平均
【4】留一法(leave-out-out)(LOO):k=样本数,训练集较大时留一法计算复杂度高
(3)自助法(bootstrapping):以自助采样
【1】自助采样:每次随机从数据集D中挑选一个样本,将其拷贝放入采样数据集D‘,然后将其放回到D中,使它下次仍有可能被采到,
【2】重复自助采样m次,得到一个包含m个样本的数据集D’作为训练集
【3】约1/e=0.368的样本为出现在D’中
【4】适用于数据集较小,难以有效划分训练/测试集时
六.数据可视化
1.可视化只是让我们对数据和模型有直观的认识,其目的在于观测数据和模型,不仅仅是作图,还包括一些数据信息(比如最大最小值、均值等)
2.在建立和选择模型前进行数据可视化:在建模前进行训练数据可视化(因为训练数据量大)可以让我们直观地观察数据的规律、观测到特征之间的关系、观测到特征对问题的影响、观测到是否存在一些问题...从而建立或选择适合的模型,有利于提高效率,避免一些明显错误
3.建模后可视化模型和数据:能够使我们直观地观察所建模型与真实数据的差距,从而验证我们所建模型的正确性,或者说查找模型对于数据是否有明显错误
4.可视化方法:
(1)表格:体现数据的一些基本信息,比如均值、最大最小值等
(1)条形图:展示某些离散的项目的集合的数量变化
(2)线图:展示某种事物的趋势
(3)散点图:展示特征项之间关系
注:以下流程图并非按步骤顺序来,而且还未更新
1 import numpy as np # 提供数组型的数据结构,科学计算库 2 import pandas as pd # 提供了一种高效的DateFrame结构,数据处理库 3 import matplotlib.pyplot as plt # 数据可视化 4 import tensorflow as tf # 整合的机器学习库 5 6 import tensorflow.data as td # tensorflow 提供的处理数据的库 7 from sklearn.model_selection import train_test_split 8 9 # 选择GPU 10 import os 11 os.environ["CUDA_VISIBLE_DEVICES"] = "2" 12 13 # 1.获得数据 14 DATAS_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv" 15 # 通过url下载csv文件并保存 16 datas_path = tf.keras.utils.get_file(r"E:\python_work\machine_learning\datas\datas.csv", DATAS_URL) 17 # 若csv文件无列名,则需手动添加 tf.data.experimental.make_csv_dataset() 18 19 # 2.读取数据 20 df = pd.read_csv(datas_path) # 通过pandas读取csv文件 21 print(df.head()) # 查看表头部 22 print(df.dtypes) # 查看数据类型 23 24 # 3.数据预处理(缺失值--填充,重复样本--删除,错误数据--查找), 25 # 4.数据集采样--使用tf.data.experimental.sample_from_datasets 26 # 5.数字化 27 # 比如将 sex 列(数据帧(dataframe)中的 object )转换为离散数值 28 df['sex'] = pd.Categorical(df['sex']) 29 df['sex'] = df.sex.cat.codes 30 31 # 6.可视化 32 # 7.把DataFrame划分数据集 33 train, test = train_test_split(df, test_size=0.2) # 以8:2的比例划分数据集 34 train, val = train_test_split(train, test_size=0.2) 35 36 # 8.把dataframe变成data类,便于模型的使用 37 # 以元组形式把需要的特征作为张量来创建data 38 # train_set = td.Dataset.from_tensor_slices((train.sex, train.n_siblings_spouses, train.alone)) 39 features = pd.concat([train.iloc[:,:3],train['class']],axis=1) 40 labels = train.alone 41 train_set = td.Dataset.from_tensor_slices((dict(features), labels)) 42 43 # 9.特征工程 44 feature_columns = [] 45 # 对于数字特征,先声明其为数值特征 46 for header in ['survived','age','sex']: 47 feature_columns.append(tf.feature_column.numeric_column(header)) 48 49 # 对于定量特征,可以特征离散化,根据数值范围将其值分成不同的类别,one-hot 50 age = tf.feature_column.numeric_column('age') 51 age_buckets = tf.feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65]) 52 feature_columns.append(age_buckets) 53 54 # 对于定性特征,把类别编码,先将它们映射到数值, 55 clas = tf.feature_column.categorical_column_with_vocabulary_list( 56 'class', ['First', 'Second', 'Third']) 57 # 当某个特征类别较少时,用one_hot编码 58 class_one_hot = tf.feature_column.indicator_column(clas) 59 feature_columns.append(class_one_hot) 60 # 当某个特征类别很多时,用集成特征(值不在为0或1,而是给定条件的实数) 61 # thal_embedding = tf.feature_column.embedding_column(clas, dimension=8) 62 # feature_columns.append(thal_embedding) 63 64 # 组合特征,它让模型能够为每种特征组合学习单独的权重 65 crossed_feature = tf.feature_column.crossed_column([age_buckets, clas], hash_bucket_size=1000) 66 crossed_feature = tf.feature_column.indicator_column(crossed_feature) 67 feature_columns.append(crossed_feature) 68 # 新建特征层 69 feature_layer = tf.keras.layers.DenseFeatures(feature_columns) 70 --------------------------------------------------------- 71 survived sex age ... deck embark_town alone 72 0 0 male 22.0 ... unknown Southampton n 73 1 1 female 38.0 ... C Cherbourg n 74 2 1 female 26.0 ... unknown Southampton y 75 3 1 female 35.0 ... C Southampton n 76 4 0 male 28.0 ... unknown Queenstown y 77 78 [5 rows x 10 columns] 79 survived int64 80 sex object 81 age float64 82 n_siblings_spouses int64 83 parch int64 84 fare float64 85 class object 86 deck object 87 embark_town object 88 alone object 89 dtype: object
1 # 补充.data类:处理大量数据,从不同数据格式读取数据以及执行复杂的转换 2 # tf.data.Dataset表示元素的序列,其中,每个元件由一个或多个部件的抽象 3 # 读取数据,自定义函数处理数据,快 4 # (1)直接使用张量(numpy数组,列表,张量对象)(输入:张量的嵌套结构,每个张量在第0维)创建数据集(输出一个Dataset对象) 5 d2 = td.Dataset.from_tensor_slices([[8, 3],[2,4]]) 6 # (2)迭代处理 7 print(train_set) 8 print(type(train_set)) 9 for elem in train_set.take(2): # 取出前2个样本 10 print(elem) # 每个元素都是作为一个张量 11 print(elem[0]) 12 print(elem[0].items()) # 字典显示,还有元组显示,numpy显示 13 print(elem[0].get('class').numpy()) 14 it = next(iter(train_set.take(1))) # 生成器 15 # (3)数据处理 16 # map:接收一个函数,Dataset中的每个元素都会被当作这个函数的输入,并将函数返回值作为新的Dataset, 17 # 比如对所有数据进行平方,也可自己编写函数 18 # train_set = train_set.map(tf.square) 19 # batch:在每次梯度下降的时候取batch-size的数据量做平均来获取梯度下降方向 20 train_set = train_set.batch(batch_size=3) # 每次训练的样本数 21 # shuffle:打乱dataset中的元素, 它会维持一个固定大小的buffer,并从该buffer中随机均匀地选择下一个元素 22 train_set = train_set.shuffle(2) # 取出2个组件,对这两个组件乱序(数据量) 23 # repeat:将整个序列重复多次 24 train_set = train_set.repeat(count=3) # 重复3次 25 # 26 # # Dataset.zip((d1,d2)) #把两个数据集合并 27 ----------------------------------------------------------- 28 <DatasetV1Adapter shapes: ({survived: (), sex: (), age: (), class: ()}, ()), types: ({survived: tf.int32, sex: tf.int32, age: tf.float32, class: tf.string}, tf.string)> 29 <class 'tensorflow.python.data.ops.dataset_ops.DatasetV1Adapter'> 30 ({'survived': <tf.Tensor: id=19, shape=(), dtype=int32, numpy=0>, 'sex': <tf.Tensor: id=18, shape=(), dtype=int32, numpy=1>, 'age': <tf.Tensor: id=16, shape=(), dtype=float32, numpy=22.0>, 'class': <tf.Tensor: id=17, shape=(), dtype=string, numpy=b'Third'>}, <tf.Tensor: id=20, shape=(), dtype=string, numpy=b'y'>) 31 {'survived': <tf.Tensor: id=19, shape=(), dtype=int32, numpy=0>, 'sex': <tf.Tensor: id=18, shape=(), dtype=int32, numpy=1>, 'age': <tf.Tensor: id=16, shape=(), dtype=float32, numpy=22.0>, 'class': <tf.Tensor: id=17, shape=(), dtype=string, numpy=b'Third'>} 32 dict_items([('survived', <tf.Tensor: id=19, shape=(), dtype=int32, numpy=0>), ('sex', <tf.Tensor: id=18, shape=(), dtype=int32, numpy=1>), ('age', <tf.Tensor: id=16, shape=(), dtype=float32, numpy=22.0>), ('class', <tf.Tensor: id=17, shape=(), dtype=string, numpy=b'Third'>)]) 33 b'Third' 34 ({'survived': <tf.Tensor: id=24, shape=(), dtype=int32, numpy=0>, 'sex': <tf.Tensor: id=23, shape=(), dtype=int32, numpy=1>, 'age': <tf.Tensor: id=21, shape=(), dtype=float32, numpy=28.0>, 'class': <tf.Tensor: id=22, shape=(), dtype=string, numpy=b'Third'>}, <tf.Tensor: id=25, shape=(), dtype=string, numpy=b'y'>) 35 {'survived': <tf.Tensor: id=24, shape=(), dtype=int32, numpy=0>, 'sex': <tf.Tensor: id=23, shape=(), dtype=int32, numpy=1>, 'age': <tf.Tensor: id=21, shape=(), dtype=float32, numpy=28.0>, 'class': <tf.Tensor: id=22, shape=(), dtype=string, numpy=b'Third'>} 36 dict_items([('survived', <tf.Tensor: id=24, shape=(), dtype=int32, numpy=0>), ('sex', <tf.Tensor: id=23, shape=(), dtype=int32, numpy=1>), ('age', <tf.Tensor: id=21, shape=(), dtype=float32, numpy=28.0>), ('class', <tf.Tensor: id=22, shape=(), dtype=string, numpy=b'Third'>)]) 37 b'Third'
七.补充
1.不在模型中用到的数据并不代表它不重要,每个数据都很重要,不能删除,要进行备份保存,
2.涉及到特征,这就要和模型相结合
3.数据可视化很重要