机器学习总结

目录

一.连续特征的离散化:在什么情况下将连续的特征离散化之后可以获得更好的效果?

二.LabelEncoder和OneHotEncoder 在特征工程中的应用

三.神经网络(深度学习)

四.反向传播与梯度下降

五.聚类算法

六.机器学习:样本分布不均衡问题的处理

1.对正样本过采样---容易造成过拟合

2.对负样本欠采样 ---容易丢失重要信息

3.调整权重

七.jieba中文分词

八.推荐系统传统召回是怎么实现热门item的打压

 


 

一.连续特征的离散化:在什么情况下将连续的特征离散化之后可以获得更好的效果?

在工业界,很少直接将连续值作为逻辑回归模型的特征输入,而是将连续特征离散化为一系列0、1特征交给逻辑回归模型,这样做的优势有以下几点:

0. 离散特征的增加和减少都很容易,易于模型的快速迭代;

1. 稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;

2. 离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0。如果特征没有离散化,一个异常数据“年龄300岁”会给模型造成很大的干扰;

3. 逻辑回归属于广义线性模型,表达能力受限;单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合;

4. 离散化后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;

5. 特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是门学问;

6. 特征离散化以后,起到了简化了逻辑回归模型的作用,降低了模型过拟合的风险。

 

李沐曾经说过:模型是使用离散特征还是连续特征,其实是一个“海量离散特征+简单模型” 同 “少量连续特征+复杂模型”的权衡。既可以离散化用线性模型,也可以用连续特征加深度学习。就看是喜欢折腾特征还是折腾模型了。通常来说,前者容易,而且可以n个人一起并行做,有成功经验;后者目前看很赞,能走多远还须拭目以待。

https://www.zhihu.com/question/31989952

二.LabelEncoder和OneHotEncoder 在特征工程中的应用

在特征工程工程中处理离散数据时候,需要将原来的数据转化成数字格式才能传入 模型,这时候需要用到两个编码函数

先简单的来说:

LabelEncoder()是标签编码,即是对不连续的数字或者文本进行编号,转换成连续的数值型变量,例如

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit([1,5,67,100])
le.transform([1,1,100,67,5])

输出: array([0,0,3,2,1])

OneHotEncoder()即独热编码,直观的来看就是有几个需要编码的状态就有几个比特,例如

  5个需要编码的,编码结果就是[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,01]

一般用来分类

底下是详细的说法

1、LabelEncoder

LabelEncoder 可以理解为一个打标签的机器
首先 通过 fit 列表 a 来得到所有标签的种类, a 中可以有重复的数据,这个种类也就是 a 中所有不同数据的 集合,可以通过 le.classes_ 来查看,并且会给定顺序,每个数据有对应的序号,在对其他数据列表进行标记时候,返回 每个数据对应的序号,通过 inverse_transform 还可以实现反向编码
LabelEncoder是用来对分类型特征值进行编码,即对不连续的数值或文本进行编码。其中包含以下常用方法:

fit(y) :fit可看做一本空字典,y可看作要塞到字典中的词。
fit_transform(y):相当于先进行fit再进行transform,即把y塞到字典中去以后再进行transform得到索引值。
inverse_transform(y):根据索引值y获得原始数据。
transform(y) :将y转变成索引值。

>>> from sklearn import preprocessing
>>> le = preprocessing.LabelEncoder()
>>> le.fit([1, 2, 2, 6])
LabelEncoder()
>>> le.classes_
array([1, 2, 6])
>>> le.transform([1, 1, 2, 6]) 
array([0, 0, 1, 2]...)
>>> le.inverse_transform([0, 0, 1, 2])
array([1, 1, 2, 6])
==============================================================

>>> le = preprocessing.LabelEncoder()
>>> le.fit(["paris", "paris", "tokyo", "amsterdam"])
LabelEncoder()
>>> list(le.classes_)
['amsterdam', 'paris', 'tokyo']
>>> le.transform(["tokyo", "tokyo", "paris"]) 
array([2, 2, 1]...)
>>> list(le.inverse_transform([2, 2, 1]))
['tokyo', 'tokyo', 'paris']

