数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已html
什么是特征工程:java
帮助咱们使得算法性能更好发挥性能而已python
sklearn主要用于特征工程
pandas主要用于数据清洗、数据处理算法
特征工程包含以下3个内容:编程
一、特征抽取/特征提取数组
|__>字典特征抽取,应用DiceVectorizer实现对类别特征进行数值化、离散化浏览器
|__>文本特征抽取,应用CounterVertorize/TfIdfVectorize实现对文本特征数值化app
|__>图像特征抽取(深度学习)框架
二、特征预处理机器学习
|_>归一化,应用MaxmixScaler,根据最小最大值进行放缩,默认范围0-1,容易受到异常值的影响,稳定性差,适合小规模
|_>标准化,应用StandardScaler, 数据处理到指定的范围内,默认0~1
三、特征降维
|_>特征选择
|_>PCI(主要内容分析)
咱们常说的机器学习算法实际上就是咱们统计学上的统计方法也就是咱们数学上的数学公式
即 机器学习算法--》统计方法--》数学公式
字典特征抽取的应用场景:
1)pclass, sex 数据集当中类别特征比较多
一、将数据集的特征 转换为字典类型
二、利用DictVectorizer转换为二维数组
2)自己拿到的数据就是字典类型
1- 字典特征提取:
当咱们调用sklearn.feature_extraction.DictVectorizer(sparse=True,…)的时候,实际上就是初始化了一个父类的转换器对象,而后调用实例进行fit_transform(X),进行字典和数值的转换。
(下图)有多少行数据就有多少个向量(有方向和大小),向量在计算机中以矩阵存储(二维数组),而矩阵的行和列均可以看作一个一维数组。下图中一行数据能够看作一个向量,n个样本有n个向量,即将字典转换为了计算机识别的二维数组。每个样本有2个特征(城市+temperature),正常应该返回一个3行2列的矩阵,可是字典特征抽取后,样本量没有变(3个样本),可是特征量变成了4个(当特征中有类别的时候,要想表示成数值,又想要公平的表示数据,咱们采用one-hot编码,有3个类别,就占用3列,若是是北京,则第二列的特征值就是1,最后添加上temperature就是4个特征了)。
字典特征抽取DEMO:
from sklearn.feature_extraction.dict_vectorizer import DictVectorizer # 字典特征提取 def dic_demo(): data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}] # 一、实例化一个转换器对象 # transform = DictVectorizer(sparse=True) # 默认开启稀疏矩阵 transform = DictVectorizer(sparse=False) # 默认sparse=True, # 二、调用fit_transform() new_data = transform.fit_transform(data) # 三、获取特征名称 print("特征名字:\n", transform.get_feature_names()) # 特征名字:['city=上海', 'city=北京', 'city=深圳', 'temperature'] print('转换后的结果:\n', new_data) ''' # sparse=True时候的new_data的值:返回的new_data是一个sparse的稀疏矩阵 (0, 1) 1.0 (0, 3) 100.0 (1, 0) 1.0 (1, 3) 60.0 (2, 2) 1.0 (2, 3) 30.0 # sparse=True时候的new_data的值,返回的是一个二维数组 [[ 0. 1. 0. 100.] [ 1. 0. 0. 60.] [ 0. 0. 1. 30.]] # 总结: 稀疏矩阵将非零值按位置表示出来,这样作能够节省内存 - 提升加载效率 ''' if __name__ == '__main__': dic_demo()
结果截图:
附: one-hot编码:
对特征中的类别信息,为了公平的表示每一组样本数据,咱们处理的时候,就是根据类别进行划分,样本中几个类别就有几列,是这个数据则置该列的数值为1,不然为0
2- 文本特征提取:
文本特征提取就是将单词、字母、短语做为主要的特征词进行特征提取
能够利用以下方法统计:
1. from sklearn.feature_extraction.text import CountVectorizer ==》 根据分词进行数量统计继续文本分类
2. from sklearn.feature_extraction.text import TfidfVectorizer ==》 根据文章出现的词的占比(重要程度)进行文本分类
CountVectorizer:统计的是文本中出现的特征词次数,stop_words停用的停词表,toarray()能够转换为二维数组
文本特征提取—>英文的测试DEMO
from sklearn.feature_extraction.text import CountVectorizer # 文本特征提取 def text_count_demo(): data = ["life is short,i like like python", "life is too long, i dislike python"] # 一、实例化一个转换器类 transfer = CountVectorizer() # transfer = CountVectorizer(stop_words=["is", "too"]) ''' 不添加stop_words的效果:transfer = CountVectorizer() data_new: [[0 1 1 2 0 1 1 0] [1 1 1 0 1 1 0 1]] 特征名字: ['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too'] 添加stop_words的效果: transfer = CountVectorizer(stop_words=["is", "too"]) data_new: [[0 1 2 0 1 1] [1 1 0 1 1 0]] 特征名字: ['dislike', 'life', 'like', 'long', 'python', 'short'] ''' # 二、调用fit_transform data_new = transfer.fit_transform(data) # data_new返回的是一个sparse矩阵, print("矩阵_data_new:\n", data_new) # data_new.toarray()返回的是一个二维数组 print("数组_data_new:\n", data_new.toarray()) ''' 矩阵_data_new: (0, 5) 1 (0, 3) 2 (0, 6) 1 (0, 1) 1 (0, 2) 1 (1, 0) 1 (1, 4) 1 (1, 7) 1 (1, 5) 1 (1, 1) 1 (1, 2) 1 数组_data_new.toarray(): [[0 1 1 2 0 1 1 0] [1 1 1 0 1 1 0 1]] ''' print("特征名字:\n", transfer.get_feature_names()) return None if __name__ =='__main__': text_count_demo()
文本特征提取—>中文的手动分词DEMO效果(这里是手动用空格进行的中文分词,麻烦):
from sklearn.feature_extraction.text import CountVectorizer # 中文的须要进行分词,不然是以整句做为分词的 def chinese_text_count_demo(): data = ["我爱北京天安门", "天安门上太阳升"] # data = ["我 爱 北京 天安门", "天安门 上 太阳 升"] # 添加了空格的中文分词 ''' 未添加空格的中文分词: data_new: [[0 1] [1 0]] 特征名字: ['天安门上太阳升', '我爱北京天安门'] 添加了空格的中文分词: [[1 1 0] [0 1 1]] 特征名字: ['北京', '天安门', '太阳'] ''' # 一、实例化一个转换器类 transfer = CountVectorizer() # 二、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new.toarray()) print("特征名字:\n", transfer.get_feature_names()) return None if __name__ =='__main__': chinese_text_count_demo()
文本特征提取—>中文的自动分词统计的DEMO效果
from sklearn.feature_extraction.text import CountVectorizer import jieba # pip3 install jieba # 利用jieba能够进行jieba分词 def cut_word(text): """ 进行中文分词:"我爱北京天安门" --> "我 爱 北京 天安门" :param text: :return: """ return " ".join(list(jieba.cut(text))) # jieba.cut(text)返回的是一个生成器对象,须要转换为迭代器 def auto_chinese_text_count_demo(): data = ["一种仍是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,因此每一个人不要放弃今天。", "咱们看到的从很远星系来的光是在几百万年以前发出的,这样当咱们看到宇宙时,咱们是在看它的过去。", "若是只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与咱们所了解的事物相联系。"] data_new = [] for sent in data: data_new.append(cut_word(sent)) # print(data_new) # 一、实例化一个转换器类 transfer = CountVectorizer(stop_words=["一种", "因此"]) # 二、调用fit_transform data_final = transfer.fit_transform(data_new) print("data_new:\n", data_final.toarray()) print("特征名字:\n", transfer.get_feature_names()) return None if __name__ =='__main__': auto_chinese_text_count_demo()
附:”了解”在第三个数据中出现了4次。
CountVectorizer仅仅是根据特征名字出现的次数进行的文本分类,若是一个文本中的语气词出现了不少次,那最终统计的结果也不是很合适
2-文本特征抽取--TfidfVevtorizer
写在前面:TfidfVevtorizer对分类机器学习算法进行文章分类中前期数据处理很重要
在某一个类别的文章中,某些词出现的次数不少,可是在其余类别的文章当中出现不多,咱们利用他们的重要程度进行分类,以下图咱们就能看他们介绍的内容分别是共享车和经济证券。
TfidfVevtorizer衡量的就是一个词在文章中的重要程度
TfidfVevtorizer = TF + IDF
--> TF - 词频(term frequency,tf)
--> IDF - 逆向文档频率(inverse document frequency, idf)
TF-IDF文本特征提取:
举个例子:
背景:
假设现有两个关键词 “经济”,“很是”。
如今咱们的基础数据是1000篇文章的语料库。其中100篇文章"很是"一词出现的频率很高,10篇文章“经济”一词出现的频率很高。
计算公式
TF(词频) = 出现的频率/总词数
IDF(逆向文档频率)= log 10 文件总数目/包含该词语的文件数目
TF-IDF = TF * IDF
要求计算:
现有两篇文章
文章A(100词) : 10次“经济” TF-IDF:0.2
tf: 10/100 = 0.1
idf:lg 1000/10 = 2
文章B(100词) : 10次“很是” TF-IDF:0.1
tf:10/100 = 0.1
idf: log 10 1000/100 = 1
TF-IDF处理的API
TF-IDF处理的文本数据DEMO
from sklearn.feature_extraction.text import TfidfVectorizer import jieba # pip3 install jieba # 利用jieba能够进行jieba分词 def cut_word(text): """ 进行中文分词:"我爱北京天安门" --> "我 爱 北京 天安门" :param text: :return: """ return " ".join(list(jieba.cut(text))) # jieba.cut(text)返回的是一个生成器对象,须要转换为迭代器 def tf_idf_demo(): data = ["一种仍是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,因此每一个人不要放弃今天。", "咱们看到的从很远星系来的光是在几百万年以前发出的,这样当咱们看到宇宙时,咱们是在看它的过去。", "若是只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与咱们所了解的事物相联系。"] data_new = [] for sent in data: data_new.append(cut_word(sent)) # print(data_new) # 一、实例化一个转换器类 transfer = TfidfVectorizer(stop_words=["一种", "因此"]) # 二、调用fit_transform data_final = transfer.fit_transform(data_new) print("data_new:\n", data_final.toarray()) print("特征名字:\n", transfer.get_feature_names()) return None if __name__ =='__main__': tf_idf_demo()
特征预处理:
经过一些转换函数将特征数据转换为更适合算法模型的特征数据过程。
数值型数据的无量纲化(无量纲化,数学名词,是不一样规格的数据转换到同一规格):
--》 归一化: 根据最小最大值进行放缩,默认范围0-1,容易受到异常值的影响,稳定性差,只适合小规模的数据场景
--》 标准化: 原始数据变化到0-1直接
特征预处理API:
sklearn.preprocessing
1. 归一化
举个例子:
归一化的Demo
from sklearn.preprocessing import MinMaxScaler import pandas as pd # pandas是用于读取文本文件 # 归一化 def minmax_demo(): """ pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而建立的。 Pandas 归入了大量库和一些标准的数据模型, 提供了高效地操做大型数据集所需的工具。 pandas提供了大量能使咱们快速便捷地处理数据的函数和方法。 """ # 一、获取数据 data = pd.read_csv("dating.txt") data = data.iloc[:, :3] # 目的是进行归一化,不须要目标值,txt文件第四列值是target print("data:\n", data) # 读取的csv文件 # 二、实例化一个转换器类 transfer = MinMaxScaler(feature_range=[2, 3]) # 默认的feature_range是[0, 1] # 三、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new) return None if __name__ == '__main__': minmax_demo()
dating.txt ==> 详见附件
milage,Liters,Consumtime,target 40920,8.326976,0.953952,3 14488,7.153469,1.673904,2 26052,1.441871,0.805124,1 75136,13.147394,0.428964,1 38344,1.669788,0.134296,1 72993,10.141740,1.032955,1 35948,6.830792,1.213192,3 42666,13.276369,0.543880,3 67497,8.631577,0.749278,1 35483,12.273169,1.508053,3 50242,3.723498,0.831917,1 63275,8.385879,1.669485,1 5569,4.875435,0.728658,2 51052,4.680098,0.625224,1 77372,15.299570,0.331351,1 43673,1.889461,0.191283,1 61364,7.516754,1.269164,1 69673,14.239195,0.261333,1 15669,0.000000,1.250185,2 28488,10.528555,1.304844,3 6487,3.540265,0.822483,2 37708,2.991551,0.833920,1 22620,5.297865,0.638306,2 28782,6.593803,0.187108,3 19739,2.816760,1.686209,2 36788,12.458258,0.649617,3 5741,0.000000,1.656418,2 28567,9.968648,0.731232,3
二、标准化
标准化的测试Demo
from sklearn.preprocessing import StandardScaler import pandas as pd # pandas是用于读取文本文件 # 标准化 def standard_mode(): """ pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而建立的。 Pandas 归入了大量库和一些标准的数据模型, 提供了高效地操做大型数据集所需的工具。 pandas提供了大量能使咱们快速便捷地处理数据的函数和方法。 """ # 一、获取数据 data = pd.read_csv("dating.txt") data = data.iloc[:, :3] # 目的是进行归一化,不须要目标值,txt文件第四列值是target print("data:\n", data) # 读取的csv文件 # 二、实例化一个转换器类 transfer = StandardScaler() # 默认的feature_range是[0, 1] # 三、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new) return None if __name__ == '__main__': standard_mode()
另: dating.txt详见附件
降维实际上就是下降特征的个数,最终的结果就是特征和特征之间不相关。
降维的2种方法
什么是特征选择
特征选择的2种方法(过滤式 + 嵌入式)
特征选择的2种方式:
过滤式:
方差选择法: 能够过滤掉低方差的数据,例如用鸟类是否能够飞做为特征值是不合适的,此时的方差为0。
相关系数法:目标是去除冗余,肯定特征与特征之间的相关性。
嵌入式:
决策树:
正则化:
深度学习:
降维方式一:特征选择--过滤式 --低方差过滤
删除低方差特征Demo
from sklearn.feature_selection import VarianceThreshold from scipy.stats import pearsonr import pandas as pd def variance_demo(): """ 过滤低方差特征 :return: """ # 一、获取数据 data = pd.read_csv("factor_returns.csv") data = data.iloc[:, 1:-2] # 全部行都要,列不显示最后2行 print("data:\n", data) # 二、实例化一个转换器类 transfer = VarianceThreshold(threshold=10) # threshold表明临界值为10,默认为0 # 三、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new, data_new.shape) return None if __name__ == '__main__': variance_demo()
factor_returns.csv ==> 详见附件
index,pe_ratio,pb_ratio,market_cap,return_on_asset_net_profit,du_return_on_equity,ev,earnings_per_share,revenue,total_expense,date,return 0,000001.XSHE,5.9572,1.1818,85252550922.0,0.8008,14.9403,1211444855670.0,2.01,20701401000.0,10882540000.0,2012-01-31,0.027657228229937388 1,000002.XSHE,7.0289,1.588,84113358168.0,1.6463,7.8656,300252061695.0,0.326,29308369223.2,23783476901.2,2012-01-31,0.08235182370820669 2,000008.XSHE,-262.7461,7.0003,517045520.0,-0.5678,-0.5943,770517752.56,-0.006,11679829.03,12030080.04,2012-01-31,0.09978900335112327 3,000060.XSHE,16.476,3.7146,19680455995.0,5.6036,14.617,28009159184.6,0.35,9189386877.65,7935542726.05,2012-01-31,0.12159482758620697 4,000069.XSHE,12.5878,2.5616,41727214853.0,2.8729,10.9097,81247380359.0,0.271,8951453490.28,7091397989.13,2012-01-31,-0.0026808154146886697 5,000100.XSHE,10.796,1.5219999999999998,17206724233.0,2.245,7.7394,66034033386.1,0.0974,43883757748.0,43092263405.0,2012-01-31,0.13795588072275808 6,000402.XSHE,8.1032,1.0078,18253291248.0,3.2233,10.3965,56511787330.1,0.6,7303544153.27,5440677926.67,2012-01-31,0.08457869004968227 7,000413.XSHE,192.5234,18.3692,4270450000.0,-0.6423,-1.0375,4363236328.83,-0.0059,62630800.67,64784767.7,2012-01-31,0.11926833305744075
降维方式一:一、特征选择--过滤式--相关系数
过滤低方差特征 + 计算相关系数DEMO
from sklearn.feature_selection import VarianceThreshold from scipy.stats import pearsonr import pandas as pd def variance_demo(): """ 过滤低方差特征 + 计算相关系数 :return: """ # 一、获取数据 data = pd.read_csv("factor_returns.csv") data = data.iloc[:, 1:-2] # 全部行都要,列不显示最后2行 print("data:\n", data) # 二、实例化一个转换器类 transfer = VarianceThreshold(threshold=10) # threshold表明临界值为10,默认为0 # 三、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new, data_new.shape) # 计算某两个变量之间的相关系数 r1 = pearsonr(data["pe_ratio"], data["pb_ratio"]) print("相关系数:\n", r1) r2 = pearsonr(data['revenue'], data['total_expense']) print("revenue与total_expense之间的相关性:\n", r2) return None if __name__ == '__main__': variance_demo()
过滤低方差特征 + 计算相关系数 + 画图DEMO
from sklearn.feature_selection import VarianceThreshold from scipy.stats import pearsonr import pandas as pd import matplotlib.pyplot as plt def variance_demo(): """ 过滤低方差特征 + 计算相关系数 :return: """ # 一、获取数据 data = pd.read_csv("factor_returns.csv") data = data.iloc[:, 1:-2] # 全部行都要,列不显示最后2行 print("data:\n", data) # 二、实例化一个转换器类 transfer = VarianceThreshold(threshold=10) # threshold表明临界值为10,默认为0 # 三、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new, data_new.shape) # 计算某两个变量之间的相关系数 r1 = pearsonr(data["pe_ratio"], data["pb_ratio"]) print("相关系数:\n", r1) r2 = pearsonr(data['revenue'], data['total_expense']) print("revenue与total_expense之间的相关性:\n", r2) # 离散图 plt.figure(figsize=(20, 9), dpi=100) plt.scatter(data['revenue'], data['total_expense']) plt.show() return None if __name__ == '__main__': variance_demo()
特征与特征之间相关性很高,能够采起:
1)选取其中一个
2)加权求和
3)主成分分析
降维方式二:主成分分析(PCA)
PCI用到的主要方法
PCA降维DEMO
from sklearn.decomposition import PCA def pca_demo(): """ PCA降维 :return: """ data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]] # 一、实例化一个转换器类 # transfer = PCA(n_components=2) # 整数:将3维转换为2维 transfer = PCA(n_components=0.95) # 小数:保留95%的信息 # 二、调用fit_transform data_new = transfer.fit_transform(data) print("data_new:\n", data_new) return None
案例:探究用户对物品分类的喜爱 --instacart市场篮子分析案例
案例分析:探究用户对物品类别的喜爱细分:
首先咱们须要【用户,user_id】和【物品类别, aisle】2个关键参数
1)须要将user_id和aisle放在同一个表中 –> 合并
2)找到user_id和aisle关系 --> 交叉表和透视表
3)特征冗余过多 --> PCA降维
安装Anaconda3,点击下载
安装可参考:https://www.jianshu.com/p/026a2c43b081
点击运行:
此时会帮咱们打开一个浏览器界面:点击new->Python3,而后就能够进行编程了(Ctrl + Enter,进行文件变异)
案例DEMO:
import pandas as pd from sklearn.decomposition import PCA def demo(): ''' 分析: 一、 获取数据 二、 合并表 三、 找到UserId和Iias之间的关系 四、 进行PCA降惟 :return: ''' # 1. 获取数据 aisles = pd.read_csv("F:\instacart\\aisles.csv") orders = pd.read_csv("F:\instacart\\orders.csv") order_products__prior = pd.read_csv("F:\instacart\\order_products__prior.csv") products = pd.read_csv("F:\instacart\\products.csv") ''' 2 合并表(目标是UserID和Iisas进行机器学习) order_products__prior.csv: 订单与商品信息 字段:order_id, product_id, add_to_cart_order, reordered products.csv:商品信息 字段:product_id, product_name, aisle_id, department_id orders.csv:用户的订单信息 字段:order_id,user_id,eval_set,order_number,…. aisles.csv:商品所属具体物品类别 字段: aisle_id, aisle ''' # 合并aisles和products aisle的aisle_id tab1 = pd.merge(aisles, products, on=["aisle_id", "aisle_id"]) # 合并tab1和order_products__prior的product_id tab2 = pd.merge(tab1, order_products__prior, on=['product_id', 'product_id']) # 合并tab2和orders的order_id tab3 = pd.merge(tab2, orders, on=['order_id', 'order_id']) # 三、 找到UseID和aisle直接的关系(交叉表) table = pd.crosstab(tab3['user_id'], tab3['aisle']) data = table[:100] # 四、 下降维度 # 4-1:实例化一个转换器对象,保留95%的信息 transfer = PCA(n_components=0.95) # 4-2: 调用fit_transform() data_new = transfer.fit_transform(data) # 五、结果 print('data_new', data_new) # 100个样本数据下降维度后的特征值 print('data_new.shape', data_new.shape) # 100个数据有100多个特征,降维后剩余19个
表合并过程:
结果:
代码和资料下载:
连接:https://pan.baidu.com/s/14vBcB3o5wjef_7lYb7WrSQ 提取码:td8n