[sklearn] 特征工程
一.字典数据抽取
def dictvec():"""字典数据抽取:return: None"""# 实例化# sparse改为True,输出的是每个不为零位置的坐标,稀疏矩阵可以节省存储空间dict = DictVectorizer(sparse=False) #矩阵中存在大量的0,sparse存储只记录非零位置,节省空间# 调用fit_transformdata = dict.fit_transform([{'city': '北京', 'temperature': 100},{'city': '上海', 'temperature': 60},{'city': '深圳', 'temperature': 30}])print(dict.get_feature_names_out()) # 字典中的一些类别数据,分别进行转换成特征print(data)print('-' * 50)#print(dict.inverse_transform(data)) #去看每个特征代表的含义,逆转回去return Nonedictvec()
输出结果:
按照顺序,比如第一个样本city为北京,那么对应北京列的值为1,其它为0.
二.词提取(英文)
def couvec():# 实例化CountVectorizer# max_df, min_df整数:指每个词的所有文档词频数不小于最小值,出现该词的文档数目小于等于max_df# max_df, min_df小数:每个词的次数/所有文档数量# min_df=2vector = CountVectorizer()# 调用fit_transform输入并转换数据#三个样本res = vector.fit_transform(["life is short,i like python life","life is too long,i dislike python","life is short"])# 打印结果,把每个词都分离了print(vector.get_feature_names_out())# 对照feature_names,标记每个词出现的次数print(res.toarray()) #print(vector.inverse_transform(res))couvec()
输出结果:比如,第一行表示第一个样本中各个词出现的次数,单个字符不统计
三.词提取(中文)
def countvec():"""对文本进行特征值化,单个汉字单个字母不统计,因为单个汉字字母没有意义:return: None"""cv = CountVectorizer()data = cv.fit_transform(["人生苦短,我 喜欢 python", "人生漫长,不用 python"])print(cv.get_feature_names_out())#print(data)print(data.toarray())return Nonecountvec()
输出结果: 这里样本必须每个词要间隔空格,下面会讲使用jieba库自动分词
四.词提取(jieba库)
def cutword():#这里小例子手动输入样本值con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")# 转换成列表content1 = list(con1)content2 = list(con2)content3 = list(con3)# 把列表转换成字符串c1 = ' '.join(content1)c2 = ' '.join(content2)c3 = ' '.join(content3)return c1, c2, c3def hanzivec():"""中文特征值化:return: None"""#为了举例,在函数中已经固定好样本c1, c2, c3 = cutword()#print(c1, c2, c3)cv = CountVectorizer()data = cv.fit_transform([c1, c2, c3])#得到分词类别print(cv.get_feature_names_out())#打印矩阵形式print(data.toarray())return Nonehanzivec()
输出结果:jieba库会根据中文的习惯来进行分词
五.使用tfidf值
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度
公式:重要性=tf*idf
其中
tf:词的频率出现次数
idf:lg(总文档数量/该词出现的文档数量)
# 规范{'l1','l2'},默认='l2'
# 每个输出行都有单位范数,或者:
#
# 'l2':向量元素的平方和为 1。当应用 l2 范数时,两个向量之间的余弦相似度是它们的点积。
#
# 'l1':向量元素的绝对值之和为 1。参见preprocessing.normalize。# smooth_idf布尔值,默认 = True
# 通过在文档频率上加一来平滑 idf 权重,就好像看到一个额外的文档包含集合中的每个术语恰好一次。防止零分裂。def tfidfvec():"""中文特征值化,计算tfidf值:return: None"""c1, c2, c3 = cutword()#print(c1, c2, c3)#print(type([c1, c2, c3]))tf = TfidfVectorizer()data = tf.fit_transform([c1, c2, c3])print(tf.get_feature_names_out())#print(type(data))print(data.toarray())return Nonetfidfvec()
输出结果:
六.特征处理
参数:自己设置的参数
超参数:模型自己训练的时候变化的参数
为什么要特征处理?
为了防止特征本来的数值就很大,对输出的影响很大,所以要进行特征处理
1.归一化
好处:容易更快的通过梯度下降找到最优解
sklearn接口
def mm():"""归一化处理:return: NOne"""# 归一化容易受极值的影响,范围到0.1之间,也可以设置其它范围mm = MinMaxScaler(feature_range=(0, 1))data = mm.fit_transform([[90, 2, 10, 40], [60, 4, 15, 45], [75, 3, 13, 46]])print(data)return Nonemm()
输出结果:比如第一个1,是90-60/90-60=1
注意:这里max 和min是针对每列,因为每列是一种特征
2.标准化
特点:通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
mean是均值,σ是标准差
def stand():"""标准化缩放,不是标准正太分布,只均值为0,方差为1的分布:return:"""std = StandardScaler()data = std.fit_transform([[1., -1., 3.], [2., 4., 2.], [4., 6., -1.]])print(data)print(std.mean_) print(std.var_)#print(std.n_samples_seen_) # 样本数print('-' * 50)#这里是拿得到的结果来验证是否满足均值为0,方差为1data1 = std.fit_transform([[-1.06904497, -1.35873244, 0.98058068],[-0.26726124, 0.33968311, 0.39223227],[1.33630621, 1.01904933, -1.37281295]])print(data1) #这个并不是我们想看的,没意义# 均值print(std.mean_)# 方差print(std.var_)# 样本数#print(std.n_samples_seen_)return Nonestand()
结果:‘------’上方是结果,下方是拿到结果反向验证是否符合均值为0,方差为1
3.缺失值处理
#下面是填补,针对删除,可以用pd和np
def im():"""缺失值处理:return:NOne"""# NaN, nan,缺失值必须是这种形式,如果是?号(或者其他符号),就要replace换成这种im = SimpleImputer(missing_values=np.nan, strategy='mean')data = im.fit_transform([[1, 2], [np.nan, 3], [7, 6], [3, 2]]) #(1+7+3)/3 = 3.666 print(data)return Noneim()
输出结果:strategy = mean指定了使用均值来填补,比如(1+7+3)/3 = 3.666 注意这里分母不包含nan的数量
4.删除方差低的特征
因为方差低,说明此特征的区别度很小
def var():"""特征选择-删除低方差的特征:return: None"""#默认只删除方差为0,threshold是方差阈值,删除比这个值小的那些特征var = VarianceThreshold(threshold=1)data = var.fit_transform([[0, 2, 0, 3],[0, 1, 4, 3],[0, 1, 1, 3]])print(data)# 获得剩余的特征的列编号print('The surport is %s' % var.get_support(True))return Nonevar()
输出结果:删除了方差低于阈值1的列,
5.PCA算法降维
算法思想详细参考:降维算法之PCA:从原理到应用,8000多字,助你彻底理解!_pca降维-CSDN博客
def pca():"""主成分分析进行特征降维:return: None"""# n_ components:小数 0~1 90% 业界选择 90~95%## 整数 减少到的特征数量pca = PCA(n_components=1)data = pca.fit_transform([[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]])print(data)return Nonepca()
输出结果:设置n_components=1 即降到1维