2、OneHotEncoder

有一些特征并不是以连续值的形式给出。例如:人的性别 [“male”, “female”],来自的国家 [“from Europe”, “from US”, “from Asia”],使用的浏览器[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]。这种特征可以采用整数的形式进行编码,如: [“male”, “from US”, “uses Internet Explorer”] 可表示成 [0, 1, 3] ,[“female”, “from Asia”, “uses Chrome”] 可表示成[1, 2, 1]。 但是,这些整数形式的表示不能直接作为某些机器学习算法输入,因为有些机器学习算法是需要连续型的输入数据,同一列数据之间数值的大小可代表差异程度。如: [0, 1, 3]与[0,1,0]的特征差异比[0, 1, 3]与[0,1,2]之间的差异要大,但事实上它们的差异是一样的,都是浏览器使用不一样。

一个解决办法就是采用OneHotEncoder,这种表示方式将每一个分类特征变量的m个可能的取值转变成m个二值特征,对于每一条数据这m个值中仅有一个特征值为1,其他的都为0。

>>> enc = preprocessing.OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  # 注意:第1、2、3列分别有2、3、4个可能的取值
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
>>> enc.transform([[0, 1, 3]]).toarray() #要对[0,1,3]进行编码
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.]]) # [1,0]对应数值0,[0,1,0]对应数值1,[0,0,0,1]对应数值3

3、LabelEncoder与OneHotEncoder的混合使用方式

from sklearn.preprocessing import LabelEncoder,OneHotEncoder
enc = OneHotEncoder()
lb = LabelEncoder()
tmp = lb.fit_transform([123,456,789])
print(tmp)#输出LabelEncoder的结果
enc.fit(tmp.reshape(-1,1))#将LabelEncoder的结果作为OneHotEncoder特征输入
x_train = enc.transform(lb.transform([123,789]).reshape(-1, 1))
#输出特征[123,789]的OneHotEncoder的编码结果
print(x_train)

完整的机器学习流程图

机器学习总结_第1张图片

参考:

https://www.cnblogs.com/king-lps/p/7846414.html

https://www.tqwba.com/x_d/jishu/98776.html

三.神经网络(深度学习)

神经网络顾名思义,就像我们人脑中的神经元一样,为了让机器来模拟人脑,我们在算法中设置一个个节点,在训练模型时,输入的特征与预测的结果用节点来表示,系数w(又称为"权重")用来连接节点,神经网络模型的学习就是一个调整权重的过程,训练模型一步步达到我们想要的效果.

三大神经网络:

"多层感知器",即MLP算法,泛称为神经网络 -DNN

卷积神经网络--CNN

递归神经网络-RNN

机器学习总结_第2张图片

神经网络主要有三个基本要素:权重、偏置和激活函数

权重:神经元之间的连接强度由权重表示,权重的大小表示可能性的大小

偏置:偏置的设置是为了正确分类样本,是模型中一个重要的参数,即保证通过输入算出的输出值不能随便激活。

激活函数:起非线性映射的作用,其可将神经元的输出幅度限制在一定范围内,一般限制在(-1~1)或(0~1)之间。最常用的激活函数是Sigmoid函数,其可将(-∞,+∞)的数映射到(0~1)的范围内。

  • tanh函数吧特征X的值压缩进-1到1的区间内,-1代表的是X中较小的数值,而1代表X中较大的数值.
  • relu函数把小于0的X值全部去掉,用0来代替

激活函数还有tanh和ReLU等函数,

tanh是Sigmoid函数的变形,tanh的均值是0,在实际应用中有比Sigmoid更好的效果;

ReLU是近来比较流行的激活函数,当输入信号小于0时,输出为0;当输入信号大于0时,输出等于输入;具体采用哪种激活函数需视具体情况定。

机器学习总结_第3张图片机器学习总结_第4张图片

