总结
1.机器学习概念:
机器学习( Machine Learning )就是通过对海量数据信息进行学习得出一个数学模型,使其具有强大的预测能力。
机器学习已经有了十分广泛的应用,例如:数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA序列测序、语音和手写识别、战略游戏和机器人运用。
2.研究内容
- 分类(classification):将实例数据划分到合适的类别中。
应用实例:判断网站是否被黑客入侵(二分类 ),手写数字的自动识别(多分类)- 回归(regression):主要用于预测数值型数据。
应用实例:股票价格波动的预测,房屋价格的预测等。
3.应用
文档分类
搜索引擎: 根据你的搜索点击,优化你下次的搜索结果,是机器学习来帮助搜索引擎判断哪个结果更适合你(也判断哪个广告更适合你)。
垃圾邮件: 会自动的过滤垃圾广告邮件到垃圾箱内。
超市优惠券: 你会发现,你在购买小孩子尿布的时候,售货员会赠送你一张优惠券可以兑换6罐啤酒。
邮局邮寄: 手写软件自动识别寄送贺卡的地址。
申请贷款: 通过你最近的金融活动信息进行综合评定,决定你是否合格。
监督学习与非监督学习
监督学习:利用一组已知类别的样本调整分类器的参数,使其达到所要求性能的过程
非监督学习:在没有类别信息情况下,通过对所研究对象的大量样本的数据分析实现对样本分类的一种数据处理方法。
强化学习:这个算法可以训练程序做出某一决定。程序在某一情况下尝试所有的可能行动,记录不同行动的结果并试着找出最好的一次尝试来做决定。 属于这一类算法的有马尔可夫决策过程。
拟合程度
欠拟合(Underfitting):模型没有很好地捕捉到数据特征,不能够很好地拟合数据,对训练样本的一般性质尚未学好。类比,光看书不做题觉得自己什么都会了,上了考场才知道自己啥都不会。
过拟合(Overfitting):模型把训练样本学习“太好了”,可能把一些训练样本自身的特性当做了所有潜在样本都有的一般性质,导致泛化能力下降。类比,做课后题全都做对了,超纲题也都认为是考试必考题目,上了考场还是啥都不会。
画决策树
数据集包含17个训练样例,为二分类分别为好瓜和坏瓜,好瓜占p1=8/17,坏瓜占p2=9/17.
- 计算根节点信息熵
Ent(D)=−∑k=22pklog2pk=−(817log2817+917log2917)=0.998Ent(D) = -\sum_{k=2}^2{p_klog_2p_k}=-(\frac{8}{17}log_2{\frac{8}{17}}+\frac{9}{17}log_2{\frac{9}{17}})=0.998Ent(D)=−∑k=22pklog2pk=−(178log2178+179log2179)=0.998- 计算属性的信息增益
以属性色泽为例
记D1(青绿),D2(乌黑),D3(浅白)
D1中,总共有6个样例,好瓜占 p1=3/6,坏瓜占p2=3/6;D2中,总共有6个样例,好瓜占 p1=4/6,坏瓜占p2=2/6;D3中,总共有5个样例,好瓜占 p1=1/5,坏瓜占p2=4/5.
Ent(D1)=−(36log236+36log236)=1Ent(D1)=-(\frac{3}{6}log_2{\frac{3}{6}}+\frac{3}{6}log_2{\frac{3}{6}})=1Ent(D1)=−(63log263+63log263)=1
Ent(D2)=0.918Ent(D2)=0.918Ent(D2)=0.918
Ent(D3)=0.722Ent(D3)=0.722Ent(D3)=0.722
属性色泽的信息的增益为
Gain(D,色泽)=Ent(D)−∑v=13DvDEnt(Dv)Gain(D,色泽)=Ent(D)-\sum_{v=1}^3{\frac{D_v}{D}Ent(D_v)}Gain(D,色泽)=Ent(D)−∑v=13DDvEnt(Dv)
=0.998-(6/171+6/170.918+5/17*0.722)
=0.109- 计算出其他属性的信息增益
G(D,根蒂)=0.143;G(D,敲声)=0.141;
G(D,纹理)=0.381;G(D,脐部)=0.289;
G(D,触感)=0.006
显然,纹理信息增益最大,被选为划分属性- 基于纹理属性对根节点对属性划分
纹理=清晰分支
根蒂,脐部,触感均获得最大的信息增益,选其一作为划分属性
编程题:
请使用python语言编程程序实现对于输入任意温度表示的温度值转换为对应另外一种温度表示并输出。
TempStr = input("请输入带有符号的温度值:")
if TempStr[-1] in ['f', 'F']:
C = (eval(TempStr[0:-1]) - 32) / 1.8
print("转换后的温度是{:.2f}C".format(C))
elif TempStr[-1] in ['c', 'C']:
F = 1.8 * eval(TempStr[0:-1]) + 32
print("转换后的温度是{:.2f}F".format(F))
else:
print("输入格式错误")
聚类
k-Means算法实现过程如下:
(1)导入数据:收集并准备数值型矩阵作为原始数据集;
(2)创建初始质心:指定聚类数k,从原始数据集中随机选取k个对象作为初始质心;
(3)分配:计算数据集中每个对象到所有质心的距离,并将数据点分配到距离最接近的质心,从而形成簇分配矩阵;
(4)重新计算质心:计算簇中所有点的均值,并将均值作为新的质心。
(5)反复执行(3)和(4),直至质心不再移动。
import numpy as np
import matplotlib.pyplot as plt
def loadFile(path):
dataList = []
#打开文件:以二进制读模式、utf-8格式的编码方式打开
fr = open(path,"r",encoding='UTF-8')
record = fr.read()
fr.close
#按照行转换为一维表即包含各行作为元素的列表,分隔符有'\r', '\r\n', \n'
recordList = record.splitlines()
#逐行遍历:行内字段按'\t'分隔符分隔,转换为列表
for line in recordList:
if line.strip():
dataList .append(list(map(float, line.split('\t'))))
#返回转换后的矩阵
recordmat = np.mat(dataList )
return recordmat
def distEclud(vecA, vecB):
return np.linalg.norm(vecA-vecB, ord=2)
def randCents(dataSet, k):
n = np.shape(dataSet)[1]
cents = np.mat(np.zeros((k,n)))
for j in range(n):
#质心必须在数据集范围内,也就是在min到max之间
minCol = min(dataSet[:,j])
maxCol = max(dataSet[:,j])
#利用随机函数生成0到1.0之间的随机数
cents [:,j] = np.mat(minCol + float(maxCol - minCol) * np.random.rand(k,1))
return cents
def kMeans(dataset, k):
m = np.shape(dataset)[0]
ClustDist = np.mat(np.zeros((m, 2)))
cents = randCents(dataset, k)
clusterChanged = True
# 循环迭代,得到最近的聚类中心
while clusterChanged:
clusterChanged = False
for i in range(m):
DistList = [distEclud(dataset[i, :], cents[jk,:]) for jk in range(k)]
minDist = min(DistList)
minIndex = DistList.index(minDist)
if ClustDist[i, 0] != minIndex:
clusterChanged = True
ClustDist[i, :] = minIndex, minDist
# 更新聚类
for cent in range(k):
ptsInClust = dataset[np.nonzero(ClustDist[:, 0].A == cent)[0]]
# 更新聚类中心cents,axis=0按列求均值
cents[cent, :] = np.mean(ptsInClust, axis=0)
# 返回聚类中心和聚类分配矩阵
return cents, ClustDist
path_file = "testdata.txt"
recordMat = loadFile(path_file)
k = 4
cents, distMat = kMeans(recordMat, k)
# 绘制数据散点图
for indx in range(len(distMat)):
if distMat[indx, 0] == 0:
plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='red', marker='o')
if distMat[indx, 0] == 1:
plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='blue', marker='o')
if distMat[indx, 0] == 2:
plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='cyan', marker='o')
if distMat[indx, 0] == 3:
plt.scatter(recordMat[indx, 0], recordMat[indx, 1], c='green', marker='o')
# 绘制聚类中心
x = [cents[i,0] for i in range(k)]
y = [cents[i,1] for i in range(k)]
plt.scatter(x, y, s = 80, c='yellow', marker='o')
plt.show()
K近邻
自己构造数据
import numpy as np
X=np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
y=np.array([1,1,1,2,2,2])
from sklearn.neighbors import KNeighborsClassifier
#参数n_neighbors设置为3,即使用最近的3个邻居作为分类的依据,其他参数保持默认值,并将创建好的实例赋给变量clf。
clf=KNeighborsClassifier(n_neighbors=3)
clf.fit(X,y)
print(clf.predict([[-0.8,-1],[3,3]]))
导入鸢尾花数据
import numpy as np
from sklearn.datasets import load_iris
iris=load_iris()
print(iris.keys())
#print(list(iris.target_names))
#print(iris['target_names'])
print(iris.target_names)
print("Type of target:\n{}".format(iris['target']))
print(iris['feature_names'])
print(iris.data[:5])
print(iris['DESCR'][:225])
print(iris.data.shape)
print(iris.target.shape)
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(iris.data,iris['target'],random_state=0)
print(X_train.shape,y_train.shape)
print(X_test.shape,y_test.shape)
from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train,y_train)
print(knn.predict([[5,2.9,1,0.2]]),iris.target_names[knn.predict([[5,2.9,1,0.2]])])
print("k近邻分类测试精度为:{:.4f}".format(knn.score(X_test,y_test)))
y_pred=knn.predict(X_test)
print("k近邻分类测试精度为:{:.4f}".format(np.mean(y_pred==y_test)))
决策树
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
import numpy as np
iris=load_iris()
dtc = DecisionTreeClassifier()
X_train,X_test,y_train,y_test=train_test_split(iris.data,iris['target'],random_state=0)
dtc.fit(X_train, y_train)
print("k近邻分类测试精度为:{:.4f}".format(dtc.score(X_test,y_test)))
y_pred=dtc.predict(X_test)
print("k近邻分类测试精度为:{:.4f}".format(np.mean(y_pred==y_test)))
print(cross_val_score(dtc, iris.data, iris.target, cv=10))
香农熵
from numpy import linspace, math, zeros
import matplotlib.pyplot as plt
def calcShannonEnt(dataSet):
"""
输入:数据集
输出:数据集的香农熵
描述:计算给定数据集的香农熵
"""
num = len(dataSet) # 样本集总数
classList = [c[-1] for c in dataSet] # 抽取分类信息
# print(classList)
labelCounts = {} # 词典形式存储类别计数
for cs in set(classList): # 对每个类别计数
labelCounts[cs] = classList.count(cs)
# print(labelCounts[cs])
# print(labelCounts['No'])
# print(labelCounts)
shannonEnt = 0.0 # 信息熵
for key in labelCounts:
prob = labelCounts[key] / float(num)
# print(labelCounts[key])
# print(prob)
shannonEnt -= prob * math.log2(prob)
# print(shannonEnt)
return shannonEnt
# 给定数据集
def CreateDataSet():
dataSet = [[1, 1, ' Yes'],
[1, 1, ' Yes'],
[1, 0, 'No'],
[0, 1, 'No'],
[0, 1, 'No']]
labels = ['no surfacing', 'flippers']
# print(labels[0:])
return dataSet, labels
# 计算信息熵
def entropy(prob):
return -prob * math.log2(prob) - (1 - prob) * math.log2(1 - prob)
# 绘制信息熵
def plotEnt():
x = linspace(0.001, 0.999, 100)
ent = zeros(100)
for i in range(98):
# print(x[i+1])
ent[i + 1] = entropy(x[i + 1])
plt.figure()
plt.plot(x, ent)
plt.xlabel("x")
plt.title("Entropy")
plt.show()
print("ent MAX is {}".format(max(ent)))
if __name__ == "__main__":
myDat, labels = CreateDataSet()
calcShannonEnt(myDat)
# print(calcShannonEnt(myDat))
plotEnt()
手写数字识别
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits
digits = load_digits()
X = digits.data
y = digits.target
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size =0.2,random_state=666)
knn_clf = KNeighborsClassifier(n_neighbors=3)
knn_clf.fit(X_train,y_train)
y_predict = knn_clf.predict(X_test)
from sklearn.metrics import accuracy_score
accuracy_score(y_test,y_predict)
from sklearn.model_selection import cross_val_score
cross_val_score(knn_clf, X_test, y_test, cv=10)
SVM
复杂性参数C可用于调整容许的间隔错误的总数和严重程度
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import LinearSVC
from sklearn.datasets import make_blobs
# 创建随机分布的,可以分离的400个样本点
X, y = make_blobs(n_samples=400, centers=2, random_state=32)
# 创建LinearSVC对象
clf = LinearSVC(C=10.0)
clf.fit(X, y)
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
# 画出决策函数
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# 网格化评价模型
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# 画分类边界
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
plt.title("Maximum margin using LinearSVC")
plt.show()