机器学习实战读书笔记
第一章 机器学习小技巧
疫情留在宿舍无聊,看书时突然发现自己以前学的知识点在需要回顾时,都得把书再扫一遍,或者去各个文件夹里面找资料。所以,将它存放在此,其中应该会有很多错误,希望大佬们路过的时候帮忙纠正一下,谢谢!
前言
此章节用于记录完整项目中的一些小技巧,便于之后快速复习回顾
一、数据集准备
1.1 数据基本操作
numpy,pandas,matplotlib简单操作(详细细节见:),此部分只随书写一点常用的。
1.1.1 numpy随机种子、随机数
1.1.1.1 使用np.random.permutation(num)生成随机数
np.random.permutation(10)
#array([0, 1, 8, 5, 3, 4, 7, 9, 6, 2])
np.random.permutation(10) #生成随机数,与之前的随机数不同
#array([9, 2, 0, 6, 8, 5, 3, 7, 1, 4])
1.1.1.2 使用np.random.seed(num)随机种子,搭配随机数,形成固定的随机数
np.random.seed(42) #其中42可换成其它数字,不知道有什么区别
np.random.permutation(10)
#array([8, 1, 5, 0, 7, 2, 9, 4, 3, 6])
np.random.seed(42)
np.random.permutation(10)
#array([8, 1, 5, 0, 7, 2, 9, 4, 3, 6])
1.1.1.3 运用背景:训练集/测试集的划分
此处以sklearn中的train_test_split()为例
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]
1.1.2 pandas数据操作
1.1.2.1 读取数据:excel/csv/sql
import pandas as pd
data=pd.read_excel('dir/fileName.xlsx') #读取excel数据
data=pd.read_csv('dir/fileName.csv') #读取csv数据
data=pd.read_sql(sql,con) #读取sql数据
1.1.2.2 查看数据:DataFrame
df.head() #查看前5行数据
df.info() #产看总行数/每个属性非空数/每个属性数据类型
df[column].value_counts() #对分类问题的数据进行统计
df.describe() #统计总数/均值/标准差/最小值/最大值
1.1.2.3 数据转化为标签:pd.cut()
将原有属性中的范围值归类,形成另外的属性:
此处假设已有df[‘num’]的数据从0到无穷大分布,需要将此数据分段统计,比如:0-1.5,1.5-3,3-4.5,4.5-6,6-np.inf分为5类。其代码如下:
df['label']=pd.cut(df['num'],bins=[0,1.5,3,4.5,6,np.inf],labels=[1,2,3,4,5])
#np.inf为无穷大
1.1.2.4 数据相关性寻找
假设已有数据df,其中一个column是label为’values’,需要查看’values’与其他属性的相关性。其代码如下:
corr_matrix=df.corr()
corr_matrix['values'].sort_values(ascending=False)
#输出为一个相关性排序
1.1.2.5 数据填充
df.dropna(subset=['values']) #删除空值
df.drop('values',axis=1) #删除属性
median=df['values'].median() #中值填充
df['values'].fillna(median,inplace=True)
1.1.3 matplotlib数据可视化
此处可视化内容,见*https://download.csdn.net/download/weixin_52028615/84650336*(自己手敲的Python中pandas/numpy/matplotlib基础)
二、sklearn数据准备
2.1 sklearn的一致性
sklearn的设计原则很多,包括:一致性、检查、防止类扩散、构成、合理的默认值。此处仅介绍一致性,用于之后学习的基础,其他性质内化于平常python学习的基础中。
2.1.1 sklearn一致性:估算器
能够根据数据集对某些参数进行估算的任意对象都可以称为估算器(例如:imputer)。估算由fit()方法执行,需要一个(X)或者两个(X,y)数据集作为参数,其他任何参数都为超参(必须设置为实例变量)。
2.1.2 sklearn一致性:转换器
有些估算器也可以转换数据集,这些称为转换器,由transform()函数进行转换,返回的值为转换后的数据集。所有的转换器都可以使用一个简单的方法,即fit_transform()。
fit_transform()相当于先调用fit()然后调用transform(),但是fit_transform()有时是被优化过的,运行速度会快一些。
也就是说:转换器至少含有fit(),transform()和fit_transform()三个函数。
2.1.3 sklearn一致性:预测器
有些估算器能够基于给定的数据集进行预测,被成为预测器。
预测器的predict()方法接受一个新例的数据集,返回一个相应的预测数据集。
预测器的score()方法可以用来衡量测试集的预测质量。
也就是说:预测器至少含有fit(),predict(),score()。
2.1.4 sklearn一致性:小结
- 转换器、预测器都包含估算器中的函数:fit()
2.2 数据准备
2.2.1 数据清理
sklearn通过sklearn.impute处理
from sklearn.impute import SimpleImputer
imputer=SimpleImputer(strategy='median')
df1=df.drop('values',axis=1)
imputer.fit(df)
X=imputer.transform(df) #中值填充
imputer.statistic_
#显示填充的数据 相当于pandas中的df.median().values,返回的是一维数组
'''
参数strategy的可选项:
"mean", 均值填充
"median", 中值填充
"most_frequent", 最大频次填充(众数)
"constant" 常数填充
'''
2.2.2 处理文本和分类属性
sklearn包装了两个常用处理分类的类:OrdinalEncoder,OneHotEncoder
2.2.2.1 OrdinalEncoder普通分类
OrdinalEncoder输出的是一维数组,适用于程度依次变化的分类(如:坏,平均,好,优秀),不适用于几个分类完全无关的。因为计算机会将邻近的几个数据认为他们关系很贴近。
#导入包
from sklearn.preprocessing import OrdinalEncoder
import pandas as pd
df=pd.DataFrame({'a':[1,2,3,4,5,6],
'b':['one','two','three','two','two','one']})
df
'''
输出:
a b
0 1 one
1 2 two
2 3 three
3 4 two
4 5 two
5 6 one
'''
#OrdinalEncoder操作
ordinal_encoder=OrdinalEncoder()
data=ordinal_encoder.fit_transform(df[['b']])
data
'''
array([[0.],[2.],[1.],[2.],[2.],[0.]])
'''
ordinal_encoder.categories_ #显示原有的类别
#输出:[array(['one', 'three', 'two'], dtype=object)]
2.2.2.2 OneHotEncoder热值分类
OneHotEncoder输出的是二维数组,适用于类别几乎没有联系的分类。
from sklearn.preprocessing import OneHotEncoder
cat_encoder=OneHotEncoder()
data1=cat_encoder.fit_transform(df[['b']])
data1.toarray() #此处需要显示,与OrdinalEncoder不同(可视化需要)
'''
array([[1., 0., 0.],
[0., 0., 1.],
[0., 1., 0.],
[0., 0., 1.],
[0., 0., 1.],
[1., 0., 0.]])
'''
2.2.3 自定义转换器
转换器需要三个函数:fit(),transform(),fit_transform()。其中,我们需要自己写fit()及transform()函数。此外,需要继承TransformerMixin和BaseEstimator类。(已有的转换器,都直接或间接继承了这两个类)。
- TransformerMixin类:提供fit_transform()
- BaseEstimator类:get_params()和set_params()
from sklearn.base import BaseEstimator,TransformerMixin
class myTransform():
def __init__(self):
#此处省略
pass
def fit(self,X,y=None):
#此处省略
return self
def transfrom(self,X):
#此处省略
return np.c_[df,df2,df3] #用于将若干个df拼接,并将其转化为二维数组形式
2.2.4 sklearn归一化、标准化
很多时候,由于特征和标签之间的数字差距很大,导致运算量过大(神经网络需要特征的值在0-1)或其它情况,需要将特征归一化、标准化。
from sklearn.preprocessing import StandardScaler,MinMaxScaler
data1=MinMaxScaler(np.array) #若不想在0-1之间,可以通过feature_range超参调整
data2=StandardScaler(np.array)
2.2.5 转换流水线
2.2.5.1 普通流水线(Pipeline)
通过“流水线”的方式传递数据,此方式可以将处理过程封装到一起,便于预测时的数据达到相同的处理。
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
num_pipeline=Pipeline([
('imputer',SimpleImputer()), #输入df,输出df
('myTransform',myTransform()), #输入df,输出np.array
('stdScaler',StandardScaler()), #输入np.array,输出np.array
#注意,此处是必须以逗号结尾
])
data=num_pipeline.fit_transform(df)
注:
- Pipeline中的最后一个必须是估算器,其前面必须是转换器,即:最后一个调用fit(),前面调用fit_transform();
- Pipeline中需要传入的是元组列表,即列表中必须以逗号结尾。
2.2.5.2 列流水线(ColumnTransformer)
用于将列数据进行处理,可结合Pipeline。
from sklearn.compose import ColumnTransformer
x_attribs_list=['str1','str2','str3']
y_attribs_list=['label']
full_pipeline=ColumnTransformer([
('num',num_pipeline,x_attribs_list),
('cat',OneHotEncoder(),y_attribs_list),
])
data=full_pipeline.fit_transform(df)
#此处可以将数据处理的过程全部封装
注:
- ColumnTransformer是Pipeline的特殊情况,其需要传入的是元组列表;
- 元组内的三个数据以此为:名称(自定义),转化器(函数),列名称(列表)。
三、模型处理小技巧
3.1 评估模型
用于训练模型的时候交叉验证模型
from sklearn.model_selection import cross_val_score
scores=cross_val_score(
estimator,
X,
y=None,
scoring=None, #详细的打分见下图
cv=10 #10折交叉
)
交叉验证的打分字符串选择图:图片源自于https://www.jianshu.com/p/aaa820acae64
3.2 微调模型
3.2.1 网格搜索
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestRegressor
param_grid=[
{'n_estimators':[3,10,30],'max_feature':[2,4,6,8]},
{'bootstrap':[False],'n_estimators':[3,10],'max_features':[2,3,4]},
]
forest_reg=RandomForestRegressor()
grid_search=GridSearchCV(forest_reg,param_grid,cv=5, #estimator
scoring='neg_mean_squared_error',
return_train_score=True)
grid_search.fit(X,y)
grid_search.best_params_ #获取最优参数
#评估分数获取
cvres=grid_search.cv_results_
for mean_sore,params in zip(cvres['mean_test_score'],cvres['params']):
print(np.sqrt(-mean_score),params)
注:
- param_grid为列表,其中以字典分组,最后一个字典后必须加逗号
- 可以利用此交叉验证,写成一个自动搜索参数的类。
3.2.2 随机搜索
当搜索范围很大时,优先选择随机搜索:RandomizedSearchCV。随机搜索的参数和网格搜索大致相同。
3.2.3 集成搜索
此处留着之后填充
总结
此章只列出机器学习常用到的技巧和小知识点,更多、更细的知识点需要对应查找。