前言

在正式开始做 “异常新闻检测” 的科研训练之前,需要机器学习、深度学习有一定基础

为此,打算先做一个快速入门,在对所学知识有一定了解之后,再回头补一些基础的理论性较强的知识

该笔记作于 《2018年3天快速入门python机器学习【黑马程序员】》的观看学习过程中

一、特征工程

0. 梗概

image-20200718165205103 image-20200718165144638

1. sklearn

Scikit learn 也简称 sklearn, 是机器学习领域当中最知名的 python 模块之一。

  • 简单高效的数据挖掘和数据分析工具
  • 可供大家在各种环境中重复使用
  • 建立在 NumPy ,SciPy 和 matplotlib 上
  • 开源,可商业使用 - BSD许可证

Scikit-learn is an open source machine learning library that supports supervised and unsupervised learning. It also provides various tools for model fitting, data preprocessing, model selection and evaluation, and many other utilities.

sklearn包含的内容:

  • Classification 分类

  • Regression 回归

  • Clustering 非监督分类

  • Dimensionality reduction 数据降维

  • Model Selection 模型选择

  • Preprocessing 数据预处理

image-20200715172312712

2. 数据集

sklearn 提供了用来学习的多种数据集:

  • 自带的小数据集(packaged dataset):sklearn.datasets.load_
  • 可在线下载的数据集(Downloaded Dataset):sklearn.datasets.fetch_
  • 计算机生成的数据集(Generated Dataset):sklearn.datasets.make_
  • svmlight/libsvm格式的数据集:sklearn.datasets.load_svmlight_file(…)
  • 从买了data.org在线下载获取的数据集:sklearn.datasets.fetch_mldata(…)

数据集返回结果:

image-20200715173156243

以自带的小数据集 鸢尾花数据集 为例演示数据集的使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.datasets import load_iris

def datasets_demo():
iris = load_iris()
print("鸢尾花数据集:\n",iris)
print("查看数据集描述:\n",iris["DESCR"])
print("查看特征值的名字:\n",iris.feature_names)
print("查看特征值:\n",iris.data)
print("查看特征值形状:\n",iris.data.shape)
return None

if __name__ == "__main__":
datasets_demo()

这里要注意不要把所有的数据集都拿来训练一个模型,还一个留一部分用来验证,于是有了数据集的划分

数据集划分:

  • 机器学习一般的数据集会划分为两个部分:训练数据、测试数据

  • 划分比例:

    • 训练集:70% 80% 75%
    • 测试集:30% 20% 30%
image-20200715175248929
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from sklearn.datasets  import load_iris
from sklearn.model_selection import train_test_split
def datasets_demo():
#获取数据集
iris = load_iris()
print("鸢尾花数据集:\n",iris)
print("查看数据集描述:\n",iris["DESCR"])
print("查看特征值的名字:\n",iris.feature_names)
print("查看特征值:\n",iris.data)
print("查看特征值形状:\n",iris.data.shape)
#数据集的划分
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.2,random_state=22)
print("训练集的特征值:\n",x_train,x_train.shape)
print("测试集的特征值:\n",x_test,x_test.shape)
return None
if __name__ == "__main__":
datasets_demo()

3. 特征工程简介

业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。

特征工程是使用专业背景知识和技巧处理数据使得特征能在机器学习算法上发挥更好的作用的过程会直接影响机器学习效果。

特征工程内容:

  • 特征抽取
  • 特征预处理
  • 特征降维

4. 特征抽取

特征抽取:将任意数据(文本或图像)转化为用于机器学习的数字特征

分类:

  • 字典特征抽取(特征离散化)
  • 文本特征抽取
  • 图像特征抽取(深度学习中使用)

使用的 API :sklearn.feature_extraction

1)字典特征提取

简介:

image-20200715180318408

实例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer

def dict_demo():
data = [{'city':'北京','temperature':100},{'city':'上海','temperature':60},{'city':'深圳','temperature':30}]
#实例一个转换器类
transfer = DictVectorizer(sparse=False)
#调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n",data_new)
print("特征名称:\n",transfer.get_feature_names())
return None

if __name__== "__main__":
dict_demo()

执行结果:

  • sparse = False

    image-20200715180612908
  • sparse = True

    image-20200715180641344

2)文本特征提取

简介:

image-20200715180752889
英文文本分词:
1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer

def count_demo():
data = {"Life is short,i like like python","Life is too long,i dislike python"}
#实例化一个转化器
transfer = CountVectorizer()
#调用transform
data_new = transfer.fit_transform(data)
print("data_new:\n",data_new.toarray())
return None
if __name__ == '__main__':
count_demo()

image-20200715180925250

中文文本分词:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
import jieba

