从零开始的深度学习-python之机器学习

引言

作为一位计算机系的学生,本人十分惭愧居然一点python的基础都没有。因此,这一系列博文便记录了本人学习从python基础到python深度学习的过程吧。

数据集

数据集的划分

训练数据:用于训练构建模型

测试数据:在模型检验时使用,用于评估模型是否有效(20%~30%)

1
2
3
4
5
6
7
8
9
10
11
12
api:sklearn.model_selection.train_test_spilt(arrays,*options)

x 数据集的特征值

y 数据集的目标值

test_size 测试集的大小,一般为float

random_size 随机数种子

return 训练集特征值(x_train)、测试集特征值(x_test)、训练集目标值(y_train)、测试集目标值(y_test)

对鸢尾花数据集进行划分

1
2
3
4
5
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris=load_iris()
#数据集划分
x_train,x_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)

特征提取

将任意数据(如文本或图像)转换为可用于机器学习的数字特征

特征提取api:sklearn.feature_extraction

字典特征提取

对字典数据进行特征值化–类别

1
2
3
4
5
6
7
8
9
10
11
12
13
api:sklearn.feature_extraction.DictVectorizer(Sparse=True,...)

DictVectorizer.fit_transform(X)

X:字典或包含字典的迭代器返回值 返回sparse矩阵

DictVectorizer.inverse_transform(X)

X:Array数组或sparse矩阵 返回:转换成之前数据格式

DictVectorizer.getfeature_names()

返回类别名称

代码:

1
2
3
4
5
6
from sklearn.feature_extraction import DictVectorizer
data = [{"city":"北京","temperature":100},{"city":"上海","temperature":60},{"city":"深圳","temperature":30}]
#1.实例化一个转换器类
transfer=DictVectorizer()
#2.调用fit_transform()
data_new=transfer.fit_transform(data)

输出

1
2
3
4
5
6
(0, 1)        1.0  
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0

由于是稀疏矩阵,等价于

1
2
3
[  0.   1.   0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]

文本特征提取

根据单词作为特征

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
api:sklearn.feature_extraction.text.CountVectorizer(stop_words[])

统计样本出现特征词的次数,返回词频矩阵

CountVectorizer.fit_transform(X)

X:文本或包含文本字符串的可迭代对象 返回值:sparse矩阵

CountVectorizer.inverse_transform(X)

X:Array数组或sparse矩阵 返回:转换成之前数据格式

CountVectorizer.getfeature_names()

返回值:单词列表

代码:

1
2
3
4
5
6
7
from sklearn.feature_extraction.text import CountVectorizer
data = ["life is short,i like like python", "life is too long,i dislike python"]
#1.实例化一个转换器类
transfer=CountVectorizer()
#2.调用fit_transform()
data_new=transfer.fit_transform(data)
print(data_new.toarray())

输出:

1
2
[0 1 1 2 0 1 1 0]
[1 1 1 0 1 1 0 1]

但是如果需要特征值化的数据是中文呢?

jieba分词

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.feature_extraction.text import CountVectorizer
import jieba
data = ["作为一位计算机系的学生,本人十分惭愧居然一点python的基础都没有。因此,这一系列博文便记录了本人学习从python基础到python深度学习的过程吧。"]
#1.实例化一个转换器类
transfer=CountVectorizer()
'''
2.jieba分词
由于返回的是词汇生成器,需要强转
'''
data=" ".join(list(jieba.cut(data[0])))
#3.调用fit_transform()
data_new=transfer.fit_transform([data])
print(data_new.toarray())

结果:

1
[[3 1 1 1 1 1 1 1 2 2 1 1 1 2 1 1 1 1 1]]

方法二:统计关键词

关键词:在某一个类别的文章中,出现的次数很多,但是在其他类别的文章中出现很少

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
api:sklearn.feature_extraction.text.TfidfVectorizer(stop_words[])

统计样本出现关键词的次数,返回词频矩阵

TfidfVectorizer.fit_transform(X)

X:文本或包含文本字符串的可迭代对象 返回值:sparse矩阵

TfidfVectorizer.inverse_transform(X)

X:Array数组或sparse矩阵 返回:转换成之前数据格式

TfidfVectorizer.get_feature_names_out()

返回值:单词列表

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
data = ["作为一位计算机系的学生,本人十分惭愧居然一点python的基础都没有。因此,这一系列博文便记录了本人学习从python基础到python深度学习的过程吧。"]
#1.实例化一个转换器类
transfer=TfidfVectorizer(stop_words=["一位","一点"])
'''
2.jieba分词
由于返回的是词汇生成器,需要强转
'''
data=" ".join(list(jieba.cut(data[0])))
#3.调用fit_transform()
data_new=transfer.fit_transform([data])
print(data_new.toarray())
print(transfer.get_feature_names_out())

