目录
一.连续特征的离散化:在什么情况下将连续的特征离散化之后可以获得更好的效果?
二.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()是标签编码,即是对不连续的数字或者文本进行编号,转换成连续的数值型变量,例如
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)
完整的机器学习流程图
参考:
https://www.cnblogs.com/king-lps/p/7846414.html
https://www.tqwba.com/x_d/jishu/98776.html
神经网络顾名思义,就像我们人脑中的神经元一样,为了让机器来模拟人脑,我们在算法中设置一个个节点,在训练模型时,输入的特征与预测的结果用节点来表示,系数w(又称为"权重")用来连接节点,神经网络模型的学习就是一个调整权重的过程,训练模型一步步达到我们想要的效果.
三大神经网络:
"多层感知器",即MLP算法,泛称为神经网络 -DNN
卷积神经网络--CNN
递归神经网络-RNN
神经网络主要有三个基本要素:权重、偏置和激活函数
权重:神经元之间的连接强度由权重表示,权重的大小表示可能性的大小
偏置:偏置的设置是为了正确分类样本,是模型中一个重要的参数,即保证通过输入算出的输出值不能随便激活。
激活函数:起非线性映射的作用,其可将神经元的输出幅度限制在一定范围内,一般限制在(-1~1)或(0~1)之间。最常用的激活函数是Sigmoid函数,其可将(-∞,+∞)的数映射到(0~1)的范围内。
激活函数还有tanh和ReLU等函数,
tanh是Sigmoid函数的变形,tanh的均值是0,在实际应用中有比Sigmoid更好的效果;
ReLU是近来比较流行的激活函数,当输入信号小于0时,输出为0;当输入信号大于0时,输出等于输入;具体采用哪种激活函数需视具体情况定。
#导入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
最简单的理解,(随机)梯度下降基于梯度更新网络参数,最小化目标函数,从而训练网络。
反向传播则是用于计算梯度的,基于误差(目标函数)层层反传。
二者关系是梯度下降需要用到反向传播计算得到的梯度,梯度下降需要用反向传播算法实现
反向传播算法是计算Loss对各层参数的梯度,也就是多元函数求梯度的链式法则,换个说法而已。梯度下降法,是说已经知道梯度大小和方向了,要怎么更新梯度:更新的方向是是什么?更新的大量是多少?直观解释是“沿着梯度下降的方向走多远”。
https://www.zhihu.com/question/311616761
https://blog.csdn.net/xiewenrui1996/article/details/89762809
聚类算法:就是把距离作为特征,通过自下而上的迭代方式(距离对比),快速地把一群样本分成几个类别的过程。
更严谨,专业一些的说法是:
将相似的对象归到同一个簇中,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离。
K-Means 聚类的步骤如下:
随机的选取K个中心点,代表K个类别;
计算N个样本点和K个中心点之间的欧氏距离;
将每个样本点划分到最近的(欧氏距离最小的)中心点类别中——迭代1;
计算每个类别中样本点的均值,得到K个均值,将K个均值作为新的中心点——迭代2;
重复步骤2、3、4;
满足收敛条件后,得到收敛后的K个中心点(中心点不再变化)。
K-Means 聚类可以用欧式距离,欧式距离很简单,二维平面就是两个点的距离公式,在多维空间里,假设两个样本为a(x1,x2,x3,x4...xn),b(y1,y2,y3,y4...yn),那么他们之间的欧式距离的计算公式是:
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,这是比较严重的偏斜类问题,下面针对这种问题,探讨一下:
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)
这种方式会减少很多负样本的信息,为了保留这种信息,将负样本按1k或500切分10份,每份分别与全量正样本进行进行训练得到分类器,然后集成学习assemble的方式进行组合成一个分类器
在训练的时候调节权重:
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
import jieba
print(" ".join(jieba.cut("我今天早上去吃了一些好吃的,你是怎么想的西安工程大学北京大学")))
https://blog.csdn.net/yellow_python/article/details/80559586
先确定是否需要打压。 本来就是多路召回,工业界大部分召回阶段不需要打压。像抖音这种还嫌热点太少,会用流量池打造爆款,体验上来看,不同的人推荐内容就很相似了。 如果非要打压的话,那就对热点样本降权吧。 并且swing 也可以对热点样本降权吧,计算用户cf时,分母就和样本被点击次数正相关的。 在融合排序阶段,会考虑多样性,避免信息茧房。
CF类的算法里面应该挺多的,在算相似度时,惩罚一下。或者对热门商品的行为采样
https://www.zhihu.com/question/426543628
这篇文章是写的真好,强烈推荐
https://www.163.com/dy/article/FA48UMIA0532E0UF.html