def cut_word(text):
return " ".join(list(jieba.cut(text)))
def count_chinese_demo():
data = ["在北上广深,软考证书可以混个工作居住证,也是一项大的积分落户筹码。",
"升职加薪必备,很多企业人力资源会以此作为审核晋升的条件。",
"简历上浓彩重抹一笔,毕竟是国家人力部、工信部承认的IT高级人才。"]
data_new=[]
for sent in data:
data_new.append(cut_word(sent))
#实例化一个转化器
transfer = CountVectorizer()
#调用transform
data_final = transfer.fit_transform(data_new)
print("转化后结果:\n",data_final.toarray())
print("特征名字:\n",transfer.get_feature_names())
return None
if __name__ == '__main__':
count_chinese_demo()
image-20200715181700533

上述方法会出现一些 “可以”、“很多” 等与主题无关紧要的特征,会印象我们对结果的判断,不够完善,此时我们引入 Tf-idf 文本特征提取方法

Tf-idf 文本特征提取:

简介:

  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

  • TF-IDF作用:用以评估-字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

image-20200715182239136

api:

image-20200715182310569

使用方法与上面提到的中文文本分词方法大体一致,只是将转换器换为:TfidfVectorizer()

5. 特征预处理

image-20200715182740495

特征预处理就是通过一些转化函数将特征数据转换成更加适合算法模型的特征数据过程无量纲化处理)

特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其它的特征

包括内容:归一化、标准化

使用的 api :sklearn.preprocessing

1)归一化

通过对原始数据进行变换把数据映射到(默认为[0,1])之间

image-20200715183155497

api:

image-20200715183210002

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
def minmax_demo():
data = pd.read_csv("dating.txt")
data = data.iloc[:,:3] #只取数据前三列
print("data=\n",data)
transfer = MinMaxScaler() #默认0-1
data_new = transfer.fit_transform(data)
print("data_new=\n",data_new)


if __name__ == '__main__':
minmax_demo()
image-20200715183245714

归一化鲁棒性(最大值最小值容易受异常点影响)较差,只适合传统精确小数据场景

2)标准化

image-20200715183530348

api:

image-20200715183605810

使用方法与上面提到的归一化方法大体一致,只是将转换器换为:StandardScaler()

6. 特征降维

image-20200715183831598

降维两种方式:

  • 特征选择
  • 主成分分析

1)特征选择

数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征

方法:

image-20200715184212364

使用的模块: sklearn-feature.selection

低方差特征过滤

删除低方差(衡量随机变量或一组数据时离散程度的度量,低方差说明数据相近)一些特征。

api:

image-20200716162726579
高相关系数过滤

相关关系是一种非确定性的关系,相关系数是研究变量之间线性相关程度的量。

image-20200716163333534 image-20200716163349396

api:

image-20200716163534685 image-20200716163616901
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 代码总结
def variance_demo():
"""
过滤低方差特征
:return:
"""
# 1、获取数据
data = pd.read_csv("factor_returns.csv")
data = data.iloc[:, 1:-2]
print("data:\n", data)

# 2、实例化一个转换器类
transfer = VarianceThreshold(threshold=10)

# 3、调用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

2) 主成分分析(PCA)

  • 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量。

  • 作用:尽可能降低原数据的维数,同时尽量保证数据损失较少

  • 简单示例:

    1. 三维物体的二维特征

    image-20200718164344152

    1. 将给定一组坐标降维

      image-20200718164455771 image-20200718164514052 image-20200718164540852

image-20200718164554187

  • API

    image-20200718164644648
  • 实例:

    image-20200718164725784
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from sklearn.decomposition  import PCA

    def pca_demo():
    data = [[2,8,4,5],[6,3,0,8],[5,4,9,1]]
    transfer = PCA(n_components=2) #降维成两个特征
    data_new = transfer.fit_transform(data)
    print("data_new:\n",data_new)
    return None
    if __name__ == '__main__':
    pca_demo()

    image-20200718164750676

    成功将四维坐标降为二维!

二、分类算法

0. 梗概

image-20200721173457106

1. 转换器和估计器

1)转换器

​ 我们把特征工程的接口称为转换器

转换器的调用方法:

  • fit_transformfittransform 的结合
  • fit:计算每一列的平均值和标准差
  • transform(x - mean) / std(进行最终的计算)

2)估计器

估计器是一类实现了算法的 API

  1. 用于分类的估计器

    • sklearn.neighbors K-近邻算法
    • sklearn.naive_bayes 朴素贝叶斯
    • sklearn.linear_model.LogisticRegression 逻辑回归
    • sklearn.tree 决策树和随机森林
  2. 用于回归的估计器

    • sklearn.linear_model.LinearRegression 线性回归

    • sklearn.linear_model.Ridge 岭回归

  3. 用于无监督学习的估计器

    • sklearn.cluster.KMeans 聚类

估计器工作流程:

image-20200721164812435

2. K-近邻算法(KNN 算法)

核心思想:根据你的邻居来判断你的类别!

