No title

在上一章博客中我们学习到了一些基本的机器学习的分类计算模型,接下来我们将进行更加深入的学习。

无监督学习:机器学习的一种方法,训练数据中不带标签,让机器自动寻找数据规律并完成任务。

特点:

  1. 数据不需要标签。
  2. 算法不受监督信息约束。

优点:

  1. 降低数据采集难度,极大程度扩充样本量。
  2. 可能发现新的数据规律、被忽略的重要信息。

聚类分析:把数据样本按照一定的方法分成不同的组别,这样让在同一个组别中的成员对象都有相似的一些属性。

K均值聚类:在样本数据空间中选取K个点作为中心,计算每个样本到各中心的距离,根据距离确定数据类别,是聚类算法中最为基础但也最为重要的算法。

核心流程

  1. 基于要求,观察或经验确定聚类的个数K.
  2. 确定K个中心。
  3. 计算样本到各中心点距离。
  4. 根据距离确定各个样本点所属类别。
  5. 计算同类别样本的中心点,并将其设定为新的中心。
  6. 重复步骤3-5直到收敛(中心点不再变化)。

通过K均值聚类可以实现图像分割图像分割就是把图像分成若干个特定的、具有独特性质的区域的技术,是由图像处理到图像分析的关键步骤。

KMeans实现数据聚类:

1
2
3
4
5
import pandas as pd
import numpy as np
data=pd.read_csv('task1_data1.csv')#测试样本
data_result=pd.read_csv('task1_data2.csv')#检验
data.head()

image-20220225111032327

1
2
3
#获取唯一一个有标签的数据点
x_labeled=data.iloc[0,:]#取第0行的所有数据
print(x_labeled)

image-20220225111138082

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#x赋值
x=data.drop['y',axis=1]
#正确结果的赋值
y=data_result.loc[;,'y']

#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(x.loc[:,'x1'],x.loc[:'x2'],label='unlabeled')
plt.scatter(x_labeled['x1'],x_labeled['x2'],label='labeled')#格式不同,取点方式也不同
plt.title('unlabeled data')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend(loc='upper left')#移动至左上角
plt.show()

image-20220225112243062

1
2
3
4
5
#建立KMeans模型并训练
from sklearn.cluster import KMeans
KM=KMeans(n_clusters=2,init='random',random_state=0)
#训练
KM.fit(x)#无监督,不用训练y
1
2
3
4
5
#查看聚类中心
centers=KM.cluster_centers_

#画中心点
plt.scatter(centers[:,0],centers[:,1],100,marker='x',label='centers')#设置大小和标记

image-20220225203120993

