2023.10.4学习

2023.10.4学习

人工智能基础学习

决策树(Decision Tree)

一种对实例进行分类树形结构,通过多层判断区分目标所属类别。

本质:通过多层判断,从训练数据集中归纳出一组分类规则

优点:计算量小,运算速度快;易于理解,可清晰查看各属性的重要性。

缺点:忽略属性间的相关性;样本类别分布不均匀时,容易影响模型表现。

决策树求解:

假设给定训练数据集
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } D = \lbrace (x_1,y_1),(x_2,y_2),...,(x_N,y_N)\rbrace D={(x1,y1),(x2,y2),...,(xN,yN)}
其中,xi为输入实例,yi类标记,N为样本容量。

求解目标:根据训练数据集构建一个决策树模型,使它能够对实例进行正确的分类

问题核心:特征选择。在每一个节点,应该选用哪个特征。

三种求解方法:ID3、C4.5、CART。

ID3:利用信息熵原理选择信息增益最大的属性作为分类属性,递归地拓展决策树的分支,完成决策树的构造。

信息熵(entropy)是度量随机变量不确定性的指标,熵越大,变量的不确定性就越大。假定当前样本集合D中第k类样本所占的比例为pk,则D的信息熵为:
E n t ( D ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 p k Ent(D) = -\sum \limits^{|y|}\limits_{k=1}p_klog_2p_k Ent(D)=k=1ypklog2pk
Ent(D)的值越小,变量的不确定性越小。

image-20231004141948598

根据信息熵,可以计算以属性a进行样本划分带来的信息增益(划分前的信息熵-划分后的信息熵):
G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V D v D E n t ( D v ) Gain(D,a) = Ent(D)-\sum \limits^V \limits_{v=1}\frac {D_v} D Ent(D_v) Gain(D,a)=Ent(D)v=1VDDvEnt(Dv)
V为根据属性a划分出来的类别数、D为当前总样本数,Dv为类别 v 的样本数。

目标:划分后样本分布不确定性尽可能小,即划分后信息熵小,信息增益大。

代码:

import pandas as pd
from matplotlib import pyplot as plt
from sklearn import tree

# 原文件为.data类型,将其转化为dataFrame
data = pd.read_csv('iris.data', header=None, sep=',')
print(data.head())
# 添加列名称
data = data.rename(columns={0: 'sepal_length', 1: 'sepal_width', 2: 'petal_length', 3: 'petal_width', 4: 'class'})
print(data.head())

X = data.drop('class', axis=1)
y = data.loc[:, 'class']

# 创建决策树实例
# 第一个参数:指用信息增益最大化的方法选择节点,即使用ID3算法;第二个参数:该决策树不超过5个节点,防止过拟合
dc_tree = tree.DecisionTreeClassifier(criterion='entropy', min_samples_leaf=5)
dc_tree.fit(X, y)

# 可视化决策树
# 参数:filled=True,指同一种类别填充同一种颜色
tree.plot_tree(dc_tree, filled=True, feature_names=['sepal_length', 'sepal_width', 'petal_length', 'petal_width'],
               class_names=['setosa', 'versicolor', 'virginica'])
plt.show()

运行结果

异常检测(Anomaly Detection)

根据输入数据,对不符合预期模式的数据进行识别。

from sklearn.covariance import EllipticEnvelope
  1. 一维数据集:寻找低概率数据/事件

步骤:

(1)计算数据均值μ、标准差σ

(2)计算对应的高斯分布概率函数
p ( x ) = 1 σ 2 π e − ( x − μ ) 2 2 σ 2 p(x) = \frac 1 {\sigma \sqrt{2\pi}} e^{-\frac {(x-\mu)^2} {2\sigma^2}} p(x)=σ2π 1e2σ2(xμ)2
(3)根据数据点概率,进行判断:若p(x) < ε(一般为0.5),则该点为异常点

  1. 高维数据集

步骤:

(1)计算数据均值μ1、μ2、μ3…,标准差σ1、σ2、σ3…

(2)计算概率密度函数p(x)(连乘)
p ( x ) = ∏ j = 1 n p ( x j ; μ j , σ j 2 ) = ∏ j = 1 n 1 σ j 2 π e − ( x j − μ j ) 2 2 σ j 2 p(x)=\prod^n_{j =1}p(x_j;\mu_j,\sigma_j^2)=\prod^n_{j=1}\frac 1 {\sigma_j\sqrt{2\pi}}e^{-\frac{(x_j-\mu_j)^2} {2\sigma_j^2}} p(x)=j=1np(xj;μj,σj2)=j=1nσj2π 1e2σj2(xjμj)2
(3)若p(x) < ε,则该点为异常点

代码:

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from scipy.stats import norm
from sklearn.covariance import EllipticEnvelope

data = pd.read_csv('data2.csv')
print(data.head())

x = data.loc[:, 'x']
y = data.loc[:, 'y']

fig1 = plt.figure()
plt.scatter(x, y)
plt.show()

# 数据分布统计与可视化
fig2 = plt.subplot(121)
plt.hist(x, bins=100)  # bins = 100表示横轴共分为100个小格
fig3 = plt.subplot(122)
plt.hist(y, bins=100)
plt.show()

# 计算数据均值和标准差
x_mean = x.mean()  # 均值
x_sigma = x.std()  # 标准差
y_mean = y.mean()
y_sigma = y.std()

# 绘制高斯分布曲线(概率密度函数曲线)
x_range = np.linspace(0, 100, 1000)  # 横轴范围,0: 20, 300间隔
normal1 = norm.pdf(x_range, x_mean, x_sigma)  # 生成曲线
fig4 = plt.figure()
plt.plot(x_range, normal1)
plt.show()

y_range = np.linspace(0, 100, 1000)
normal2 = norm.pdf(y_range, y_mean, y_sigma)
fig5 = plt.figure()
plt.plot(y_range, normal2)
plt.show()

# 直接用sklearn中的工具包拟合
clf = EllipticEnvelope(contamination=0.02)  # contamination: 概率阈值,默认为0.1,但有时可能过高,会把正常点也判断成了异常点
clf.fit(data)

# 异常点预测与标记(返回值:y_predict==-1,表明为异常点)
y_predict = clf.predict(data)
fig6 = plt.figure()
un_normal_points = plt.scatter(data.loc[:, 'x'][y_predict == -1], data.loc[:, 'y'][y_predict == -1],
                             marker='o', facecolor='none', edgecolors='red', s=100)  # marker:绘制点的形状;facecolor:填充;edgecolors:边框颜色;s:大小
normal_points = plt.scatter(x, y, marker='x')
plt.show()

主成分分析(PCA)

数据降维:在某些限定条件下,降低随机变量个数,得到一组“不相关”主变量的过程。

作用:减少模型分析数据量,提升处理效率,降低计算难度;实现数据可视化。

PCA:实现数据降维的方法。

from sklearn.decomposition import PCA

目标:寻找k(k<n)维新数据,使它们反映事物的主要特征。

核心:在信息损失尽可能少的情况下,降低数据维度。

如何保留主要信息:投影后的不同特征数据尽可能分得开(不相关),即,使投影后数据的方差最大,方差越大数据越分散。

步骤:

(1)原始数据预处理(标准化:μ = 0,σ = 1)

(2)计算协方差矩阵特征向量、数据在各特征向量投影后的方差

(3)根据需求(任务指定或方差比例),确定降维维度k

(4)选取k维特征向量,计算数据在其形成空间的投影

代码:

import pandas as pd
from matplotlib import pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

data = pd.read_csv('iris.data', header=None, sep=',')
print(data.head())
data = data.rename(columns={0: 'sepal_length', 1: 'sepal_width', 2: 'petal_length', 3: 'petal_width', 4: 'class'})
print(data.head())

X = data.drop('class', axis=1)
y = data.loc[:, 'class']

# KNN分类
KNN = KNeighborsClassifier(n_neighbors=3)
KNN.fit(X, y)
y_predict = KNN.predict(X)

accuracy = accuracy_score(y, y_predict)
print(accuracy)

# PCA分类
# 数据标准化处理(取第一个维度)
X_norm = StandardScaler().fit_transform(X)
print(X_norm)

fig1 = plt.figure(figsize=(20,5))
plt.subplot(121)
plt.hist(X.loc[:, 'sepal_length'], bins=100)
plt.subplot(122)
plt.hist(X_norm[:, 0], bins=100)
plt.show()

# 计算均值
x1_mean = X.loc[:, 'sepal_length'].mean()
x1_norm_mean = X_norm[:, 0].mean()
x1_sigma = X.loc[:, 'sepal_length'].std()
x1_norm_sigma = X_norm[:, 0].std()
print(x1_mean, x1_sigma, x1_norm_mean, x1_norm_sigma)

# 创建PCA实例
print(X.shape)
pca = PCA(n_components=4)  # 参数:维度为4
X_pca = pca.fit_transform(X_norm)  # 降维后的数据

# 查看所有主成分方差,只保留方差较高的主成分
var_ratio = pca.explained_variance_ratio_
print(var_ratio)
# 结果可视化
fig2 = plt.figure()
plt.bar([1, 2, 3, 4], var_ratio)
plt.xticks([1, 2, 3, 4], ['PC1', 'PC2', 'PC3', 'PC4'])
plt.ylabel('variance ratio of each PC')
plt.show()

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_norm)  # 降维后的数据
print(X_pca.shape)  # (150, 2)

print(type(X_pca))  #numpy.ndarray

fig3 = plt.figure()
setosa = plt.scatter(X_pca[:, 0][y == 'Iris-setosa'], X_pca[:, 1][y == 'Iris-setosa'])
ver = plt.scatter(X_pca[:, 0][y == 'Iris-versicolor'], X_pca[:, 1][y == 'Iris-versicolor'])
vir = plt.scatter(X_pca[:, 0][y == 'Iris-virginica'], X_pca[:, 1][y == 'Iris-virginica'])
plt.legend((setosa, ver, vir), ('setosa', 'versicolor', 'virginica'))
plt.show()

# 将降维后的数据用于KNN分类,比较分类准确率
KNN = KNeighborsClassifier(n_neighbors=3)
KNN.fit(X_pca, y)
y_predict = KNN.predict(X_pca)

accuracy = accuracy_score(y, y_predict)
print(accuracy)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值