机器学习——Chapter 2. 项目实战(获取数据、数据预处理、数据探索、确定测试集)

学习机器学习,最终还是要投身于真实的项目实例,一切基础知识的学习,都是为了最终投身于实践,为现实中真实的项目服务。现对机器学习案例步骤及实现方法进行简单介绍如下:

A、【一般项目流程】:
(1)观察数据大背景
(2)得到数据
(3)单变量分析,发现和可视化数据,以获得洞察力,对数据进行可视化
(4)数据分类及过滤,为机器学习算法准备数据
(5)选择合适的模型进行数据拟合,实现训练
(6)模型评估并调整模型
(7)解决方案
(8)启动、监视和维护您的系统

B、【数据来源】:
在我们进行案例实践之前,我们需要提前获取于案例相关的数据。在进行机器学习中,最好是利用真实世界的数据进行实验,而不是人工数据集,幸运的是,有成千上万的开放数据集可供选择,这些数据集分布在各个领域,你可以从以下几个地方获取数据。
· 流行的开放公共数据存储库
(1)UC Irvine Machine Learning Repository
(2)Kaggle datasets
(3)Amazon’s AWS datasets
· 元数据门户(公开的数据列)
(1)Data Portals
(2)OpenDataMonitor
(3)Quandl
· 其他流行的开放数据存储库
(1)Wikipedia’s list of Machine Learning datasets
(2)Quora.com
(3)The datasets subreddit
当然除此之外,你也可以使用python自带的sklearn包(机器学习包)中自带的数据集进行模型训练。

C、数据预处理——数据清洗
由于在实际案例数据中,大部分机器学习算法无法处理存在缺失值的数据特性,因此我们需要对缺失值进行处理。
1)数值型数据预处理
【处理缺失值的方法】:
Option1:去掉相应的缺失值区域;
Option2:去掉整个属性;
Option3:将值设为某个值(0,中位数,平均数等)。
Option4:Scikit-Learn类有提供一个SimpleImputer类来处理缺失值
具体应用:

housing.dropna(subset=["total_bedrooms"]) # option 1  
housing.drop("total_bedrooms", axis=1) # option 2  
housing["total_bedrooms"].median() # option 3  
housing["total_bedrooms"].fillna(median, inplace=True) # option 3

*注意:*若使用option3方法进行缺失值处理,则需要提前进行计算中位数(平均数),并利用该数值进行填充缺失值。
option4详解:
【使用步骤】:
(1)创建一个SimpleImputer实例,指定要用该属性的中位数替换每个属性的缺失值;

from sklearn.impute import SimpleImputer 
imputer = SimpleImputer(strategy="median")

(2)利用fit()函数将imputer实例装入训练数据,进行数据拟合

imputer.fit(housing_num)

(3)将训练过的数据转换为训练集(转化为numpy的数据集),用学习过的中值替换缺失的值

X = imputer.transform(housing_num)   #得到一个numpy数组

(4)将numpy数组转化为dataframe数据框

housing_tr = pd.DataFrame(X, columns=housing_num.columns, 
index=housing_num.index) 

2)处理文本和类别属性(处理文本类型属性)
该值不能是任意的文本,其能取得值是有限的,每个值代表一个类别,表示分类属性,由于机器学习算法更习惯于与数值型数据打交道,因此我们需将文本型数据转化为数值型数据,可以使用Scikit-Learn的 OrdinalEncoder类。

from sklearn.preprocessing import OrdinalEncoder 
ordinal_encoder = OrdinalEncoder()  
housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)
housing_cat_encoded[:10]
from sklearn.preprocessing import OneHotEncoder 
cat_encoder = OneHotEncoder() 
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)
housing_cat_1hot

==one-hot encoding ==:热编码技术(用于进行文本数值化处理)
通过调用ordinal_encoder.categories_实例变量获取每个属性的类别列表

ordinal_encoder.categories_ 
#[array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'], dtype=object)]