#导入numpy
import numpy as py
#导入numpy
import numpy as np
#导入画图工具
import matplotlib.pyplot as plt
#导入numpy
import pandas as pd

#生成一个等差数列
line = np.linspace(-5,5,200)

#画出非线性骄傲正图形表示
plt.plot(line,np.tanh(line),label = 'tanh')
plt.plot(line,np.maximum(line,0),label='relu')

#设置图注位置
plt.legend(loc='best')

#这只横纵轴标题
plt.xlabel('x')
plt.ylabel('rule(x) and tanh(x)')

#显示图形
plt.show()

我们有4种方法可以调节模型的复杂程度:

    第一种,调整神经网络每一个隐藏层上的节点数

    第二种,调节神经网络隐藏层的层数

    第三种,调节activation的方式

    第四种,通过调整alpha值来改变模型正则化的过程

参考:

https://zhuanlan.zhihu.com/p/63184325

"多层感知器"--MLP神经网络算法“  https://blog.csdn.net/a706769817/article/details/102063571

https://blog.csdn.net/weixin_39527292/article/details/110854877

神经网络几种常见的激活函数和用法:

https://blog.csdn.net/qq_29831163/article/details/89887655

四.反向传播与梯度下降

机器学习总结_第5张图片

最简单的理解,(随机)梯度下降基于梯度更新网络参数,最小化目标函数,从而训练网络。

反向传播则是用于计算梯度的,基于误差(目标函数)层层反传。

二者关系是梯度下降需要用到反向传播计算得到的梯度,梯度下降需要用反向传播算法实现

反向传播算法是计算Loss对各层参数的梯度,也就是多元函数求梯度的链式法则,换个说法而已。梯度下降法,是说已经知道梯度大小和方向了,要怎么更新梯度:更新的方向是是什么?更新的大量是多少?直观解释是“沿着梯度下降的方向走多远”。

机器学习总结_第6张图片

https://www.zhihu.com/question/311616761

https://blog.csdn.net/xiewenrui1996/article/details/89762809

五.聚类算法

聚类算法:就是把距离作为特征,通过自下而上的迭代方式(距离对比),快速地把一群样本分成几个类别的过程。

更严谨,专业一些的说法是:

将相似的对象归到同一个簇中,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。

机器学习总结_第7张图片

K-Means 聚类的步骤如下:

  1. 随机的选取K个中心点,代表K个类别;

  2. 计算N个样本点和K个中心点之间的欧氏距离;

  3. 将每个样本点划分到最近的(欧氏距离最小的)中心点类别中——迭代1;

  4. 计算每个类别中样本点的均值,得到K个均值,将K个均值作为新的中心点——迭代2;

  5. 重复步骤2、3、4;

  6. 满足收敛条件后,得到收敛后的K个中心点(中心点不再变化)。

K-Means 聚类可以用欧式距离,欧式距离很简单,二维平面就是两个点的距离公式,在多维空间里,假设两个样本为a(x1,x2,x3,x4...xn),b(y1,y2,y3,y4...yn),那么他们之间的欧式距离的计算公式是:

机器学习总结_第8张图片

K-Means的代码:

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=300, centers=4,
                       cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.show()

def draw(m_kmeans,X,y_pred,n_clusters):
    centers = m_kmeans.cluster_centers_
    print(centers)
    plt.scatter(X[:, 0], X[:, 1], c=y_pred, s=50, cmap='viridis')
    #中心点(质心)用红色标出
    plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5)
    print("Calinski-Harabasz score:%lf"%metrics.calinski_harabasz_score(X, y_pred) )
    plt.title("K-Means (clusters = %d)"%n_clusters,fontsize=20)
    plt.show()

from sklearn.cluster import KMeans
from sklearn import metrics

m_kmeans = KMeans(n_clusters=4)
m_kmeans.fit(X)
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
    n_clusters=4, n_init=10, n_jobs=None, precompute_distances='auto',
    random_state=None, tol=0.0001, verbose=0)
y_pred = m_kmeans.predict(X)
draw(m_kmeans,X,y_pred,4)