1
2
3
4
#无监督聚类结果预测
y_predict=KM.predict(x)
print(pd.value_counts(y_predict)#统计1和0的数量
print(pd.value_counts(y))

image-20220225203751535

由测试数集可以看出,聚类预测的结果由较大的偏差,但也不难看出,可能在分析时,将1和0的分类有可能分反了,因此:

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
#结果矫正
y_corrected=[]#创建一个新的列表
for i in y_predict:
if i==0:
y_corrected.append(1)
elif i==1:
y_corrected.append(0)

#可视化
y_corrected=np.array(y_corrected)#转化格式用于画图索引
fig2=plt.figure(figsize=(16,8)#设定图片大小

fig3=plt.subplot(121)
plt.scatter(x.loc[:,'x1'][y_corrected==0],x.loc[:'x2'][y_corrected==0],label='label0')
plt.scatter(x_labeled['x1'][y_corrected==1],x_labeled['x2'][y_corrected==1],label='label1')
plt.scatter(x_labeled['x1'],x_labeled['x2'],label='labeled')
plt.title('unlabeled data(corrected result)')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend(loc='upper left')#移动至左上角

fig4=plt.subplot(122)
plt.scatter(x.loc[:,'x1'][y==0],x.loc[:'x2'][y==0],label='label0')
plt.scatter(x_labeled['x1'][y==1],x_labeled['x2'][y==1],label='label1')
plt.scatter(x_labeled['x1'],x_labeled['x2'],label='labeled')
plt.title('labeled data')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend(loc='upper left')#移动至左上角
plt.show()

image-20220225210356372

接下来,我们运用KNN算法进行建模并于之前的方法进行比较:

1
2
3
4
5
6
7
8
#knn建模与训练
from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=3)#设置k=3
knn.fit(x,y)

#模型预测
y_predict_knn=knn.predict(x)
#通过计算准确率有1.0预测效果好。
1
2
3
4
5
#KMeans迭代一次的结果
KM2=KMeans(n_clusters=2,init='random',random_state=1,n_init=1,max_iter=1)
KM2.fix(x)
centers=KM2.clusters_centers
y_predict2=KM2.predict(x)

KMeans实现图像分割:

1
2
3
4
5
6
#图像的加载与展示
import numpy as np
import matplotlib.pyplot as plt
from skimage import io as io
img=io.read('1.jpg')
plt.show(img.)

image-20220227212737932

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#维度存储
img_height=img.shape[0]
img_width=img.shape[1]

#数据维度转化
img_data=img.reshape(-1,3)

#x赋值
x=img_data

#模型建立与训练
from sklearn.cluster import KMeans
model=KMeans(n_clusters=3,random_state=0)
model.fit(x)
1
2
3
4
5
6
7
8
9
10
11
#聚类结果预测
label=model.predict(x)

#结果数据的维度转化
label=label.reshape([img_height,img_width])

#后续灰度处理
label=1/(label+1)

#结果可视化
plt.imshow(label)

image-20220227221719584

1
2
3
4
5
6
#图像储存到本地
io.imsave('result_k3.png',label)

#改变k值
model1=KMeans(n_clusters=4,random_state=0)
model1.fit(x)

image-20220227221733893

1
2
3
#改变k值
model2=KMeans(n_clusters=8,random_state=0)
model2.fit(x)

image-20220227221744681

由观察可知,k越小的时候,从一个层级到另一个层级过度的较快,轮廓较为清晰,k越大的时候,层级之间的过度较慢,轮廓较为模糊。

异常检测:根据输入数据,对不匹配预期模式的数据进行识别。

监督式异常检测:提前使用带“正常”与“异常”标签的数据对模型进行训练,机器基于训练好的模型判断新数据是否为异常数据。

无监督式异常检测:通过寻找与其他数据最不匹配的实例来检测出未标记测试数据的异常。

数据降维:在一定的限定条件下,按照一定的规则,尽可能的保留原始数据集重要信息的同时,降低数据集特征的个数。

随着特征数量越来越多,为了避免过拟合,对样本数量的需求会以指数速度增长。

数据降维最常用的方法:主成分分析(PCA),

也称主分量分析,按照一定规则把数据变换到一个新的坐标系统中,使得任何数据投影后尽可能可以分开(新数据尽可能不相关,分布方差最大化)。

计算过程:

  1. 数据预处理(数据分布标准化:u=0,o=1)。
  2. 计算协方差矩阵特征向量、及数据在各特征向量投影后的方差。
  3. 根据需求(任务指定或方差比例)确定降维维度k。
  4. 选取k维特征向量,计算数据在其形成空间的投影。

异常消费行为检测:

1
2
3
4
5
#数据加载
import pandas as pd
import numpy as np
data=pd.read_csv('task1_data.csv')
data.head()

image-20220305142048582

1
2
3
4
5
6
7
8
#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x')
plt.title('raw data')
plt.xlabel('frequency')
plt.ylabel('payment')
plt.show()

image-20220305143951886

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#赋值
x=data
x1=data.loc[:,'frequence']
x2=data.loc[:,'payment']

#数据分布的可视化操作
fig2=plt.figure(figsize=(20,5))

fig2_1=plt.subplot(121)
plt.hist(x1,bins=100)#柱状图,切割成100份
plt.title('frequency data')
plt.xlabel('frequency')
plt.ylabel('counts')

fig2_2=plt.subplot(122)
plt.hist(x2bins=100)#柱状图,切割成100份
plt.title('payment data')
plt.xlabel('payment')
plt.ylabel('counts')

image-20220305223113217

1
2
3
4
5
6
7
8
9
10
11
#计算平均值u,以及标准差sigma
x1_mean=x1.mean()
x1_sigma=x1.std()
#x2同理

#计算基于高斯分布的概率密度函数
from scipy.stats import norm
x1_range=np.linspace(0,10,300)#将0到10分成300份
x1_normal=norm.pdf(x1_ramge,x1_mean,x1_sigma)
x2_range=np.linspace(0,400,300)
x2_normal=norm.pdf(x2_range,x2_mean,x2_sigma)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#原始数据的高斯分布概率密度函数的可视化
fig3=plt.figure(figsize(20,15))

fig3_1=plt.subplot(121)
plt.plot(x1_range,x1_normal)
plt.title('x1(frequency) Gaussian Distribution')
plt.xlabel('x1(frequency)')
plt.ylabel('p(x1)')

fig3_2=plt.subplot(122)
plt.plot(x2_range,x2_normal)
plt.title('x2(payment) Gaussian Distribution')
plt.xlabel('x2(payment)')
plt.ylabel('p(x2)')
plt.show()

image-20220305225833616

1
2
3
4
5
6
7
8
9
10
#建立异常检测模型
from sklearn.covariance import EllipticEnvelope
model=EllipticEnvelope(contamination=0.03)
model.fit(x)

#模型预测
y_predict=model.predict(x)

plt.scatter(data.loc[:,'frequency'][y_predict==1],data.loc[:,'payment'][y_predict==1],marker='o',facecolor='none',edgecolor='red',s=150,label='anomaly_data')#红色空心和大小
plt.legend()

image-20220306134407329

当contamination=0.2时

image-20220306134836497

由此可见,当阈值增大时,检测出的异常数据的比例也因此增大。

PCA+逻辑回归预测检查者是否患糖尿病

1
2
3
4
5
#数据加载
import pandas as pd
import numpy as np
data=pd.read_csv('task2_data.csv')
data.head()

image-20220306162432375

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#赋值
x=data.drop(['label'],axis=1)
y=data.loc[:,'label']

#逻辑回归模型
from sklearn.linear_model import LogisticRegression
model1=LogisticRegression(max_iter=1000)#更新最大迭代次数
model1.fit(x,y)

#结果预测
y_predict=model1.predict(x)

#模型评估
from sklearn.metrics import accuracy_score
accuracy=accutacy_score(y,y_predict)
1
2
3
4
5
6
7
8
9
#数据标准化
from sklearn.precessing import StandardScaler
x_norm=StandardScaler().fit_transform(x)

#计算均值与标准差
x1_mean=x.loc[:,'glucise'].mean()
x1_norm_mean=x_norm[:,1].mean()#取第二列,坐标为1,因为格式变化,所以索引方式不同
x1_sigma=x.loc[:,'glucose'].std()
x1_norm_sigma=x_norm[:,1].std()
1
2
3
4
5
6
7
8
9
10
#可视化
from matplotlib import pyplot as plt
fig1=plt.figure(figsize=(12,5))

fig1_1=plt.subplot(121)
plt.hist(x.loc[:,'glucose'],bins=100)

fig1_2=plt.subplot(122)
plt.hist(x_norm[:,1],bins=100)
plt.show()

image-20220306164900034

1
2
3
4
5
6
7
#pca分析
from sklearn.decomposition import PCA
pca=PCA(n_components=8)
x_pca=pca.fit_transform(x_form)
#计算分析后各成分的方差以及方差比例
var=pca.explained_variance_
var_ratio=pca.explained_variance_ratio_
1
2
3
4
#可视化方差比例
fig2=plt.figure(figsize=(10,5))
plt.bar([1,2,3,4,5,6,7,8],var_ratio)
plt.show()

image-20220306183137392

1
2
3
4
#数据降维到2维
pca=PCA(n_components=2)
x_pca=pca.fit_transform(x_norm)
print(x_pca.shape,x_norm.shape)

image-20220306185414925

由此可见,通过pca将原本八维的数据降维成了二维。

1
2
3
4
5
6
#降维数据的可视化
fig3=plt.figure()
plt.scatter(x_pca[:,1][y==0],x_pca[:,1][y==0],marker='x',label='negative')
plt.scatter(x_pca[:,1][y==1],x_pca[:,1][y==1],marker='*',label='positive')
plt.legend()
plt.show()

image-20220306193036424

1
2
3
4
5
6
7
#降维后的模型建立与训练
model2=LogisticRegression()
model2.fit(x_pca,y)

#模型预测
y_predict_pca=model2.predict(x_pca)
accuracy_pca=accuracy_score(y,y_predict_pca)

Start Up For Machine Learning

人工智能,亦称智机器智能,指由人制造出来的机器所表现出来的智能。人工智能的核心问题包括建构能够跟人类似甚至超卓的推理、知识、规划、学习、交流、感知、移物、使用工具和操控机械的能力等。

机器学习从数据中自动分析获得规律,并利用规律对未知数据进行预测或用于解决实际问题的方法。

机器学习的应用场景:

  1. 数据挖掘。
  2. 机器视觉。
  3. 语言理解。
  4. 无人驾驶、机器人。
  5. 病例分析。

关于sklearn:针对机器学习应用而开发的算法库。常用功能有:数据预处理、分类、回归、降维、模型选择等常用的机器学习算法。

三大优点:

  1. 丰富的算法模块。
  2. 易于安装和使用。
  3. 样例丰富、教程文档详细。

基于面积的单因子房价预测

1
2
3
4
5
#数据加载
import pandas as pd
import numpy as np
data=pd.read_csv('task1_data.csv')
data.head()
1
2
3
4
5
6
7
#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(x,y)#散点图
plt.xlabel('size(x)')
plt.ylabel('price(y)')
plt.show()
1
2
3
4
#x,y赋值
x=data.loc[:,'面积']#面积为自变量
y=data.loc[:,'房价']#房价为因变量
print(x,y)
1
2
3
4
5
6
7
8
#数据格式转化(方便运算)
x=np.array(x)
y=np.array(y)
print(x.shape,y.shape)
#将一维变为二维
x=x.reshape(-1,1)#行数不变,列数变为1
y=y.reshape(-1,1)
print(x.shape,y.shape)
1
2
3
4
5
#创建模型实例
from sklearn.linear_model import LinearRegression
model=LinearRegression()
#模型训练
model.fit(x,y)
1
2
3
4
5
6
7
8
9
10
11
#获取线性回归模型系数
a=model.coef_#斜率
b=model.intercept_#截距
print(a,b,"y=f(x)={}*x+{}".format(a[0][0],b[0]))#ax+b

#结果预测
y_predict=a[0][0]*x+b[0]
print(y_predict)
#第二种预测的方法
y_predict2=model.predict(x)
print(y_predict2)
1
2
3
4
#预测面积为100时,对应的价格
X_test=np.array([[100]])#转换为数组
y_test_p=model.predict(X_test)
print(y_test_p)
1
2
3
4
5
6
#模型评估
from sklearn.metrics import mean_squared_error,r2_score
MSE=mean_squared_error(y,y_predict)#均方误差
R2=r2_score(y,y_predict)
print(MSE,R2)
#MSE越小越好,R^2越接近1越好
1
2
3
4
5
6
7
8
9
#预测结果可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(x,y,label='y_real')
plt.plot(x,y_predict,label='y_predict')
plt.xlabel('size(x)')
plt.ylabel('price(y)')
plt.legend()#在图中显示标签
plt.show()

多因子房价预测

1
2
3
4
5
#数据加载
import pandas as pd
import numpy as np
data=pd.read_csv('task2_data.csv')
data.head(10)
1
2
3
4
5
6
7
8
9
10
11
12
#可视化
from matplotlib import pyplot as plt
fig=plt.figure(figsize=(20,5))#设置图片大小

fig1=plt.subplot(131)#一行三列第一个图
plt.scatter(data.loc[:,'面积'],data.loc[:,'价格'])

fig2=plt.subplot(132)
plt.scatter(data.loc[:,'人均收入'],data.loc[:,'价格'])

fig3=plt.subplot(133)
plt.scatter(data.loc[:,'平均房龄'],data.loc[:,'价格'])

image-20220214162319845

1
2
3
#x,y赋值
x=data.drop(['价格',axis=1])#按列剔除价格,取其余列
y=data.loc[:,'价格']
1
2
3
4
#多因子模型建立与训练
from sklearn.linear_model import LinearRegression
model_multi=LinearRegression()
model_multi.fit(x,y)
1
2
3
#多因子模型预测
y_predict_multi=model_multi.predict(x)
#模型评估同上
1
2
3
4
5
6
#可视化预测结果
fig3=plt.figure(figsize(8,5))
plt.scatter(y,y_predict_multi)
plt.xlabel('real price')
plt.ylabel('predicted price')
plt.show

image-20220214162528945

点集越集中说明模型拟合度越好。

1
2
3
#预测面积=160,人均收入=70000,平均房龄=5的合理房价
x_test=np.array([[160,70000,5]])
y_test_predict=model_multi.predict(x_test)

分类任务与逻辑回归

现实案例如:垃圾短信检测

如何实现:

  1. 收集一些样本,告诉计算机那些是垃圾信息。
  2. 计算机自动寻找垃圾信息共同特征。
  3. 在新信息中检测是否包含垃圾信息特征内容,判断其是否为垃圾信息。
  4. 部分特征:发件人、是否群发、网址、元、赢、微信、免费等。

又如:图像识别,手写数字识别,股票涨跌预测

分类预测:根据数据类别和部分特征信息,自动寻找类别与特征信息的关系,判断一个新的样本属于那种类别。

逻辑回归实现产品分类

1
2
3
4
5
#数据加载
import pandas as pd
import numpy as np
data=pd.read_csv('task1_data.csv')
data.head()

image-20220218233941341

1
2
3
4
5
6
7
8
#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(data.loc[:,'尺寸1'],data.loc[:,'尺寸2'])
plt.title('size1-size2')
plt.xlabel('size1')
plt.ylabel('size2')
plt.show()

image-20220216095652611

1
2
3
#建立一个用于筛选类编的变量
mask=data.loc[:,'y']==1
print(mask)
1
2
3
4
5
6
7
8
#重新数据可视化
ok=plt.scatter(data.loc[:,'尺寸1'][mask],data.loc[:,'尺寸2'][mask])#正样本
ng=plt.scatter(data.loc[:,'尺寸1'][~mask],data.loc[:,'尺寸2'][~mask])#反样本
plt.title('size1-size2')
plt.xlabel('size1')
plt.ylabel('size2')
plt.legend((ok,ng),('ok','ng'))
plt.show()

image-20220216112537683

1
2
3
4
#x,y赋值
x=data.drop(['y'],axis=1)
y=data.loc[:,'y']
x.head()
1
2
3
4
5
6
#创建模型实例
from sklearn.linear_model import LogisticRegression
model=LogisticRegression()

#模型训练
model.fit(x,y)
1
2
3
4
#模型预测
y_predict=model.predict(x)
y_test=model.predict([1,10])
print('ok'if y_test==1 else 'ng')

准确率=正确预测样本数量/总样本数量。

1
2
3
#模型评估
from sklearn.metrics import accuracy_score
accuracy=accuracy_score(y,y_predict)

image-20220217163930239

1
2
3
4
5
6
#通过边界函数计算边界
theta0=model.intercept_
theta1,theta2=model.coef_[0][0],model.coef_[0][1]
x1=data.loc[:,'尺寸1']
x2_new=-(theta0+theta1*x1)/theta2
plt.plot(x1,x2_new)#边界曲线

边界函数如图:

image-20220217165339155

商业异常消费数据预测:线性边界的逻辑回归模型效果并不好,因此要建立二项式边界的逻辑回归模型。

1
2
3
4
5
#数据加载
import numpy as np
import pandas as pd
data=pd.read_csv('task2_data.csv')
data.head()

image-20220221093541661

1
2
3
4
5
6
7
8
数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(data.loc[:,'pay1'],data.loc[:,'pay2']'y')
plt.title('pay1-pay2')
plt.xlabel('pay1')
plt.ylabel('pay2')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
#创建mask
mask=data.loc[:,'y']==1#等于1则为true
fig1=plt.figure()
abnormal=plt.scatter(data.loc[:,'pay1'][mask],data.loc[:,'pay2'][mask])
normal=plt.scatter(data.loc[:,'pay1'][~mask],data.loc[:,'pay2'][~mask])

plt.plot(x1,xw_new)
plt.title('pay1-pay2')
plt.xlabel('pay1')
plt.ylabel('pay2')
plt.legend((abnormal,normal),('abnormal','normal'))
plt.show()

image-20220217174122101

1
2
3
#x,y赋值
x=data.drop(['y'],axis=1)
y=data.loc[:,'y']
1
2
3
4
5
6
7
8
9
#生成二阶数据
x2=data.loc[:,'pay2']
x1_2=x1*x1#x1的平方
x2_2=x2*x2
x1_x2=x1*x2

#创建新的输入数据
x_new={'x1':x1,'x2':x2,'x1_2':x1_2,'x2_2':x2_2,'x1_x2':x1_x2}#创建一个字典
x_new=pd.DataFrame(x_new)#转化格式
1
2
3
4
5
6
7
8
9
#建立新模型
LR2=logisticRegression()
LR2.fit(x_new,y)

#模型预测
y2_predict=LR2.predict(x_new)

#准确率
accuracy2=accuracy_score(y,y2_predict)
1
2
3
#获取边界函数系数、生成新的边界数据
theta0=LR2.intercept_
theta1,theta2,theta3,theta4,theta5=LR2.coef_[0][0],LR2.coef_[0][1],LR2.coef_[0][2],LR2.coef_[0][3],LR2.coef_[0][4]

image-20220221222531805

1
2
3
4
a=theta4
b=theta5*x1+theta2
c=theta0+theta1*x1+theta3*x1*x1
x2_new_2=(-b+np.sqrt(b*b-4*a*c))/(2*a)
1
2
3
4
5
6
7
8
9
10
fig2=plt.figure()
abnormal=plt.scatter(data.loc[:,'pay1'][mask],data.loc[:,'pay2'][mask])
normal=plt.scatter(data.loc[:,'pay1'][~mask],data.loc[:,'pay2'][~mask])

plt.plot(x2,x2_new_2)
plt.title('pay1-pay2')
plt.xlabel('pay1')
plt.ylabel('pay2')
plt.legend((abnormal,normal),('abnormal','normal'))
plt.show()

image-20220221223033531

此时图像的边界较为杂乱,因为x1的排列并不是按从小到大的顺序进行的,因此解决方案是将x1排序。

1
2
3
#排续
x1_new=x1.sort_values()#从小到大排列
#替换

image-20220221223329061

1
2
3
4
#新样本预测 pay1=80,pay2=20
x_test=np.array([[80,20,80*80,20*20,80*20]])
y_predict=LR2.predict(x_test)
print('abnormal' if y_predict==1 else 'normal')

K近邻分类模型:通过计算新数据与训练数据之间的距离,然后选取K(K>=1)个距离最近的邻居进行分类判断(K个邻居),这K个邻居多数属于某个类,就把该数据实例分类到这个类中。

欧氏距离:两点之间的直线距离,KNN计算中应用最多的距离。

曼哈顿距离:两个点在标准坐标系上的绝对轴距总和。如图:

image-20220222170601294

一般来说,K值越小,分类边界越曲折,抗干扰性更弱(噪声数据影响结果明显)。

信息熵:是度量随机变量不确定性的指标,熵越大,样本的不确定性就越大。假定当前样本集合D中第K类样本所占比例为Pk,则D的信息熵为:

image-20220222212212164

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

概率是反应随机事件出现的可能性大小的量度,而条件概率则是给定某事件A的条件下,另一个事件B发生的概率。全概率公式则是利用条件概率将复杂事件A分割成若干简单事件概率的求和问题。贝叶斯公式则是利用条件概率和全概率公式计算后验概率

决策树判断员工是否适合相关工作:

关于一些sklearn中的用法:

criterion=’entropy’:以信息熵的变化作为建立树结构的标准。

min_samples_leaf=5:建立树结构最小分支的样本数。

1
2
3
4
5
#数据加载
import pandas as pd
import numpy as np
data=pd.read_csv('task1_data.csv')
data.head()
1
2
3
4
5
6
7
8
9
10
#x,y赋值
x=data.drop(['y'],axis=1)
y=data.loc[:,'y']

#建立决策树模型
from sklearn.tree import DecisionTreeClassifier
model=DecisionTreeClassifier(criterion='entropy',min_samples_leaf=5)

#模型预测
model.fit(x,y)
1
2
3
4
5
#模型预测
y_predict=model.predict(x)
#准确率指标评估
from sklearn.metrics import accuracy_score
accuracy=accuracy_score(y,y_predict)
1
2
3
4
#测试样本预测
x_test=np.array([[1,0,1,1]])
y_test_predict=model.predict(x_test)
print('适合' if y_test_predict==1 else '不适合')
1
2
3
4
5
#作图
from matplotlib import pyplot as plt
fig1=plt.figure(figsize=(200,200))
from sklearn import tree
tree.plt_tree(model,filled='True',feature_names=['Skill','Experience','Degree','Income'],class_names=['Unqualified','Qualified'])#filled为填充

由于图片比较大,因此将图片保存在本地

1
fig1.savefig('dc_result.png')

为了达到较好的准确度,一般适当提高最小样本叶子树(避免过拟合)。

1
model2=DecisionTreeClassifier(criterion='entropy',min_samples_leaf=50)

参考图如下(不全):

image-20220223222354931

1
2
3
#设置字体
import matplotlib as mpl
mpl.rcParams['font.family']='SimHei'

image-20220223222621219

朴素贝叶斯预测学生录取及奖学金情况:

1
2
3
4
5
#数据加载
import numpy as np
import pandas as pd
data=pd.read_csv('task2_data_csv')
data.head()
1
2
3
4
5
6
7
8
9
#x,y赋值
x=data.drop(['y',axis=1])
y=data.loc[:,'y']

#创建朴素贝叶斯模型并训练
from sklearn.naive_bayes import CategoricalNB
model=CategoricalNB()
#模型训练
model.fit(x,y)
1
2
3
4
5
6
7
8
9
#训练数据的概率预测
y_predict_prob=model.predict_proba(x)#每个类别有个对应的概率

#训练预测
y_predict=model.predict(x)

#计算模型准确率
from sklearn.metric import accuracy_score
accuracy=accuracy_score(y,y_predict)
1
2
3
4
5
6
7
8
#测试样本预测
x_test=np.array([[2,1,1,1,1]])
y_test_prob=model.predict_proba(x_test)
y_test_predict=model.predict(x_test)
#5个测试样本预测
x_test=np.array([[2,1,1,1,1],[2,1,1,1,0],[2,1,1,0,0],[2,1,0,0,0],[2,0,0,0,0]])
y_test_prob=model.predict_proba(x_test)
y_test_predict=model.predict(x_test)
1
2
3
#数据组合
test_data_result=np.concatenate((x_test,y_test_predict_prob,y_test_predict.reshape(5,1)),axis=1)#axis=1为按列,如果不reshape组合会不能完成
print(test_data_result)

image-20220224115946640

1
2
3
#格式转化
test_data_result=pd.DataFrame(test_data_result)
test_data_result.head()

image-20220224153405317

1
2
#列名称替换
test_data_result.columns=['score','school','award','gender','english','p0','p1','p2','y_test_predict']

image-20220224153854681

1
test_data_result.to_csv('test_data_result.csv')

Basic Math For AI

在简单的对python有了基础的了解之后,我们的下一步的目标是对机器学习和人工智能进行初步的了解,但是,需要知道的是,机器学习和人工智能中包含着大量的数学知识,如果不对这些基础的知识进行学习,日后的学习中将难以深入一些算法,因此在此处我们先对一些必须的基础数学知识进行了解。

首先我们应该了解到,人工智能模型可以被理解成一个多元函数,有输入X,模型f(x)和输出Y。如图:

image-20220205231110405

其次,我们了解到,对于图片来说,每一个图片都是像素的三维矩阵,其中拥有红绿蓝(RGB)的三通道,如图:

image-20220206145122283

image-20220206145208783

关注,用A矩阵的转置和B矩阵相乘时:

1
2
3
4
5
6
import numpy as np
x=np.linspace(1,10,1000)#将1到10分成1000份
A=np.array([[5,2][4,3][1,1]])
B=np.array([[2,7][9,3][1,5]])
np.dot(A.T,B)
np.dot(A,B.T)

有关导数在机器学习中的应用:梯度下降,机器学习常常通过梯度下降来对模型函数进行优化。通过向函数上当前点的对应梯度(导数)的反方向的规定的步长距离点进行迭代搜索,直到在极小点收敛。

在深度学习中,如图像识别,大部分的识别结果都是一个概率,因此概率与统计也被成为AI模型的评估和优化,其中,我们用平均值标准差来评估模型的表现(如猫狗识别)和优化输入数据(如预测房价对输入数据进行归一化)。

1
2
3
4
#生成随机数
np.random.randn(10000)#高斯分布,平均值为0,标准差为1
np.random.randn(10000)*2#平均值为0,标准差为2
np.random.randn(10000)+1#平均值为1,标准差为1
1
2
tmp=np.random.randn(10000)
np.sum(tmp>0)#接近5000

image-20220207220907537

1
2
3
4
5
#蒙特卡洛近似
dots=np.random.rand(10000,2)#等效为坐标
#随机分布一定位于0到1,而高斯分布则不是。
rad=np.sqrt(dots[:,0]**2+dots[:,1]**2)#通过x,y坐标平方取根求半径
np.sum(rad<=1)#可以估算Π

接着是机器学习与深度学习的模块,其中,深度学习包括:

  1. 全连接神经网络。
  2. 卷积神经网络。
  3. 循环神经网络。

机器学习的本质:以数据为驱动,自主的从数据种寻找规律的方法。

  1. 更少的人为假设和定义。
  2. 更灵活的应用。
  3. 更高的准确度。

通过机器学习可以获得模型,常见的机器学习的方法有:

  1. 非监督学习。(聚类)
  2. 监督学习。(分类,量化预测)
  3. 强化学习。(无初始数据)
  4. 优化。

回归:根据已有的数据,建立因变量Y和自变量X的定量(函数)关系的模型。

通过均方误差来评价回归模型的好坏。

求解线性回归有两个方法,分别是最小二乘法梯度下降法

1
2
3
4
5
6
7
8
9
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%pip install sklearn
import sklearn
x=np.linspace(1,100,100)
y=5*x+10+10*np.random.randn(100)
plt.plot(x,y,".k")#黑色点图

image-20220208224733637

1
2
3
4
5
6
7
from sklearn.linear_model import LinearRegression
model=LinearRegression()

model.fit(x.reshape(100,1),y.reshape(100,1))#若不进行reshape则无法进行运算
y_p=model.predict(x.reshape(100,1))
plt.plot(x,y,".k")
plt.plot(x,y_p,"b")#蓝线

image-20220209142350814

1
2
#模型预测:
model.predict(np.array(10).reshape(1,1))#注意要进行reshape!

读入外部数据多元线性回归

1
2
3
4
5
6
7
8
9
10
data=pd.read_csv('data.csv')
x=data[:,1:3]#1至3列
y=data[:,3]#第三列

form sklearn.linear_model import LinearRegression
model=LinearRegression()
model.fit(x,y)#训练

predict=model.predict(x)
plt.plot(y,predict,".b")#真实值为x轴,预测值为y轴

image-20220209164309337

由此可见拟合度是较好的。

计算误差如下:

1
2
3
diff=predict-y
mae=np.mean(np.abs(diff))#平均误差
rmse=np.sqrt(np.mean(diff**2))#均方误差

关于逻辑运算逻辑运算又称为布尔运算,是通过数学方法研究逻辑问题来建立了逻辑演算。

布尔值:是(True,1),否(False,0)

逻辑运算常用来搭建AI配套模型来实现具体应用。

深度强化学习:深度强化学习神经网络模型+强化学习方法。

马尔科夫链:状态空间中经过从一个状态到另一个状态的转换的随机过程,下一状态的概率分布只能由当前状态决定,且与它前面的事件均无关。

数学表达为:

image-20220209223825640

假设有三种天气状态(晴天、阴天、下雨),在第二天的状态只取决于前一天的天气状态。

  1. 第一天晴天,第二天70%晴天,20%阴天,10%下雨。
  2. 第一天阴天,第二天40%晴天,40%阴天,20%下雨。
  3. 第一天下雨,第二天20%晴天,40%阴天,40%下雨。

状态转移矩阵可写为:

image-20220209225144605

用已知概率和状态转移矩阵相乘,可以得到对应的预测的概率。

马尔科夫链收敛和平稳的条件

  1. 可能的状态数是有限的。
  2. 状态间的转移概率需要固定不变。
  3. 从任意状态能够转变到任意状态。
  4. 不能是简单的循环,例如全是从x到y再从y到x。

关于马尔科夫奖励过程
马尔科夫过程主要描述的是状态之间的转移关系,在各个状态的转移过程中赋予不同的奖励值就得到了马尔科夫奖励过程。有一个四元组组成(S,P,R,y)

S表示状态集合,P表示状态转移矩阵,R表示奖励函数,y表示衰减因子(0-1)。

马尔科夫决策过程:相比于马尔科夫奖励过程多了一个动作A,A表示决策过程的集合。

强化学习的目标就是最大化期望回报,相应的结果就是找到从状态空间S映射到动作空间A的最优策略。


Basic For Python

python开发环境的准备:Anaconda,Jupyter Notebook,Spyder

Numpy,Pandas,和Matplotlib的使用也是在python学习中非常重要的部分。

本人在按照教程安装完anaconda环境以及对应的idejupyter notebook之后开始正式的python的学习。

(:在本篇博客中,仅对python的各个功能进行最基础的了解。)

首先是python的数据结构列表list,元组tuple,字典dict,集合set:

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
#列表
l=[1,2,3,"hello"]
l.append("world")#在列表的末尾插入元素
l.extend(["a"])#在列表l末尾增加列表
l.insert(0,"lol")#在列表指定位置插入元素
l.remove("lol")#删除列表中出现的第一个lol
del l[3]#删除列表中对应位置的元素
l.pop(4)#删除列表中对应位置的元素

#特别注意!!
a=[1,2,3,4]
b=a
#此时如果对b表进行更改,a表也会随之更改,因此应该设置为:
b=a.copy()

#元组
a=(1,2,3)
#元组中的元素不可被更改

#字典
d={"Name":"Charlie","Job":"Teacher"}
print(d["Name"])
d["age"]=25#添加
del d["age"]#删除

#集合
set([1,2,3,4,2,1,1,1,2,12])
#set仅保留一次(去重)

对于if语句,注意:

1
2
3
4
if a<b:#注意有冒号
c=10
else:#注意有冒号
c=20

对于循环

1
2
3
4
5
6
7
8
9
10
i=0
while i<10:#注意有冒号
i=i+1;

for i in range(10):
print(i)

s="abcdefg"
for i in s:
print(i)

关于函数:

1
2
3
def sumoftwo(x,y):
result=x+y
return result

文件的IO:

1
2
3
4
5
6
7
8
9
file=open("text.txt","r")#注意路径
file.read()
file.read(100)#读入元素的个数
file.readline()#读入行的行数
file.readlines()#读入所有行
file=open("test.txt","w")#覆盖
file.write("你好")
file=open("text.txt","a")#加入
file.close()
1
2
3
4
file=open("text.txt","r")
for line in file:
print(line)
file.close()

python模块:

1
2
3
4
5
6
7
8
import time
time.time()#显示时间从1970年1月1日0时0分0秒到现在
time.sleep()#停留时间
time.strftime("%y-%m-%d %H:%M:%S")
#年月日时分秒
import time as t
from time import strftime as t
#简写
1
2
3
4
5
import os
os.getcwd()#查看当前文件盘
os.listdir()#查看某文件盘包含的文件
os.listdir(os.getcwd())
os.mkdir()#生成新文件夹

异常处理:

1
2
try:
except:

在这里可以等效为c++中的异常处理的的trycatch

关于NumpyNumpy是一个运行速度非常快的数学库,主要用与数组计算,包含:

  1. 一个强大的N维数组对象。
  2. 广播功能函数。
  3. 整合代码的工具。
  4. 线性代数、傅里叶变化、随机数生成等功能。

接着,本人在按照教程安装完numpy环境以及对应的idespyder

1
2
3
4
5
6
7
8
9
10
11
12
13
#载入numpy
import numpy as np
#定义ndarray
a=np.array([1,2,3,4])
b=np.array([[1,2,3],[3,2,1]])
c=np.array([[1,2.5,3.14][13.1,2.6,1.2]])
d=np.array([[1,2,3,4]])#1*4二维数组
#查看指令
a.size
a.shape
b.shape
b.size
b.ndim
1
2
3
4
5
6
np.arrange(20)#生成数字0-19
np.linspace(0,9,10)#生成0-9的浮点数
m=np.zeros([5,5])#生成5*5的全0矩阵
m=np.ones([5,5])#生成5*5的全1矩阵
m=np.random.rand(5,5)#生成5*5的随机矩阵
m=np.random.randn(33)#生成3*3的高斯分布

有关矩阵的运算:

1
2
3
4
5
6
7
8
9
10
11
12
13
a=np.array([1,2,3])
b=a.copy()
c=a+b#[2,4,6]
c=a*b#[1,4,9]
d=np.dot(a,b)#[1,4,9]
#注意reshape元素数量要一致!
ax=np.reshape(a,(3,1))#更改矩阵
bx=np.reshape(b,(1,3))
np.dot(ax,bx)#矩阵乘法3*3

np.vstack()#竖直方向拼接vertically
np.hstack()#水平方拼接horizontally
a.T#矩阵转置

向量和矩阵的索引:

1
2
3
4
5
6
7
8
9
10
a=np.array([0,1,2,3,4,5,6,7,8,9])
a[0:5]#0,1,2,3,4,从第一个开始第五个结束
a[3:]#3,4,5,6,7,8,9
a[3:-1]#3,4,5,6,7,8
a[:3]#0,1,2

b=a.reshape(5,2)
b[3,0]#6
b[3]#[6,7]
b[:0]#[0,2,4,6,8]

Numpy的常用科学计算:

1
2
3
4
5
6
7
8
9
10
np.log(2)#0.69
np.exp(2)#7.38
#作用与向量、矩阵是一样的
np.log(a)#对a中的每个数都求对数
np.max(a)#求a之中最大的数
np.mean(a)#平均数
np.median(a)#中值
np.std(a)#方差
np.argmax()#返回最大值的索引
np.argmin()

生成一个10*10,边界为1,内部为0的矩阵:

1
2
m=np.ones([10,10])
m[1:9,1:9]=0

关于pandaspandas是为了解决数据分析任务而创建的。pandas纳入了大量库和一些标准的数据模型,提供了高效的操作大型数据集所需的工具。

关于matplotlib:matplotlib是基于python语言的开源项目,旨在为python提供一个数据绘图包,实现专业的绘图功能。

1
2
import pandas as pd
data=pd.DataFrame([1,2,3,4]),columns=["number"],index=["a","b","c","d"]

值得一提的是,pandas可以直接导入csv文件。关于pandas中的数据预处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
data1=pd.read_csv('data.csv')
data.to_csv('data_first.csv')
data1.loc[5,"Age"]#第一个为index,第二个为columns不可输入数字
data1.iloc[6,1]#两个索引都可以是数字

pd.concat([data,data1])
data2=pd.read_csv('data.csv')
data3=pd.concat([data1,data2])
data4=data3.append([data1,data2])
#有没有的部分会被设成nan
data.isnull()#判断nan的位置
#True的位置为nan
data.dropna()#删去含有nan的行
data.fillna(0)#将nan值全部填为0

关于pandas中的常用函数:

1
2
3
4
5
6
7
8
data.drop(2)#删去第二行(与index对应)
data1["Age"].mean
#各种函数同numpy
data1.sort_values(by="Age")#根据年龄大小进行排序
data1.sort_values(by="Job")#根据首字母的顺序进行排序(a开始)

temp=data3["Age"].values#array of float
data3["Age"].describe()#自动统计,快速查看某一列的统计数据

用matplotlib进行画图:

1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt
x=np.linspace(0,10,100)
y=np.six(x)

plt.plot(x,y)#将定义的x,y画入图中
plt.xlabel("x")
plt.ylabel("y")
plt.title("asdf123")
plt.grid(True)#背景网格
plt.show()

可画出如下的图案:

image-20220130154128301

1
2
3
4
5
6
7
8
9
10
11
y1=np.six(x)
y2=np.exp(x)

plt.figure()

plt.subplot(1,2,1)#1行2列第一个图
#将两个图分开
plt.plot(x,y1,"r")#red

plt.subplot(1,2,2)
plt.plot(x,y2,"g")#green

可画出如下的图案:

image-20220130162502084

1
2
3
4
5
6
plt.xlim()#显示x轴的区间
plt.ylim()#显示y轴的区间
"r."#只有点
"r.-"#点行
"r--"#虚线连接
plt.imshow()#展示图片

在最后,我们进行简单的网络爬虫的学习。有关爬虫:可以自动的获取网页内容的程序,能够高效获得网上的海量数据。

过程如下:

  1. 通过网址和DNS服务器找到服务器主机。
  2. 发送请求获得浏览器结果。
  3. 解析获得浏览器呈现的结果。

几种常见的爬虫工具:

  1. Urllib
  2. Requests(页面级)
  3. Scarpy(网站级)
  4. Selenium

对于status_code:

  1. 2字头:代表请求已经被服务器成功接收和理解。
  2. 3字头:重新定向。
  3. 4字头:客户端发生错误。
  4. 5,6字头:服务器发生错误或异常。
1
2
3
4
import requests
data=requests.get("https://www.csdn.net")
data.encoding="utf-8"#显示中文
data.text#网站源代码

爬虫静态网站实战:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
form bs4 import BeautifulSoup

url=#静态网站网址定义
header={"user-agent":"Mozilla/5.0"}#反爬机制
data=requests.get(url=url,headers=header)
html=data.text
#可以运用chrome中的开发者工具

soup=BeautifulSoup(html,"lxml")
lis=soup.find_all(name="div",attrs="id":"row355")

i=0
for li in lis:
temp=li.find(name="div",attrs={"_index":str(i)})
i=i+1
print(temp.text)

About The Git

关于git

在我们运用hexo搭建个人博客的时候,不难发现需要运用到一些关于github仓库的一些知识,因此在这里进行一些基础知识的学习。

首先,git本身是一种分布式版本控制的系统,它没有”中央服务器“,每个人的电脑上都是一个完整的版本库而且具有高安全性。git是一款免费的,开源的分布式版本控制系统,github是用git做版本控制的代码托管平台。

创建远程仓库

  1. 确认秘钥的保存路径。
  2. 如果上一步置顶的保存路径下已经有秘钥文件,则需要确认是否覆盖。
  3. 创建密码。
  4. 确认密码。

常见命令

  1. git status用于查看工作目录当前状态。
  2. git add用于将修改放入暂存区。(git add.用于所有文件添加)。
  3. git commit -m用于将代码文件提交到本地仓库。
  4. 第一次使用时:git remote add origin+路径,添加远程仓库,仓库名为origin。
  5. git push -u提交到github。
  6. 在github上创建-README md。
  7. git pull origin master用于获取远程仓库变动并直接更新到本地仓库中。

基本原理

如图:

Git版本管理

  1. git log命令显示从最近到最远的提交日志。
  2. git reset –hard HEAD~2回退到前两个版本。
  3. git reflog查看命令历史。
  4. git reset –hard commit_id跳转到对应的版本。
  5. git status查看当前状态。

ps:这是本人第一次写blog,有很多不足之处,还请大家多多包涵!