【原理】:
为每个类别创建一个二进制属性:当类别为’<1H OCEAN’时,一个属性为1(否则为0),当类别为’INLAND’时,另一个属性为1(否则为0),以此类推。
新属性有时被称为虚拟属性。
Scikit-Learn提供了一个OneHotEncoder类来将分类值转换为一个热向量(用于进行文本数值进行转化)。
【解析】:One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。然后,每个整数值被表示为二进制向量,除了整数的索引之外,它都是零值,被标记为1。
例如:

性别特征:[“男”,“女”] (这里只有两个特征,所以 N=2): 男 => 10 女 => 01

祖国特征:[“中国”,"美国,“法国”](N=3): 中国 => 100 美国 => 010 法国 => 001

D、数据探索——认识数据
数据探索是数据分析的一个重要阶段,在具有较好的样本后,对样本数据进行解释性的分析工作,是数据挖掘较为前期的部分,它更侧重于定义数据的本质,描述数据的形态特征并解释数据的相关性,通过数据探索的结果,我们可以更好的开展后续的数据挖掘和建模工作。
通俗而言,数据探索需要弄清楚样本数据长什么样?有什么特性?数据之间有没有关系?样本数据是否能满足建模需求?
在数据探索阶段,我们可以对数据进行分析统计描述,进行单变量分析,描述变量间相关性描述。
(1)数据进行统计描述(描述数据特性)
法一、describe()函数 对数据进行分析统计(展示平均值、最大值、分位数、中位数等)
法二、绘制直方图 可对每个属性进行直方图统计,也可对整个数据集绘制直方图(调用matplotlib包,进行图形的绘制)
(2)利用可视化的方式进行单变量分析
例如:绘制地价热力图

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4, 
s=housing["population"]/100, label="population", figsize=(10,7), 
c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True, 
)
plt.legend()

(3)相关性分析
法一:利用corr()函数进行变量之间的相关性分析==>适用于数据集较小时
相关性系数区间为-1到1;当接近于1 时,表示较强正相关,当接近于-1时,表示较强的负相关;若系数接近于0,表示无线性相关
法二:调用pandas包中的scatter_matrix()方法,绘制每个数值属性与其他数值属性的对比图。

E、确定测试集
测试集的数据具有随机性,因此我们须在实例数据中挑选一些实例,一般为数据集的20%,然后将其放再一边。
可使用自定义函数split_train_test()函数来划分数据集

def split_train_test(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    test_indices = shuffled_indices[:test_set_size]
    train_indices = shuffled_indices[test_set_size:]
    return data.iloc[train_indices], data.iloc[test_indices]

【data:表示数据集,test_ratio:表示占数据集比例】
但由于数据是随机的,每次调用产生的数据都不完全的相同,随着演变次数的增加,会导致整个数据集都展示出来,但这并不是我们想要的。
【解决办法】:
法一、第一次运行后保存测试集,然后再后续运行中加载它
法二、再调用np.random.permutation()之前,设置随机数生成器的种子,以便它总是生成相同的打乱索引
但注意:以上两种方式都会再更新数据集时中断。
因此即使在更新数据集之后,也要有一个稳定的train/test分离,一个常见的解决方案
使用每个实例的标识符来决定它是否应该进入测试集(假设每个实例都有一个唯一且不可变的标识符),确保测试集在多次运行中保持一致。
#一般,若没有标识符列,则选用行索引,若使用行索引则需保证新数据必须加载元数据的末尾,且没有删除的行,若无法保证,则选用绝对稳定变量作为识别符。
#Scikit-Learn函数提供了一些函数,以各种方式将数据集拆分为多个子集。
例如:train_test_split()函数
优势:
(1)提供一个random_state参数允许您设置随机生成器种子。
(2)可以传递一个相同行数的多个数据集,它会自动在相同的索引上进行拆分。

你可能感兴趣的:(Python,机器学习,python)