定位
算法是核心,数据与计算是基础
找准定位
大部分复杂模型的算法设计都是算法工程师再做,我们
怎么做
企业内部数据、数据接口
学习阶段可用的数据集
sklearn
https://scikit-learn.org/stable/datasets
kaggle
https://www.kaggle.com/datasets
UCI
http://archive.ics.uci.edu/
工具简介
Python语言的机器学习工具
Scikit-learn工具包括许多知名的机器学习算法的实现
Scikit-learn文档完善,容易上手,丰富的API
安装
pip install sklearn
Scikit-learn包含的内容
sklearn数据集API介绍
sklearn.datasets
加载获取流行数据集
datasets.load_*()
datasets.fetch_*(data_home=None)
获取大规模数据集
例如
sklearn.datasets.fetch_20newsgroups(data_home=None, subset='train')
数据集的返回值
数据集的使用
加载鸢尾花数据集
from sklearn.datasets import load_iris
def datasets_demo():
"""
sklearn数据集使用
:return:
"""
# 获取数据集
iris = load_iris()
print("数据集key列表:\n", str(iris.keys()))
print("数据集描述:\n", iris['DESCR'])
print("特征值的名字:\n", iris.feature_names)
print("特征值:\n", iris.data, iris.data.shape)
return None
if __name__ == '__main__':
datasets_demo()
数据集的划分
机器学习一般的数据集会划分两个部分
数据集划分api
sklearn.model_selection.train_test_split(arrays, *options)
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2)
print("训练集的特征值:", x_train, x_train.shape)
sklearn.featrue_extraction
作用:对字典数据进行特征值化
sklearn.featrue_extraction.DictVectorizer(sparse=True,…)
def dict_demo():
"""
字典特征抽取
:return:
"""
data = [{'city': '北京', 'temperature': 100},
{'city': '上海', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
# 实例化一个转换器类
transfer = DictVectorizer(sparse=True)
# 调用fit_transform(data)
data_new = transfer.fit_transform(data)
print(data_new)
print("特征名称\n", transfer.get_feature_names_out())
return None
应用场景:
作用:对文本数据进行特征值化
单词作为特征
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
统计样本特征词出现次数
返回词频矩阵
CountVectorizer.fit_transform(X)
X:文本或者包含文本字符串的可迭代对象,
返回sparse矩阵
CountVectorizer.inverse_transform(X):
X array数组或者sparse矩阵
返回值 :转换之前数据格式
CountVectorizer.get_feature_names_out()
stop_words 停用词 网上查停用词表
def count_demo_cn():
"""
中文文本特征抽取 CountVectorizer
:return:
"""
data = ["我 爱 北京 天安门", "天安门 上 太阳 升"]
# 实例化转换器
transfer = CountVectorizer()
# 调用
data_new = transfer.fit_transform(data)
print(transfer.get_feature_names_out())
print(data_new.toarray())
return None
中文分词
def count_chinese_demo():
"""
中文文本特征抽取,自动分词
:return:
"""
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# # 实例化转换器
transfer = CountVectorizer(stop_words=["一种"])
# 调用
data_final = transfer.fit_transform(data_new)
print(transfer.get_feature_names_out())
print(data_final.toarray())
# import jieba
def cut_word(text):
"""
中文分词
:param text:
:return:
"""
return " ".join(list(jieba.cut(text)))
关键词:在某一个类别的文章中,出现的次数很多,但是在其他类别的文章中出现很少
Tf-idf文本特征提取
主要思想:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很号的类别区分能力,适合用来分类
TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度
公式
API
sklearn.feature_extraction.text.TfidfVectorizer(stop_words=None,…)
返回词的权重矩阵
TfidfVectorizer.fit_transform(X)
X:文本或者包含文本字符串的可迭代对象,
返回sparse矩阵
TfidfVectorizer.inverse_transform(X):
X array数组或者sparse矩阵
返回值 :转换之前数据格式
TfidfVectorizer.get_feature_names_out()
def tfidf_demo():
"""
使用tfidf进行文本特征抽取
:return:
"""
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# # 实例化转换器
transfer = TfidfVectorizer(stop_words=["一种"])
# 调用
data_final = transfer.fit_transform(data_new)
print(transfer.get_feature_names_out())
print(data_final.toarray())
定义:通过一些转换函数将特征数据转换成更加适合算法模型的特征数据的过程
无量纲化
特征处理API
sklearn.preprocessing
为什那么要进行归一化/标准化
x ′ = x − m i n m a x − m i n , x ′ ′ = x ′ ∗ ( m x − m i ) + m i x' = \frac{x-min}{max-min} ,x''=x' * (mx-mi) + mi x′=max−minx−min,x′′=x′∗(mx−mi)+mi
sklearn.preprocessing.MinMaxScaler(feature_range(0,1)…)
MinMaxScalar.fit_transform(X)
def minmax_demo():
"""
归一化
:return:
"""
# 获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
# 实例化一个转换器类
transfer = MinMaxScaler(feature_range=[0, 1])
# 调用fit_transform()
data_new = transfer.fit_transform(data)
print(data_new)
注意最大值、最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性(稳定性)较差,只适合传统精确小数据场景。
定义:通过对原始数据进行变换,把数据变换到均值为0,标准差为1范围内
公式
x ′ = x − m e a n σ , m e a n 是平均值, σ 是标准差 x' = \frac{x - mean}{σ},mean是平均值,σ是标准差 x′=σx−mean,mean是平均值,σ是标准差
对于标准化来说如果出现异常点,由于具有一定数量,少量的异常点对于平均值影响并不大,从而方差改变较小
sklearn.preprocessing.StandardScaler()
应用场景:在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据环境
定义:数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征
方法:
模块
sklearn.feature_selection
低方差特征过滤
def variance_demo():
"""
低方差特征过滤
:return:
"""
# 获取数据
data = pd.read_csv('factor_returns.csv')
data = data.iloc[:, 1:-2]
# 实例化转换器
transfer = VarianceThreshold(threshold=10)
# fit_transform
data_new = transfer.fit_transform(data)
print(data_new.shape)
相关系数
皮尔逊相关系数
反应变量之间相关关系密切程度的统计指标
公式
r = n ∑ x y − ∑ x ∑ y n ∑ x 2 − ( ∑ x ) 2 − n ∑ y 2 − ( ∑ y ) 2 r = \frac{n\sum xy - \sum x \sum y}{\sqrt {n \sum x^2 - (\sum x)^2} - \sqrt{n \sum y^2 - (\sum y) ^2}} r=n∑x2−(∑x)2−n∑y2−(∑y)2n∑xy−∑x∑y
相关系数的取值范围 [-1,1]
API
from scipy.stats import pearsonr
# 计算某两个变量之间的相关系统
r = pearsonr(data['pe_ratio'], data['pb_ratio'])
特征与特征之间相关性很高时如何处理
定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量
作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息
应用:回归分析或者聚类分析当中
过程:找到一个合适的直线,通过一个矩阵运算得出主成分分析的结果
API
def pca_demo():
"""
PCA降维
:return:
"""
data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]]
# 实例化转换器
transfer = PCA(n_components=0.95)
# fit_transform
data_new = transfer.fit_transform(data)
print(data_new)
需求:探究用户对物品类别的喜好
# 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
# 分析user_id 和 aisle的关系
K Nearest Neighbor算法又叫做KNN算法,这个算法是机器学习里一个比较经典的算法。
定义:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
距离公式
a,b两点为 a(a1,a2,a3),b(b1,b2,b3)
欧式距离
( a 1 − b 1 ) 2 + ( a 2 − b 2 ) 2 + ( a 3 − b 3 ) 2 \sqrt{(a1-b1)^2 + (a2-b2)^2 + (a3-b3)^2} (a1−b1)2+(a2−b2)2+(a3−b3)2
曼哈顿距离(绝对值距离)
∣ a 1 − b 1 ∣ + ∣ a 2 − b 2 ∣ + ∣ a 3 − b 3 ∣ |a1-b1| + |a2-b2| + |a3-b3| ∣a1−b1∣+∣a2−b2∣+∣a3−b3∣
明可夫斯基距离
K取值问题
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
"""
用KNN算法对鸢尾花进行分类
:return:
"""
# 获取数据
iris = load_iris()
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 特征工程 标准化
transfer = StandardScaler()
# 训练集
x_train = transfer.fit_transform(x_train)
# 测试集
x_test = transfer.transform(x_test)
# KNN预估器流程
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)
# 模型评估
y_predict = estimator.predict(x_test)
print(y_predict)
print(y_predict == y_test)
score = estimator.score(x_test, y_test)
print(score)
def knn_iris_gscv():
"""
用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证
:return:
"""
# 获取数据
iris = load_iris()
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 特征工程 标准化
transfer = StandardScaler()
# 训练集
x_train = transfer.fit_transform(x_train)
# 测试集
x_test = transfer.transform(x_test)
# KNN预估器流程
estimator = KNeighborsClassifier()
# 网格搜索与交叉验证
params = {
"n_neighbors": [1, 3, 5, 7, 9, 11]
}
estimator = GridSearchCV(estimator, param_grid=params, cv=10)
estimator.fit(x_train, y_train)
# 模型评估
y_predict = estimator.predict(x_test)
print(y_predict)
print(y_predict == y_test)
score = estimator.score(x_test, y_test)
print(score)
print("最佳参数:", estimator.best_params_)
print("最佳结果:", estimator.best_score_)
print("最佳估计器:", estimator.best_estimator_)
print("交叉验证结果:", estimator.cv_results_)
P ( C ∣ W ) = P ( W ∣ C ) P ( C ) P ( W ) P(C|W) = \frac{P(W|C)P(C)}{P(W)} P(C∣W)=P(W)P(W∣C)P(C)
文本分类
公式(贝叶斯公式在文章分类场景中可表示为):
P ( C ∣ F 1 , F 2 , . . . ) = P ( F 1 , F 2 , . . . ∣ C ) P ( C ) P ( F 1 , F 2 , . . . ) P(C|F1,F2,...) = \frac{P(F1,F2,...|C)P(C)}{P(F1,F2,...)} P(C∣F1,F2,...)=P(F1,F2,...)P(F1,F2,...∣C)P(C)
拉普拉斯平滑系数
目的:为了防止计算出的分类概率为0
公式
P ( F 1 ∣ C ) = N i + α N + α m P(F1|C) = \frac{Ni + α}{N + αm} P(F1∣C)=N+αmNi+α
信息论基础
信息
信息的衡量
信息熵
信息增益
决策树的划分依据之一----信息增益
随机森林
在机器学习中,随机森林是一个包含多个决策树的分类器,并且输出的类别是由个别树输出的类别的众数而定。
线性回归(Linear regression)是利用回归方程(函数)对一个变量或者多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归
通用公式:
h ( W ) = w 1 x 1 + w 2 x 2 + w 3 x 3... + b = w t x + b h(W) = w1x1 + w2x2 + w3x3... + b = w^tx + b h(W)=w1x1+w2x2+w3x3...+b=wtx+b
广义线性模块
线性关系
非线性关系
线性模式不等于线性关系
目标:求模型参数能使得预测准确
损失函数
又称cost、成本函数、目标函数
定义
J ( θ ) = ( h w ( x 1 ) − y 1 ) 2 + ( h w ( x 2 ) − y 2 ) 2 + . . . + ( h w ( x m ) − y m ) 2 = ∑ i = 1 m ( h w ( x i ) − y i ) 2 J(\theta) = (h_w(x_1) - y1)^2 + (h_w(x_2) - y2)^2 + ... + (h_w(x_m) - ym)^2 = \sum_{i=1}^{m}(h_w(x_i) -y_i)^2 J(θ)=(hw(x1)−y1)2+(hw(x2)−y2)2+...+(hw(xm)−ym)2=i=1∑m(hw(xi)−yi)2
正规方程
直接求解w
公式
w = ( X T X ) − 1 X T y w = (X^TX)^{-1} X^Ty w=(XTX)−1XTy
梯度下降
公式
$$
w1 := w1 - \alpha \frac{\delta cos t(w0 + w1x1)}{\delta w1}
w0 := w0 - \alpha \frac{\delta cos t(w0 + w1x1)}{\delta w1}
$$
正规方程
梯度下降
回归性能评估
均方误差评价机制
M S E = 1 m ∑ i = 1 m ( y i − y ) 2 MSE = \frac{1}{m}\sum_{i=1}^{m}(y^i - y)^2 MSE=m1i=1∑m(yi−y)2
sklearn.metrics.mean_squared_error(y_true, y_pred)
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
def linear1():
"""
正规方程对波士顿房价进行预测
:return:
"""
# 1.获取数据
boston = load_boston()
# 2.划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3.标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4.预估器
estimator = LinearRegression()
estimator.fit(x_train, y_train)
# 得出模型
print("正规方程权重系数:", estimator.coef_)
print("正规方程偏置率", estimator.intercept_)
# 模型评估
y_predict = estimator.predict(x_test)
print("预测房价:", y_predict)
error = mean_squared_error(y_test, y_predict)
print("正规方程-均方误差为", error)
def linear2():
"""
梯度下降对波士顿房价进行预测
:return:
"""
# 1.获取数据
boston = load_boston()
# 2.划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3.标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4.预估器
estimator = SGDRegressor(max_iter=10000, eta0=0.01, learning_rate='constant')
estimator.fit(x_train, y_train)
# 得出模型
print("梯度下降权重系数:", estimator.coef_)
print("梯度下降偏置率", estimator.intercept_)
# 模型评估
y_predict = estimator.predict(x_test)
print("预测房价:", y_predict)
error = mean_squared_error(y_test, y_predict)
print("梯度下降-均方误差为", error)
正规方程与梯度下降对比
梯度下降 | 正规方程 |
---|---|
需要选择学习率 | 不需要 |
需要迭代求解 | 一次运算出 |
特征数量较大可以使用 | 需要计算方程,时间复杂度高O(n^3) |
梯度下降优化方法
欠拟合原因以及解决办法
过拟合原因以及解决办法
正则化
L2正则化(Ridge)
作用:可以使得其中一些W的值都很小,都接近于0,削弱某个特征的影响
优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
加入L2正则化后的损失函数
J ( w ) = 1 2 m ∑ i = 1 m ( h w ( x i ) − y i ) 2 + λ ∑ j = 1 n w j 2 J(w) = \frac{1}{2m} \sum_{i=1}^{m}(h_w(xi) - y_i)^2 + λ \sum_{j=1}{n}w_j^2 J(w)=2m1i=1∑m(hw(xi)−yi)2+λj=1∑nwj2
L1正则化(LASSO)
输入:逻辑回归的输入就是一个线性回归的结果
h ( w ) = w 1 x 1 + w 2 x 2 + . . . + b h(w) = w_1x_1 + w_2x_2 + ... + b h(w)=w1x1+w2x2+...+b
激活函数
sigmoid函数
g ( θ T x ) = 1 1 + e − θ T x g(\theta^Tx) = \frac{1}{1+e^{-\theta^Tx}} g(θTx)=1+e−θTx1
分析
对数似然损失
c o s t ( h θ , y ) = { − l o g ( 1 − h θ ( x ) ) , y = 0 − l o g ( h θ ( x ) ) , y = 1 cost(h_{\theta},y) = \{^{-log(h_\theta(x)), y=1}_{-log(1-h_\theta(x)),y=0} cost(hθ,y)={−log(1−hθ(x)),y=0−log(hθ(x)),y=1
c o s t ( h θ ( x ) , y ) = ∑ i = 1 m − y i l o g ( h θ ( x ) ) − ( 1 − y i ) l o g ( 1 − h θ ( x ) ) cost(h_\theta(x),y) = \sum_{i=1}^{m}-y_ilog(h_\theta(x)) - (1-y_i)log(1-h_\theta(x)) cost(hθ(x),y)=i=1∑m−yilog(hθ(x))−(1−yi)log(1−hθ(x))
#%%
import pandas as pd
import numpy as np
#%%
# 1、读取数据
path = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape',
'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin',
'Normal Nucleoli', 'Mitoses', 'Class']
data = pd.read_csv(path, names=column_name)
#%%
data
#%%
# 缺失值处理
data = data.replace(to_replace='?', value=np.nan)
#%%
data.dropna(inplace=True)
#%%
data.isnull().any()
#%%
data
#%%
# 划分数据集
x = data.iloc[:, 1:-1]
y = data['Class']
#%%
from sklearn.model_selection import train_test_split
#%%
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
#%%
x_train
#%%
# 特征工程
from sklearn.preprocessing import StandardScaler
#%%
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#%%
x_train
#%%
# 逻辑回归预估器
from sklearn.linear_model import LogisticRegression
#%%
estimator = LogisticRegression()
estimator.fit(x_train, y_train)
#%%
# 逻辑回归模型参数查看
estimator.coef_
#%%
estimator.intercept_
#%%
# 模型评估
print("预测值与真实值对比", y_test == estimator.predict(x_test))
print("准确率为:", estimator.score(x_test, y_test))
#%%
混淆矩阵
预测结果与真实结果的四种不同结果
预测结果 | |||
---|---|---|---|
正例 | 假例 | ||
真实结果 | 正例 | 真正例TP | 伪反例FN |
假例 | 伪正例FP | 真反例TN |
精确率
召回率
F1-score
分类评估报告API
# 保存模型
# joblib.dump(estimator, 'my_ridge.pkl')
# 加载模型
estimator = joblib.load('my_ridge.pkl')
轮廓系数
S C i = b i − a i m a x ( b i , a i ) SC_i = \frac{b_i - a_i}{max(b_i,a_i)} SCi=max(bi,ai)bi−ai
轮廓系数(-1, 1),越接近于1效果越好,接近于-1效果不好
API