输出:

1
2
3
4
[[0.51449576 0.17149859 0.17149859 0.17149859 0.17149859 0.17149859
0.34299717 0.34299717 0.17149859 0.17149859 0.17149859 0.34299717
0.17149859 0.17149859 0.17149859 0.17149859 0.17149859]]
['python' '一系列' '作为' '十分' '博文' '因此' '基础' '学习' '学生' '居然' '惭愧' '本人' '没有' '深度' '计算机系' '记录' '过程']

特征预处理

通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程

数值型数据的无量纲化:归一化、标准化

希望不同规格数据转化为统一规格

归一化

将原始数据映射到一个固定区间内

1
2
3
4
5
6
api:sklearn.preprocessing.MinMaxScaler(feature_range=(0.1)...)

MinMaxScaler.fit_transform(X)

X:numpy array格式的数据[n_sample,n_feature] 返回值:转换后形状相同的array

代码:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.preprocessing import MinMaxScaler
import pandas
#1.获取数据
data=pandas.read_csv("dating.txt")
data=data.iloc[:,:3]
#2.转换器类
transfer=MinMaxScaler()
#3.调用fit_transform
data_new=transfer.fit_transform(data)
print(data_new)

结果:

1
2
3
4
5
6
7
[[0.44832535 0.39805139 0.56233353]
[0.15873259 0.34195467 0.98724416]
[0.28542943 0.06892523 0.47449629]
...
[0.29115949 0.50910294 0.51079493]
[0.52711097 0.43665451 0.4290048 ]
[0.47940793 0.3768091 0.78571804]]

总结:健壮性较差,仅适合精确小数据使用

标准化

将原始数据进行变换,把数据变换到均值为0,标准差为1的范围内

1
2
3
4
5
6
api:sklearn.preprocessing.StandardScaler()

StandardScaler.fit_transform(X)

X:numpy array格式的数据[n_sample,n_feature] 返回值:转换后形状相同的array

代码:

1
2
3
4
5
6
7
8
9
10
11
from sklearn.preprocessing import StandardScaler
import pandas

#1.获取数据
data=pandas.read_csv("dating.txt")
data=data.iloc[:,:3]
#2.转换器类
transfer=StandardScaler()
#3.调用fit_transform
data_new=transfer.fit_transform(data)
print(data_new)

输出:

1
2
3
4
5
6
7
[[ 0.33193158  0.41660188  0.24523407] 
[-0.87247784 0.13992897 1.69385734]
[-0.34554872 -1.20667094 -0.05422437]
...
[-0.32171752 0.96431572 0.06952649]
[ 0.65959911 0.60699509 -0.20931587]
[ 0.46120328 0.31183342 1.00680598]]

总结:健壮性较强,仅适合大量数据使用

特征降维

降维:降低特征的个数,得到一组“不相干”的主变量的过程

特征选择

Filter:

方差选择法:低方差特征过滤

删除低方差的一些特征,再结合方差大小考虑这个方式的角度

1
2
3
4
5
api:feature_selection.VarianceThreshold(threshold=0)
删除所有低方差特征
Variance.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
返回值:低于threshold的特征都删除

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.feature_selection import VarianceThreshold
import pandas

#1.获取数据
data=pandas.read_csv("factor_returns.csv")
#2.取出非特征部分
data=data.iloc[:,1:-2]
#3.转换器类(根据需求过滤掉不需要的特征)
variance=VarianceThreshold()
#3.调用fit_transform
data_new=variance.fit_transform(data)
print(data_new)

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
[[ 5.95720000e+00  1.18180000e+00  8.52525509e+10 ...  2.01000000e+00
2.07014010e+10 1.08825400e+10]
[ 7.02890000e+00 1.58800000e+00 8.41133582e+10 ... 3.26000000e-01
2.93083692e+10 2.37834769e+10]
[-2.62746100e+02 7.00030000e+00 5.17045520e+08 ... -6.00000000e-03
1.16798290e+07 1.20300800e+07]
...
[ 3.95523000e+01 4.00520000e+00 1.70243430e+10 ... 2.20000000e-01
1.78908166e+10 1.74929478e+10]
[ 5.25408000e+01 2.46460000e+00 3.28790988e+10 ... 1.21000000e-01
6.46539204e+09 6.00900728e+09]
[ 1.42203000e+01 1.41030000e+00 5.91108572e+10 ... 2.47000000e-01
4.50987171e+10 4.13284212e+10]]
相关系数:特征与特征之间的相关程度
1
2
3
4
5
6
7
皮尔森相关系数:

相关系数的值介于-1~+1之间,性质如下:

当r>0,表示两变量正相关,r<0,表示两变量负相关
当|r|=1,表示两变量完全相关,当r=0,表示两变量无相关关系
一般分为三部分:|r|<0.4为低相关,0.4<=|r|<0.7为显著性相关,0.7<=|r|高度线性相关
1
2
3
4
api:from scipy.stats import pearsonr
x:array_like
y:array_like
Returns:皮尔森相关系数

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from sklearn.feature_selection import VarianceThreshold
from scipy.stats import pearsonr
import pandas

#1.获取数据
data=pandas.read_csv("factor_returns.csv")
#2.取出非特征部分
data=data.iloc[:,1:-2]
#3.转换器类
variance=VarianceThreshold(threshold=10)
#4.调用fit_transform
data_new=variance.fit_transform(data)
#5.计算两变量相关系数
r,p=pearsonr(data["pe_ratio"],data["pb_ratio"])
print("相关系数:",r,p)

结果:

1
相关系数: -0.004389322779936271 0.8327205496590723

特征和特征之间相关性很高:主成分分析

主成分分析(PCA)

找到一个合适的方法,在降维时最大程度保留原有特征

1
2
3
4
5
6
7
8
api:sklearn.decomposition.PCA(n_components=None)
将数据分解为较低维数空间
n_components:
小数:表示保留百分之多少的信息
整数:减少到多少特征
PCA.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
返回:已经降维后的array

Embedded:

决策树

高效的进行决策,决定特征的先后顺序

1
2
3
4
5
api:sklearn.tree.DecisionTreeClassifier(criterion='gini',max_depth=None,random_state=None)
决策树分类器
criterion:默认是gini系数,也可以选择信息增益的entropy
max_depth:树的深度大小
random_state:随机数种子

分类算法

KNN算法

核心思想:根据你的邻居推算出你的类别

定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

K值过小,容易受到异常值影响;K值过大,容易受到样本不均衡的影响

算法步骤:

1.estimator.fit(x_train,y_train) 进行模型训练

2.y_predict=estimator.predict(x_test) 进行模型预测

3.score=estimator.score(x_test,y_test) 比对模型训练结果

1
2
3
4
5
6
7
8
9
10
11
api:sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto)

n_neighbors:int,可选(默认=5),k_neighbors查询默认使用的邻居数

algorithm:["auto","ball_tree","kd_tree","brute"],可选用于计算最近邻居的算法

ball_tree将会使用 BallTree

“kd_tree将使用 KDTree。

auto将尝试根据传递给fit方法的值来决定最合适的算法。(不同实现方式影响效率)

模型选择与调优

交叉验证

将拿到的训练数据,分为训练和验证集。例如:将数据分成4份,其中一份作为验证集。然后经过4次(组)的测试,每次都更换不同的验证集。即得到4组模型的结果,取平均值作为最终结果。

超参数搜索-网格搜索

通常情况下,有很多参数是需要手动指定的 (如k-近邻算法中的K值),这种叫超参数但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)

对估计器的指定参数值进行详尽搜索
estimator:估计器对象
param_grid:估计器参数(dict)["n_neighbors":[1,3,5]]
cv:指定几折交叉验证
fit0: 输入训练数据
score0:准确率

结果分析:
最佳参数:best_params
最佳结果: best_score_
最佳估计器: best_estimator_
交叉验证结果: cv_results

朴素贝叶斯算法

1
2
3
sklearn.naive_bayes-MultinomialNB(alpha = 1.0)
朴素贝叶斯分类
alpha: 拉普拉斯平滑系故

应用场景:文本分类、单词作为特征

随机森林

随机森林是一个包含多个决策树的决策器

集成学习方法

集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何-个单分类的做出预测。

1
2
3
4
5
6
7
8
9
10
11
12
13
api:sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion='gini',max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)
随机森林分类器
n_estimators: integer,optional (default = 10) 森林里的树木数量:120,200,300,500,800,1200
criteria: string,可选 (default =“gini”)也可以选择信息增益的entropy 分割特征的测量方法
max_depth:integer或None,可选(默认=无)树的最大深度5,8,15,25,30
max features="auto”每个决策树的最大特征数量
If"auto", then max_features=sqrt(n_features)
lf"sqrt", then max_features=sqrt(n_features) (same as "auto").lf"log2", then max_features=log2(n_features)
If None, then max_features=n_features .
bootstrap: boolean,optional (default = True) 是否在构建树时使用放回抽样
min_samples_split:节点划分最少样本数
min_samples_leaf:叶子节点的最小样本数
超参数: n_estimator,max_depth, min_samples_split,min_samples_leaf