给定一个训练集,对新输入的实例,在训练集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,我们就把该输入实例分为这个类。

image-20200721165450099

基本要素:

  • 距离度量方法
    • 欧氏距离 image-20200721165649451
    • 曼哈顿距离 image-20200721165701626
    • 闵可夫斯基距离 image-20200721165755462
  • K值
    • 过小:容易受到异常数据的影响
    • 过大:容易受到样本不均衡的影响
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier

"""
案例:使用 KNN 算法对鸢尾花集进行分类
:return:
"""
def knn_iris():
# 1.获取数据
iris = load_iris()
# 2.划分数据集
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=22)
# 3.特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.fit_transform(x_test)
# 4.KNN算法预估器
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 5.模型评估
#方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n",y_test == y_predict)
#方法2:计算准确率
score = estimator.score(x_test,y_test)
print("准确率为:\n",score)
return None

if __name__ == '__main__':
knn_iris()

image-20200721171101873

3. 朴素贝叶斯算法

1)贝叶斯公式

image-20200721170331093

  • W:给定文档的特征值
  • C:文档类别

2)拉普拉斯平滑系数

目的:防止计算出的分类概率为0

image-20200721170612675

3)朴素贝叶斯

  • 朴素:假定各个事件相互独立
  • 贝叶斯:贝叶斯公式

API :sklearn.naive_bayes.MultinomialNB(alpha = 1.0)

  • 朴素贝叶斯分类
  • alpha:拉普拉斯平滑系数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB

"""
用朴素贝叶斯算法对新闻进行分类
:return:
"""
def nb_news():

# 1)获取数据
news = fetch_20newsgroups(subset="all")

# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)

# 3)特征工程:文本特征抽取-tfidf
transfer = TfidfVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

# 4)朴素贝叶斯算法预估器流程
estimator = MultinomialNB()
estimator.fit(x_train, y_train)

# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)

return None
if __name__ == '__main__':
nb_news()
image-20200721172243905

4. 决策树

image-20200721172449868

上图是一棵结构简单的决策树,用于预测贷款用户是否具有偿还贷款的能力。贷款用户主要具备三个属性:是否拥有房产,是否结婚,平均月收入。每一个内部节点都表示一个属性条件判断,叶子节点表示贷款用户是否具有偿还能力。例如:用户甲没有房产,没有结婚,月收入 5K。通过决策树的根节点判断,用户甲符合右边分支 (拥有房产为”否”);再判断是否结婚,用户甲符合左边分支 (是否结婚为否);然后判断月收入是否大于 4k,用户甲符合左边分支 (月收入大于 4K),该用户落在”可以偿还”的叶子节点上。所以预测用户甲具备偿还贷款能力。

通过信息增益找到最⾼效的决策顺序。

API:

image-20200721172921450

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz

"""
用决策树对鸢尾花进行分类
:return:
"""
def decision_iris():

# 1)获取数据集
iris = load_iris()

# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)

# 3)决策树预估器
estimator = DecisionTreeClassifier(criterion="entropy")
estimator.fit(x_train, y_train)

# 4)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)

# 可视化决策树
export_graphviz(estimator, out_file="iris_tree.dot", feature_names=iris.feature_names)

return None
if __name__ == '__main__':
decision_iris()

image-20200721173119603

5. 随机森林

image-20200721173201773

API:

image-20200721173217939
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.feature_extraction import DictVectorizer

"""
用随机森林实现泰坦尼克号实例
:return:
"""
def randomForest_demo():
# 1、获取数据
path = "http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt"
titanic = pd.read_csv(path)
# 筛选特征值和目标值
x = titanic[["pclass", "age", "sex"]]
y = titanic["survived"]
# 2、数据处理
# 1)缺失值处理
x["age"].fillna(x["age"].mean(), inplace=True)
# 2) 转换成字典
x = x.to_dict(orient="records")
# 3、数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# 4、字典特征抽取
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#随机森林预估器
estimator = RandomForestClassifier()
# 加入网格搜索与交叉验证
# 参数准备
param_dict = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}
estimator = GridSearchCV(estimator, param_grid=param_dict, cv=3)
estimator.fit(x_train, y_train)

# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)

# 最佳参数:best_params_
print("最佳参数:\n", estimator.best_params_)
# 最佳结果:best_score_
print("最佳结果:\n", estimator.best_score_)
# 最佳估计器:best_estimator_
print("最佳估计器:\n", estimator.best_estimator_)
# 交叉验证结果:cv_results_
print("交叉验证结果:\n", estimator.cv_results_)

if __name__ == '__main__':
randomForest_demo()

三、回归与聚类算法

参考

  1. 黑马程序员:https://www.bilibili.com/video/BV1nt411r7tj?t=38&p=16
  2. sklearn 中文文档:http://www.scikitlearn.com.cn/
  3. 隔壁郑同学:https://blog.csdn.net/weixin_44517301/article/details/88405939