K-Means 聚类能使用的距离度量方法不仅仅是欧式距离,也可以使用曼哈顿距离、马氏距离,思想都是一样,只是使用的度量公式不同而已。

转自:https://mp.weixin.qq.com/s?__biz=MzA5NDIzNzY1OQ==&mid=2735619871&idx=1&sn=98f278dc21bed989809cea8dbe6427ca

 

六.机器学习:样本分布不均衡问题的处理

类别不平衡问题的定义

类别不平衡(class-imbalance)就是指分类任务中,不同类别的训练数据数目差别很大的情况。

这就是所谓类别不平衡问题

举个例子,样本里有998个反例,2个正例,如果一个模型对任何的新样本都预测为反例,那么它的精度为99.8%,虽然很高,但没有任何价值。

这种情况使用的基本策略是再缩放,具体方法则是采样。通过不同的采样方法来使类别达到平衡

自己在项目中拿到数据,大部分情况下都是自己切分训练集、测试集,对于训练集,经常会遇到正负样本比例很不均衡的情况,即偏斜类Skewed Class)问题,有些时候往往还很严重,比如数据量上负样本:正样本>=100,这是比较严重的偏斜类问题,下面针对这种问题,探讨一下:

1.对正样本过采样---容易造成过拟合

a.将正样本复制累加
经过验证,这种方式是有效的,通过复杂少数样本,提高了少数样本的recall,进入提高了auc
b.SMOTE算法或ADASYN(自适应综合过采样)
这里以SMOTE算法为例,SMOTE算法在sklearn中没有集成,需要单独下载lmblearn包,使用如下:

from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state=42)  #随机因子,每次随机生成不要和上次一样
X_res,y_res = sm.fit_sample(X_train,y_train)

2.对负样本欠采样 ---容易丢失重要信息

这种方式会减少很多负样本的信息,为了保留这种信息,将负样本按1k或500切分10份,每份分别与全量正样本进行进行训练得到分类器,然后集成学习assemble的方式进行组合成一个分类器

3.调整权重

在训练的时候调节权重:
a.对于xgboost,因为xgboost不属于sklearn,需调节scale_pos_weight参数值,实测结果——改善不大,需要自己不断尝试权重值;
b.针对sklearn中的分类方法,如svm,调节class_weight参数

对于正样本量足够、负样本不足的偏斜类问题,由于有足够的正样本,采用欠采样的方式就可以解决;

对于正样本量严重不足、负样本过多的偏斜类问题,由于严重缺少正样本,可以采用上述的三种方式解决,如果采用调整权重的方式,权重的值需要不断尝试,若采用过采样方式,可以通过单纯的复制少数样本数据,也可以通过SMOTE算法生成少数样本,大家都可以尝试。
https://blog.csdn.net/hzk1562110692/article/details/89280555

https://blog.csdn.net/lolgenius/article/details/104499999

七.jieba中文分词

import jieba 
print(" ".join(jieba.cut("我今天早上去吃了一些好吃的,你是怎么想的西安工程大学北京大学")))

https://blog.csdn.net/yellow_python/article/details/80559586

八.推荐系统传统召回是怎么实现热门item的打压

先确定是否需要打压。 本来就是多路召回,工业界大部分召回阶段不需要打压。像抖音这种还嫌热点太少,会用流量池打造爆款,体验上来看,不同的人推荐内容就很相似了。 如果非要打压的话,那就对热点样本降权吧。 并且swing 也可以对热点样本降权吧,计算用户cf时,分母就和样本被点击次数正相关的。 在融合排序阶段,会考虑多样性,避免信息茧房。

CF类的算法里面应该挺多的,在算相似度时,惩罚一下。或者对热门商品的行为采样

https://www.zhihu.com/question/426543628

九.一文带你了解推荐系统——常用召回和排序技术

这篇文章是写的真好,强烈推荐

https://www.163.com/dy/article/FA48UMIA0532E0UF.html

你可能感兴趣的:(机器学习与算法)