回归与聚类算法

线性回归

应用场景:目标值为连续值(eg:房价预测、销售额度预测、贷款额度预测)

损失函数/cost:假定一个预测值,然后计算它与真实值的误差

小于10w:

1
2
3
4
5
api:sklearn.linear_model.LinearRegression(fit_intercept=True)
通过正规方程优化
fit_intercept:是否计算偏置
LinearRegression.coef_: 回归系数
LinearRegression.intercept_:偏置

大于等于10w:

1
2
3
4
5
6
7
8
9
10
11
12
13
api:sklearn.linear_model.SGDRegressor(loss="squared_loss"fit_intercept=True,learning_rate ='invscaling', eta0=0.01)
SGDRegressor类实现了随机梯度下降学习,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型。
loss:损失类型
loss="squared_loss":普通最小二乘法o
fit_intercept:是否计算偏置
learning_rate : string, optional
学习率填充
'constant': eta = eta0
'optimal': eta = 1.0 / (alpha * (t + t0)) [default]
'invscaling': eta = eta0 / pow(t, power_t) power_t=0.25:存在父类当中
对于一个常数值的学习率来说,可以使用learning_rate='constant'并使用eta0来指定学习率。
SGDRegressor.coef_: 回归系数
SGDRegressor.intercept_: 偏置

回归性能评估

1
2
3
4
5
sklearn.metrics.mean_squared_error(y_true,y_pred)
均方误差回归损失
y_true:真实值
y_pred:预测值
return:浮点数结果

岭回归

处理过拟合问题

正则化力度越大,权重越小

正则化力度越小,权重越大

1
2
3
4
5
6
7
8
9
10
api:sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,solver="auto",normalize=False)
具有L2正则化的线性回归
alpha:正则化力度,也叫λ
λ取值:0~1 1~10
solver:会根据数据自动选择优化方法
sag:如果数据集、特征都比较大,选择该随机梯度下降优化
normalize:数据是否进行标准化
normalize=True:可以在fit之前调用preprocessing.StandardScaler标准化数据
Ridge.coef_:回归权重
Ridge.intercept_:回归偏置

逻辑回归

两个类别之间的判断(eg:广告点击率,是否为垃圾邮件,是否患病,金融诈骗)

1
2
3
4
5
api:sklearn.linear_model.LogisticRegression(solver='liblinear',penalty='l2',C=1.0)
solver:优化求解方式(默认开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数)
sag:根据数据集自动选择,随机平均梯度下降
penalty:正则化的种类
C:正则化力度

模型评估

F1-score:反应模型的稳健性

召回率:数据全不全

精确率:正确程度

1
2
3
4
5
6
7
api:sklearn.metrics.classification_report(y_true, y_pred, labels=[],target_names=None)

y_true:真实目标值
y_pred:估计器预测目标值
labels:指定类别对应的数字
target_names:目标类别名称
return:每个类别精确率与召回率

ROC曲线和AUC指标

ROC曲线:模轴就是FPRate(0预测为1),纵轴就是TPRate(1预测为1),当二者相等时,表示的意义则是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5

AUC的概率意义是随机取一对正负样本,正样本得分大于负样本的概率

AUC的最小值为0.5,最大值为1,取值越高越好

AUC=1,完美分类器,采用这个预测模型时,不管设定什么闻值都能得出完美预测。

绝大多数预测的场合,不存在完美分类器。

0.5<AUC<1,优于随机猜测。这个分类器 (模型)妥善设定闻值的话,能有预测价值。

1
2
3
4
api:sklearn.metrics.roc_auc_score(y_true, y_score)
计算ROC曲线面积,即AUC值
y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
y_score:预测得分,可以是正类的估计概率、置信值或者分类器方法的返回值

K-means算法

K-means聚类步骤
1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点 (平均值)
4、如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行第二步过程

1
2
3
4
5
api:sklearn.cluster.KMeans(n clusters=8,init="k-means++")
k-means聚类
n_clusters:开始的聚类中心数量
init:初始化方法,默认为k-means ++
labels :默认标记的类型,可以和真实值比较 (不是值比较)