先推荐一款免费的笔记本,sublime_text
可以选择各种编程语言方便程序的编写和记录,如果用虚拟机登录mysql数据库也可以先在sublime上写sql语句,方便修改。
一、首先有两个基本问题:
1.1 机器学习是干什么的?
从数据中自动分析获得规律(模型),并利用规律对未知数据进行预测
1.2 哪些使用场景?
医疗、航空、物流、电商…等自动化需求的场景
二、数据集的构成和处理
2.1 数据集的构成:
数据集大多是csv格式文件,可以用pandas读取
(1)特征值+目标值(要干的事情),根据特征去判断目标,不是所有特征都需要,根据需要修改
(2)每一行是一个样本,每一列是一个特征
(3)有些数据集可以没有目标值(用非监督学习算法,典型代表聚类k-means)
获取特征值
li = 数据集
li.data
获取目标值
li.target
数据集进行分割
x_train,x_test,y_train,y_test =
sklearn.model_selection.train_test_split(li.data,li.target,test_size=0.25)
test_size= 比例 返回值包含训练集合测试集 用x_train代表训练集的特征值,x_target代表训练集的目标值
x_test测试集的特征值,y_test测试集的目标值
x:数据集的特征值
y:数据集的目标值
test_size:测试集的大小
2.2 对特征的处理
文本不能直接输入让机器计算,需要数据化,这就需要特征工程
对缺失值:数据转换
对重复值:不处理(机器学习中不需要去重)
特征工程包括:特征抽取、特征预处理、数据降维
2.2.1 特征抽取:
比如将文本转换成数字类型
文本、字符串转换成数字形式
对文本等数据进行特征值化,为了计算机更好的理解数据,只能理解数据
1.字典特征抽取 对字典进行特征值化 转成one-hot编码形式
API:sklearn.feature_extraction.DictVectorizer
#Vectorizer数字化
语法:DicVectorizer(sparse=True,...)
DictVectorizer.fit_transform(X)
X:字典或者包含字典的迭代器 字典放在列表里
返回值:返回sparse矩阵 #scipy中的数据类型
DictVectorizer.get_feature_names()
返回类别名称
DictVectorizer.transform(X)
按照原先的标准转换
2.文本特征抽取
对文本等数据进行特征值化
API:sklearn.feature_extraction.text.TfidfVectorizer
语法:TfidfVectorizer(stop_words=None,...) #stop_words= 忽略哪些词
TfidfVectorizer.fit_transform(X)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵
TfidfVectorizer.get_feature_names()
第一行特征名称
返回值:单词列表
得到的列表是每个词的重要性程度
2.2.2 特征预处理:
1.归一化
通过对原始数据进行变换把数据映射到(默认[0,1]之间)
公式: X’ =(x-min)/(max-min) X’’ = X’*(mx-mi)+mi
每一列特征,最大值max,最小值min mx,mi分别指定区间,默认mx为1,mi为0
API:sklearn.preprocessing.MinMaxScaler
最小最大值缩放
语法:MinMaxScaler(feature_range=(0,1)...) #feature_range 缩放到什么范围
MinMaxScaler.fit_transform(X)
各个特征同等重要的时候,需要进行归一化,使得一个特征对最终结果不会造成更大影响
数据中异常点较多(从公式考虑),列的最大值最小值改变,最终计算的结果有偏差
归一化容易受异常点影响,鲁棒性较差,只适合传统精确小数据场景,一般不使用归一化
2.标准化
不容易受到异常点影响
通过对原始数据进行变换把数据变换到均值为0,标准差为1的范围内
公式:X’ =(x-mean)/δ #作用于每一列,mean为平均值,δ为标准差
var(方差) =((x1-mean)^2 +(x2-mean)^2 +…)/m(每个特征的样本数) δ=√var
作用于每一列 方差为0,这个特征所有值都一样,方差越大,数据越离散
API:scikit-learn.preprocessing.StandardScaler #标准缩放
StandardScaler.fit_transform(X)
X:numpy array 格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array
StandardScaler.mean_
原始数据中每列特征的平均值
StandardScaler.std()
原始数据每列特征的方差
在已有样本足够多的情况下比较稳定,适合现代嘈杂的大数据场景
2.2.3 数据降维
维度:和数组的维度不一样,指特征的数量
降维:比如3个特征转换成2个特征,特征数量减少
两种方式:1.特征选择 2.主成分分析
过滤式
删除低方差的特征
把方差过小的、差不多的特征过滤掉
API:sklearn.feature_selection.VarianceThreshold
主成分分析
API:sklearn.decomposition #主成分分析
PCA:数据维数压缩,尽可能降低数据的维数(复杂度),损失少量信息 #应用场景不是特别多
特征数量达到上百的时候,考虑pca数据简化
PCA:数据会改变,特征数量会减少
高维度数据容易出现的问题:特征之间通常是相关的
语法:PCA(n_components=None)
n_components:小数 0-1 指定保留多少信息 经验 90%-95%之间
整数 减少到的特征数量(一般不使用)
PCA.fit_transform(X)
X:numpy array 格式的数据[n_samples,n_features]
返回值:转换后指定维度的array
2.3 转换器
特征工程步骤:
1.实例化API
2.调用fit_transform
fit_transform() #输入数据直接转换
fit() #输入数据,不转换
计算平均值标准差
+transform() #进行数据的转换
先加数据用fit_transform(),再加数据直接用transform(),不用fit()和fit_transform(),fit输入内容不同转换的标准改变
三、常见机器学习算法
3.1 k近邻算法(KNN)
定义:一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别
核心思想:比较特征的远近,相似的样本特征之间的值应该是相近的
需要做标准化处理,防止某特征距离过大影响过大
欧式距离:√((a1-b1)^2 + (a2-b2)^2 +(a3-b3)^2)
API:sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm='auto')
n_neighbors=5 默认使用的邻居数
3.2 朴素贝叶斯
预测每个文档是各个类别的概率,可能性,然后划分类别
朴素贝叶斯的前提:特征独立
P(科技|文档)替换成 P(科技|词1,词2,词3…)
P(娱乐|文档…) 文档2:词1,词2,词3…
和条件概率不一样,条件概率是一个条件下多个结果,现在是多个条件一个类别
此时需要贝叶斯公式
P(C|W)=(P(W|C)P(C ))/P(W)
W:为给定文档的特征值 C:为文档类别
可以理解为:P(C|F1,F2,…)=(P(F1,F2,…|C)P(C ))/P(F1,F2,…)
API:sklearn.naive_bayes.MultinomialNB
参数:alpha = 1.0默认 拉普拉斯平滑系数 防止出现0
算法不需要调参,影响准确率的因素就是训练集,训练集影响非常大
3.3 决策树、随机森林
问题:哪个特征放在最上面
1个字节8比特 信息定义成比特
比如:32个球队,不知道任何一支球队信息,猜对冠军的最大代价是5比特
开放一些数据信息,代价小于5比特
5=-(1/32log(1/32)+1/32log(1/32)+…)
把比特理解成代价,这个代价就是信息熵
H(X)=∑P(x)logP(x) H信息熵,单位:比特
信息和消除不确定性是相联系的
信息熵越大不确定性越大,越小不确定性越小
决策树的划分依据之一—————信息增益
当得知一个特征条件之后,减少的信息熵的大小
g(D,A)=H(D)-H(D|A) g:信息增益(某一个特征减少信息熵的大小)
A:一个特征
H(D):初始信息熵大小 H(D|A):A条件下的信息熵
决策树API:sklearn.tree.DecisionTreeClassifier(criterion='gini',max_depth=None,random_state=None)
criterion:默认是'gini'系数,也可以选择信息增益的熵'entropy'
max_depth:树的深度大小 几层
random_state:随机数种子
decision_path:返回决策树的路径
criterion= 选择依据
随机森林:
随机森林包含多个决策树的分类器,输出的类别是由个别树输出的类别的众数而定
多个决策树投票
单个树建立过程:N个样本,M个特征
1.样本
随机在N个样本当中选择一个样本(复制拿过来,不减少),重复N次
样本有可能重复
2.特征
随机在M个特征当中选出m个(小于M)特征
建立了10颗决策树,样本,特征大多不一样 随机有放回的抽样(bootstrap抽样)
为什么随机抽样训练集:每个决策树不一样
为什么有放回的抽样:无放回会使每个树都是完全不同的,每棵树训练出来有很大的差异,而随机森林最后分类取决于多棵树(弱分类器)的投票表决
API:sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=True,random_state=None,max_features="auto") #还有很多参数
n_estimators= 建立多少棵决策树 一般给120,200,300,500,800,1200
超参数
criterion= 分类依据 基尼系数,信息增益 一般用基尼系数gini
max_depth= 每一棵树的深度限制 超参数
bootstrap=True 随机有放回 默认True
random_state= 随机种子 不用管
max_features="auto" 每个决策树的最大特征数量 m的最大值,防止过拟合
auto:自动 最大特征数是特征数开根号
sqrt:根号 最大特征数是特征数开根号
log2: 以log2求 比如 3=log2(8) 8是总特征值
3.4 线性回归
定义:通过一个或多个自变量与因变量之间进行建模的回归分析。
目标值是连续的值就可以用回归算法来做,回归就是在找一种趋势
线性关系模型:f(x)=w1x1+w2x2+…+wdxd+b
线性关系模型中:w表示权重(找出这个值) b偏置项
损失函数(误差大小) 损失函数就是误差
yi为第i个样本的真实值,hw(xi)为第i个样本特征值组合预测函数,
(预测结果-真实结果)^2和
总损失:J(θ)=(hw(x1)-y1)^2 + (hw(x2)-y2)^2 +…=∑(hw(xi)-yi)^2
如何寻找w
1.正规方程 当特征过于复杂,求解速度太慢
2.梯度下降 α学习速率,需手动指定(超参数)
理解:沿着函数下降方向找,最后找到最低点,更新W值
使用:面对训练数据十分庞大的任务
正规方程API:sklearn.linear_model.LinearRegression
普通最小二乘线性回归(正规方程)
coef_:回归系数 最终的W值 W就是回归系数
梯度下降API:sklearn.linear_model.SGDRegressor
通过使用SGD最小化线性模型
coef_:回归系数 最终的W值 W就是回归系数
回归性能评估(均方误差) 平均每一个样本的差值的平方
MSE=(1/m)∑(yi(预测值)-y(真实值))^2
回归评估API:sklearn.metrics.mean_squared_error #metrics度量
mean_squared_error(y_true,y_pred)
y_true 真实值
y_pred 预测值
return:浮点数结果
真实值、预测值为标准化之前的值
过拟合欠拟合
训练的很好,但是测试数据时却没有很好的效果,怎么办?
线性回归拟合的数据不一定是线性的,对线性模型进行训练学习会变成复杂模型
模型复杂的原因:数据的特征和目标值之间的关系不仅仅是线性关系
根据结果现象判断过拟合还是欠拟合
通过交叉验证看训练集的结果:
欠拟合:训练集表现不好,测试集表现不好,看准确率和误差
过拟合:训练集特别好,测试集表现不好,考虑特征数据是不是过于复杂
过拟合原因:原始特征过多,存在嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点
正则化解决过拟合
影响模型复杂度的是高次项,尝试调整把高次项系数(权重)减少趋近于0,尽量减少高次项特征影响,不断尝试得来
L2正则化:使得W的每个元素都很小,都接近于0(把高次项权重减小,使权重趋近于0 )
优点:越小的参数说明模型越简单,越简单的模型越不容易产生过拟合现象
线性回归:LinearRegression 容易出现过拟合,为了使训练集数据表现更好
岭回归:Ridge 带有正则化的线性回归
岭回归API:sklearn.linear_model.Ridge
sklearn.linear_model.Ridge(alpha=1.0) #0-1 1-10 小数或整数 可以用网格搜索选择
alpha:正则化力度 超参数
正则化力度越大,权重趋近于0(不是等于0),模型越来越简单,但是不能过简单,正则化力度是一个需要调参的过程
coef_:回归系数
3.5 分类算法-逻辑回归
二分类问题利器,线性回归的式子作为输入
应用场景:广告点击率、是否为垃圾邮件、是否患病、金融诈骗、虚假账号
只能做二分类问题,任何二分类场景都能得出概率值
逻辑回归的输入:和线性回归一样
输入:Z(w)=w0+w1x1+w2x2+…=wTx
#得出一个值
也和线性回归一样存在过拟合问题
sigmoid函数:将输入(x)转换成 0-1之间的某个值
与y轴交叉的地方默认 0.5 #因为sigmoid函数把输入转换成0-1之间的概率值
g(z)=1/(1+e-z) # -z为上角标 e:2.71 z=回归的结果
g(z)输出:[0,1]区间的概率值,默认0.5作为阈值(小于0.5归为0,大于0.5归为1)
逻辑回归的损失函数:
与线性回归原理相同,但由于是分类问题,损失函数不一样,只能通过梯度下降求解
对数似然损失函数(类型信息熵的角度)
损失函数:均方误差(只有一个最小值,不存在多个局部最低点)
对数似然损失:有多个局部最小值(到目前没有更好的解决办法,目前解决不了)
解决办法(尽量改善,不能最终解决,尽管没有全局最低点,但是效果不错):
1.多次随机初始化,多次比较最小值结果
2.在求解过程中,调整学习率(比如加大学习率直接跳过局部最低点)
逻辑回归API:sklearn.linear_model.LogisticRegression
sklearn.linear_model.LogisticRegression(penalty='l2',C=1.0)
penalty= 正则化
有线性回归的过拟合,参数penalty='l2'以l2的形式正则化,C=1.0正则化力度
Logistic回归分类器
coef_:回归系数
3.6 非监督学习算法
只有特征值,没有目标值
k-means:聚类 把有相似特征的归成一类
比如:一些数据有2个特征,分成3个类别
k:把数据划分成多少个类别
k的取值:一般知道类别的个数
不知道类别个数,超参数,比如取3
1.随机在数据当中抽取三个样本,当做三个类别的中心点(k1,k2,k3)
2.计算其余的点分别到这三个中心点的距离(每一个样本有三个距离,从中选出距离最近的一个点,作为自己的标记,形成三个族群)
3.分别计算三个族群的平均值,把三个平均值与之前的三个旧中心点比较,如果相同,结束聚类;如果不同,把这三个平均值当做新的中心点,重复第二步
k-meansAPI:sklearn.cluster.KMeans #cluster聚类 KMeans k均值
sklearn.cluster.KMeans(n_clusters=8,init='k-means++')
n_clusters:开始的聚类中心数量 把样本分为多少个类别
init:初始化方法,默认为'k-means++'
labels_:默认标记的类型,可以和真实值比较(不是值比较)
一般聚类做在分类之前