基础
1. 泛化是核心
机器学习最基本的特征之一是,算法必须从训练的数据中泛化出该领域中所有不可见场景的完整领域,以便在使用模型时能够做出正确的推断。这个泛化的过程需要我们用来训练模型的数据有一个我们希望算法去学习的,像样的和可靠的映射。数据的质量越好,表达能力越高,模型就越容易理解从输入到输出的未知的和基本的“真实”映射。泛化是指从某种精确的东西转向某种广泛的东西。
机器学习算法是从历史场景中自动简化的技术。它们有能力在更大的数据量和更快的速度上进行泛化。
所有机器学习初学者最常犯的错误就是对训练数据进行测试,然后看起来像是成功了。如果在新数据上尝试所得到分类器,它通常不会比随机猜测更好。所以,如果你想要开发一个分类器,一定要留一些数据做测试。同时,用你的分类器对测试数据进行测试。
2. 学习=表示+评估+优化
机器学习算法分为 3 个部分,表示、评估和优化
表示:数据需要以合适的算法形式输入。对于文本分类,可以从全文输入中提取特征,并将其变为 bag-of-words 的表示形式。相反,选择一种表示方法与选择它可能学习的分类器集是同义词。这个集合称为学习者的假设空间。
评估:这是一个帮助我们理解我们正在做什么的度量。需要一个评估过程来区分好分类器和不好的分类器。如果你可以给测试集预测出一个数字,例如测试集的大小为 n,在这里,你可以计算平均绝对误差,甚至可以选择使用均方根误差。
优化:它是指寻找方法来选择不同的技术来优化它的过程。例如,我们可以简单地尝试假设空间中的每一个假设。我们也可能选择使用更智能的技术来尝试最有利的假设。同时,当我们进行优化时,我们可以利用评价函数来了解这个特定的假设是否成立。如果评价函数有多个最优值,则优化技术允许用户了解更多关于所创建分类器的信息。首先,初学者应该从现成的优化器开始,然后再转向定制设计的优化器。
3. 只有数据是不够的!
泛化是主要目的,但主要关注的是,无论数量多少,仅有数据是不够的。但是,幸运的是,我们想掌握的功能并不是从所有可计算的功能中统一得出的!即使是最一般的假设(包括平滑度,具有类似类的相似示样本,不充分的依存关系或受限制的复杂度)也足以正常运行,这是使机器学习如此强大的主要原因之一。基本上,所有初学者都联合了解大数据来制作应用程序。
4. 小心过拟合
如果数据不充分,不能完全训练好一个分类器,我们可能最终得到的是只在训练集上有用的分类器。这个问题被称为 overfitting,它被认为是 ML 的一个麻烦事。发现自己的模型过拟合了是有用的,但并不能解决这个问题。你得想办法摆脱它。幸运的是,你有很多选择去尝试。交叉验证有助于防止过拟合。训练更多的数据,正则化,删除特征,早期停止,集成是一些其他的防止过拟合的方法。
5. 特征工程是成功的关键
特征工程是利用数据的核心领域知识来开发使机器学习算法更好工作的特征的技术。如果处理得当,它可以通过从原始数据中开发特征来增强算法的预测能力。这些特征简化了整个机器学习过程。利用几个独立的特征,很好地与类相关,然后让学习变得容易。
6. 准确性&简单性是不一样的
奥卡姆剃刀(Occam’s razor)精辟地指出,实体的增加不应超出要求。这意味着两个分类器有相似的训练误差,两个分类器中较简单的可能有最低的测试误差。每一个机器学习项目都应该以你希望回答的业务问题为目标。你应该从制定分析的主要成功原则开始。
数据观察
- 数据类型:结构化数据非结构化数据
- 数据类型:定量数据、定性数据(定性数据、定序、定序、定比)
- 数据清洗:日期转化、空值处理、标准化、归一化、
数据清洗
- NumPy 库提供数字向量和矩阵操作。Pandas 是一个强大的数据框架,是 Python 中数据科学的基石。Scikit-learn 是一个通用机器学习软件包,涵盖了广泛的模型和特征变换器。Matplotlib 和 Seaborn 的样式库提供了绘图和可视化。
- 特征是原始数据的数学表示。
- 好数据:不仅仅是代表数据的显著性,并且符合模型的假设。
- 数值数据的健全性是第一个重要的基础。
- 1)最大值和最小值
- 2)跨几个数量级
- 3)输入特征对逻辑函数是否敏感
- 4)数值特征的分布:输入特征的分布有时候比模型更加重要。
- 字典转化为向量
# 特征抽取--字典格式转为向量
from sklearn.feature_extraction import DictVectorizer
def dict2Vect():
onehot = DictVectorizer(sparse=True) # 如果结果不用toarray,请开启sparse=False
instances = [{'city': '北京','temperature':100},{'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
data = onehot.fit_transform(instances)
print('data',data)
X = data.toarray()
print("X", X)
print(onehot.inverse_transform(X))
- onehot 编码
- 为了区别数据之间强加等级,比如莘县和阳谷县的编码。
- text2vect
# 文本特征提取(文本转化为向量
from sklearn.feature_extraction.text import CountVectorizerdef text2vect():
content = ["life is short,i like python", "life is too long,i dislike python"]
vectorizer = CountVectorizer()
data = vectorizer.fit_transform(content).toarray()
print(vectorizer.get_feature_names())
print('data',data)
- 统计所有不重复的词,转化为列表。不重复的词出现的个数。(单个字母不统计)
- 汉字2vect
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def hanzi2vect():
content1 = list(jieba.cut("我们爱中国,我们不喜欢美国"))
content2 = list(jieba.cut("我们是编程人员,再是算法研究员"))
content1 = ' '.join(content1)
content2 = ' '.join(content2)
content = []
content.append(content1)
content.append(content2) vectorizer = CountVectorizer()
data = vectorizer.fit_transform(content).toarray()
print(vectorizer.get_feature_names())
print('data', data)
- tf:term frequency 词频
- idf :逆文档分类 inverse document frequency
- idf = log(总文档数/该次出现的文章数)# 增加差异的影响。
- 词的重要性= tf*idf
# 文本分类
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
def tf_idf():
content1 = list(jieba.cut("我们爱中国,我们不喜欢美国"))
content2 = list(jieba.cut("我们是编程人员,再是算法研究员"))
content1 = ' '.join(content1)
content2 = ' '.join(content2)
content = []
content.append(content1)
content.append(content2) tf_idfver = TfidfVectorizer()
data = tf_idfver.fit_transform(content).toarray()
print(tf_idfver.get_feature_names())
print('data', data)tf_idf()
特征选择
from sklearn.feature_selection import VarianceThreshold
# 特征选择-删除低方差的特征
def var():
'''
特征选择的依据
:return:
'''
var = VarianceThreshold(threshold=1.0) data = var.fit_transform([[0,2,3,4],[1,0,2,3],[5,6,7,0]]) print('低var删除',data)
return None
无量钢化(特征预处理)
缺失值
- 均值填充
- 众数填充(可填充数值和字符,sklearn)
- 0填充
- 固定值填充(可填充数值和字符,sklearn)
from sklearn.preprocessing import Imputer
import numpy as np
def imputer():
'''
缺失值处理
:return:
'''
im = Imputer(missing_values='NaN',strategy = 'mean',axis =0)
data = im.fit_transform([[1,2],[np.nan,3],[7,6]])
print('缺失值处理',data)
return None
标准化缩放
归一化:normalization
- 适合不涉及距离度量和梯度、协方差以及数据需要压缩到特定区间的时候比较广泛使用。
- MinMaxScaler 公式:x’ = (x-xmin)/(max-min)
# minmaxstander
from sklearn.preprocessing import MinMaxScaler
def minmax():
'''
归一化
:return:
'''
mm = MinMaxScaler(feature_range=(2,4))
data = mm.fit_transform([[90,2,15],[60,1,20],[70,1.5,18]])
print('minmax',data)
标准化
- 适合算法pca,聚类,逻辑回归、支持向量机和神经网络
- 处理化成平均值为0,方差为1的数据。
- standardScaler==z-score 公式:x’ = (x — u)/方差
# 标准化缩放
from sklearn.preprocessing import StandardScaler
def stander_sacler():
'''
标准化缩放
:return:
'''
std = StandardScaler()
data = std.fit_transform([[1,2,3],[2,3,4],[4,5,6]])
print(data)
return 0
降维
- 减少特征的数量
- 特征选择
- 选择部分特征作为模型的输入
- 业务场景相关人员比较认可的数据维度特征
- Filter 过滤式
- 方差为0的,去掉
- 神经网络也是具有特征选择的功能
- 嵌入式:正则化、决策式
- 主成分分析
- PCA:特征数量达到上百个的时候
- 数据会改变,维度也会改变
- 数据信息没有损失
- 高维度数据之间有一定的相关性
# 主成分分析
from sklearn.decomposition import PCA
def pca_fun():
'''
主成分分析
:return:
'''
pac =PCA(n_components=1)# 信息保存的比例
data = pac.fit_transform([[1,2,3],[2,3,4]])
print('pca',data)
分类变量编码
- ordinalEncode 分类变量转化为数值,
- onehotEncode 类别转化为独热编码 增加为哑变量
- labelBinarizer 哑变量,二分类
-
连续型变量:二值化和分段
特征工程
- 数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
- 特征,即原始数据某个方面的数值表示。或者说,特征是模型输入中的X
- 特征工程就是从原始数据中提取有用因子,并转换为适合机器学习模型的特征的过程。
二值化:
一.二值化有时候我们只关心‘是不是‘,但拿到的数据是数量值。书中的例子是据用户收听次数,推测对歌的喜欢程度。可能说听得多肯定更喜欢,但是实际情况并非如此。收听次数和用户收听习惯有关,并非标识用户喜好的强指标。而且,这个次数多数较小,也有少数用户达到了几千次。如果直接使用次数,模型会被这些异常值带偏。处理方式很简单,把所有收听次数非0的设为1,这就是二值化。0代表用户没听过歌,认为不喜欢这首歌;1代表用户至少听过一次,认为喜欢这首歌。二值变量是一个简单又强壮的用户偏好衡量指标。
二.区间量化(分箱)如果一个数据跨越多个数量级,那么较大数据的实际影响可能会远超过其实际应该产生的影响,这会造成相似度度量问题。对此,可以使用区间量化对数据进行处理。区间量化,就是将数据跨度分为很多区间,给每个区间编号,然后使用区间编号代替原始数值。相当于将数据装到很多箱子中,所以也叫分箱。分箱可以将连续性数值映射为离散型数值。可以看出,分箱的主要过程在于划分区间。常见的有两种方法:固定宽度分箱和分位数分箱。
固定宽度分箱,每个区间的宽度是一定的。固定宽度并非宽度相同,常说的等距分箱,就是固定宽度分箱的一种。
宽度可以自动或人工划分,可以是线性也可以是指数级。比如,年龄数据,宽度可以设为10年;指数级增长的数据,宽度可以设为10的n次幂。
自适应分箱,是根据数据的分布特点,去划分区间。分位数分箱是常见的自适应分箱。这种方法将一些分位数设为区间端点,可以解决在固定宽度分箱中,有些箱子可能为空的问题。
三.对数变换对数变换是将变量映射为其对数的变换。前面讲了指数级分箱,如果将分箱宽度设置为无限小,就成了对数变换。
对数变换的一个性质是能对大数值进行压缩,对小数值进行扩展。所以,重尾分布在经过对数变换后,会变得更均匀一些。这会给线性模型特征空间低端值争取‘呼吸空间’,使模型不必在输入变化很小的情况下去拟合变化非常大的目标值。 - 一种重尾分布的图形四.指数变换指数变换是一个变化族,是方差稳定变换,对数变换是其中的一种。这些变换可以推广为Box-Cox变换:
- 。Box-Cox变换的作用是基于极大似然法的幂转换,其所用是让分布在不丢失信息的前提下,具有更好的性质(独立性、方差齐性、正态性等),以便得到更好的模型。λ无需计算,Scipy的boxcox函数,会找到最优λ,使变换后最近正态分布。
五.归一化(特征缩放)有的特征取值有限,有的则没有。对于回归模型或包含矩阵的模型,输出是输入的平滑函数,对输入尺度敏感,基于数的模型,则不受影响。如果模型是输入尺度敏感的,则需要进行特征归一化。
min-max缩放将特征映射到[0,1];特征标准化(方差缩放)将特征映射为均值为0方差为1的分布;范数归一化将特征映射为范数为1的变量。特征缩放不改变分布的形状。
六.交互特征将原始特征进行一定的运算就产生的特征为交互特征,如将两个特征做差、做积。这些特征捕获了特征间的交互作用。
交互特征可能是影响目标变量的关键因子,但是模型不一定能够捕获,所以我们要提前产生一些交互特征并输入模型。
交互特征构造简单,使用却需要付出很大的代价,因为增加了输入变量个数。因此交互特征不能乱用。
可以看出,数值变量的处理原则,一是分布均匀化,二是极端变量一般化。同时,也可以看出,对数据可视化也是处理数值数据的重要部分。
特征数字的奇特效果
- 特征缩放或归一化
- Min-Max缩放
- L2范数:正常化原始特征值
机器学习降维
数据可视化
pyechart
1.如果想直接将图片保存为 png, pdf, gif 格式的文件,可以使用 pyecharts-snapshot。使用该插件请确保你的系统上已经安装了 Nodejs 环境。
- 安装 phantomjs $ npm install -g phantomjs-prebuilt
- 安装 pyecharts-snapshot $ pip install pyecharts-snapshot
- 调用 render 方法 bar.render(path=’snapshot.png’) 文件结尾可以svg/jpeg/png/pdf/gif。请注意,svg 文件需要你在初始化 bar 的时候设置 renderer=’svg’。
sklearn经典命令
- 加载数据集
from sklearn.datasets import load_breast_cancer
X_breast, y_breast = load_breast_cancer(return_X_y=True)
- 2.数据集拆分
from sklearn.model_selection import train_test_split
X_breast_train, X_breast_test, y_breast_train, y_breast_test = train_test_split(X_breast, y_breast, stratify=y_breast, random_state=0, test_size=0.3)
- 3.训练
from sklearn.ensemble import GradientBoostingClassifierclf = GradientBoostingClassifier(n_estimators=100, random_state=0)
clf.fit(X_breast_train, y_breast_train)
- 预测
y_pred = clf.predict(X_breast_test)
- 准确率
from sklearn.metrics import balanced_accuracy_scoreaccuracy = balanced_accuracy_score(y_breast_test, y_pred)
print('Accuracy score of the {} is {:.2f}'.format(clf.__class__.__name__, accuracy))