一、线性差值
image.png
image.png
import numpy as np
from scipy import interp
import matplotlib.pyplot as plt
# x 和 y之间存在规律,正弦波,每个点之间,间隔
x = np.linspace(0,2*np.pi,10)
y = np.sin(x)
plt.scatter(x,y)
<matplotlib.collections.PathCollection at 0x22e872f5608>
output_2_1.png
a = np.linspace(0,2*np.pi,30)
b = np.interp(a,x,y)#根据x和y之间的关系,对a进行目标值填充
plt.scatter(x,y,color = 'r')
plt.scatter(a,b,color = 'green')
<matplotlib.collections.PathCollection at 0x22e8762c988>
output_3_1.png
from sklearn.neighbors import KNeighborsRegressor
knn = KNeighborsRegressor(weights='distance',n_neighbors = 2)
knn.fit(x.reshape(-1,1),y)
b = knn.predict(a.reshape(-1,1))
plt.scatter(x,y,c = 'r')
plt.scatter(a,b,c = 'g')
<matplotlib.collections.PathCollection at 0x22e8c552e88>
output_5_1.png
三、ks-洛伦兹曲线
image.png
- 洛伦兹曲线可以筛选最佳的阈值
KS(Kolmogorov-Smirnov)值越大,表示模型能够将正、负客户区分开的程度越大。KS值的取值范围是[0,1]
通常来讲,KS>0.2即表示模型有较好的预测准确性。
ks需要TPR和FPR两个值:真正类率(true positive rate ,TPR), 计算公式为TPR=TP/ (TP+ FN),刻画的是分类器所识别出的 正实例占所有正实例的比例。另外一个是假正类率(false positive rate, FPR),计算公式为FPR= FP / (FP + TN),计算的是分类器错认为正类的负实例占所有负实例的比例。KS=max(TPR-FPR)。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve,confusion_matrix
y_true = np.array([1,1,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0])
prob = np.array([0.42,0.73,0.55,0.37,0.57,0.70,0.25,0.23,0.46,0.62,0.76,0.46,0.55,0.56,0.56,0.38,0.37,0.73,0.77,0.21,0.39])
thresholds = np.linspace(0,1,50)
fpr = []
tpr = []
for t in thresholds:
y_pred = (prob >= t).astype(np.int8)
cm = confusion_matrix(y_true,y_pred)
fpr.append(cm[1,0]/(cm[1,0] + cm[1,1]))
tpr.append(cm[0,0]/(cm[0,0] + cm[0,1]))
plt.plot(fpr,tpr,label = 'ROC-Curve')
fpr = np.asarray(fpr)
tpr = np.asarray(tpr)
ks = tpr - fpr
index = ks.argmax()
plt.plot(fpr,ks,c = 'g')
plt.scatter(fpr[index],ks[index],c = 'r',s = 100)
plt.xlabel('FPR')# 阈值不同的
plt.ylabel('TPR')
print('当KS最大时,阈值是:%0.2f'%(thresholds[index]))
当KS最大时,阈值是:0.55
output_5_1.png
洛伦兹曲线作用:可以帮助我们筛选最合适的阈值
绘制双x轴
thresholds = np.linspace(0,1,50)
fpr = []
tpr = []
for t in thresholds:
y_pred = (prob >= t).astype(np.int8)
cm = confusion_matrix(y_true,y_pred)
fpr.append(cm[1,0]/(cm[1,0] + cm[1,1]))
tpr.append(cm[0,0]/(cm[0,0] + cm[0,1]))
ax = plt.subplot(111)
ax.plot(fpr,tpr,label = 'ROC-Curve')
ax.set_xlabel('FPR')# 阈值不同的
ax.set_ylabel('TPR')
fpr = np.asarray(fpr)
tpr = np.asarray(tpr)
ks = tpr - fpr
index = ks.argmax()
ax2 = ax.twiny()
ax2.plot(thresholds,ks,c = 'g')
ax2.scatter(thresholds[index],ks[index],c = 'r',s = 100)
ax2.set_xlabel('Threshold')
print('当KS最大时,阈值是:%0.2f'%(thresholds[index]))
当KS最大时,阈值是:0.55
output_8_1.png
四、聚类操作
(1初步使用)
- 聚类---根据相似性分类
- 特征量化--数字化
- 量化之后,距离近相视,距离远,差异性大
- 根据欧式距离来计算
- 聚类是无监督学习,不需要目标值y
-
自动的归类,手动各类定义。
image.png
image.png - 数据可以是多维的。
- 初步使用代码:
import numpy as np
import matplotlib.pyplot as plt
# KNN k个邻居,此处的k,表示,将数据分成几类
from sklearn.cluster import KMeans
import pandas as pd
d:\python3.7.4\lib\importlib\_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject
return f(*args, **kwds)
# 需要将亚洲国家对,分成三个类别
# 只有历年的统计数据,没有目标值(类别,等级)
data = pd.read_csv('./AsiaFootball.txt')
data
kmeans = KMeans(n_clusters=3)
# 无监督,只需要给数据X就可以
# 之前的降维算法,PCA也是无监督
kmeans.fit(data.iloc[:,1:])
y_ = kmeans.predict(data.iloc[:,1:])# 聚类算法预测、划分的类别
c = data['国家'].values
for i in range(3):
cond = y_ == i#索引条件
print('类别是%d的国家有:'%(i),c[cond])
类别是0的国家有: ['日本' '韩国']
类别是1的国家有: ['中国' '伊拉克' '卡塔尔' '阿联酋' '泰国' '越南' '阿曼' '印尼']
类别是2的国家有: ['伊朗' '沙特' '乌兹别克斯坦' '巴林' '朝鲜']
kmeans = KMeans(n_clusters=3)
# 无监督,只需要给数据X就可以
# 之前的降维算法,PCA也是无监督
kmeans.fit(data.iloc[:,1:])
y_ = kmeans.predict(data.iloc[:,1:])# 聚类算法预测、划分的类别
c = data['国家'].values
for i in range(3):
cond = y_ == i#索引条件
print('类别是%d的国家有:'%(i),c[cond])
类别是0的国家有: ['中国' '伊拉克' '卡塔尔' '阿联酋' '泰国' '越南' '阿曼' '印尼']
类别是1的国家有: ['日本' '韩国']
类别是2的国家有: ['伊朗' '沙特' '乌兹别克斯坦' '巴林' '朝鲜']
kmeans = KMeans(n_clusters=3)
# 无监督,只需要给数据X就可以
# 之前的降维算法,PCA也是无监督
kmeans.fit(data.iloc[:,1:])
y_ = kmeans.predict(data.iloc[:,1:])# 聚类算法预测、划分的类别
c = data['国家'].values
for i in range(3):
cond = y_ == i#索引条件
print('类别是%d的国家有:'%(i),c[cond])
类别是0的国家有: ['伊朗' '沙特' '乌兹别克斯坦' '巴林' '朝鲜']
类别是1的国家有: ['中国' '伊拉克' '卡塔尔' '阿联酋' '泰国' '越南' '阿曼' '印尼']
类别是2的国家有: ['日本' '韩国']
算法,进行了类别的划分,接下来,人介入,定义
# 类别2:日本、韩国 亚洲一流
# 类别0:伊朗、沙特、朝鲜……,亚洲二流
# 类别1:中国、伊拉克、泰国…… 亚洲三流
data['等级'] = y_
def convert(item):
if item == 0:
return '中等'
elif item == 2:
return '一流'
else:
return '末流'
data['等级'] = data['等级'].apply(convert)
data
(2、kmeans中选取k值)
- 评价k选择的好坏---轮廓系数、兰德系数
(1)轮廓系数 - b 代表簇与簇之间的距离
- a代表内之间的距离
- 公式中 b 越大越好,a越小越好
- 轮廓系数越大越好,簇内和簇间的计算
image.png
import warnings
warnings.filterwarnings('ignore')
import numpy as np
from sklearn import datasets
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 分类:准确率、召回率、精确率、F1值、ROC-AUC-KS
# 回归:R2_score、均方误差(MSE)、绝对值误差(MAE)……
# 聚类:轮廓系数,对聚类的评价指标,对应数学公式
from sklearn.metrics import silhouette_score
# 假数据,预先知道,数据X划分成3类
X,y = datasets.make_blobs(centers=3)
print(X.shape)
print(y)
plt.scatter(X[:,0],X[:,1],c = y)
(100, 2)
[2 2 2 1 2 2 0 1 0 1 0 2 1 2 0 1 0 2 0 0 1 2 0 1 1 1 0 1 1 0 1 1 0 0 2 2 1
0 2 0 1 0 1 2 2 2 2 2 0 1 0 0 0 2 2 2 0 0 2 1 1 1 0 1 0 2 1 1 2 0 0 0 0 2
2 0 2 1 0 1 1 1 0 1 2 1 2 1 0 0 1 1 2 2 2 2 0 2 0 1]
<matplotlib.collections.PathCollection at 0x25f49a41388>
output_1_2.png
plt.rcParams['font.sans-serif'] = 'KaiTi'
plt.rcParams['font.size'] = 18
plt.rcParams['axes.unicode_minus'] = False
# 可以画图,一目了然,数据简单,属性只有两个,所以可以画图
# 属性多,无法可视化,评价指标
# 轮廓系数
score = []
for i in range(2,7):
kmeans = KMeans(n_clusters=i)
kmeans.fit(X)
y_ = kmeans.predict(X)# 预测类别 == 标签
# plt.scatter(X[:,0],X[:,1],c = y_)
score.append(silhouette_score(X,y_))
# print('当聚类类别是6的时候,评价指标轮廓系数: ',silhouette_score(X,y_))
plt.plot(range(2,7),score)
plt.xlabel('K值')
plt.ylabel('轮廓系数',c = 'red')
# 结论:,当k值是3的时候,轮廓系数最大,这个时候,说明划分效果最好!
Text(0, 0.5, '轮廓系数')
output_3_1.png
y_
array([3, 0, 0, 1, 3, 3, 4, 1, 4, 1, 4, 3, 1, 0, 2, 1, 2, 3, 4, 2, 1, 3,
2, 1, 1, 5, 2, 5, 1, 4, 5, 1, 2, 2, 0, 3, 5, 2, 0, 2, 5, 4, 5, 0,
3, 0, 3, 0, 2, 5, 4, 2, 2, 0, 3, 0, 2, 4, 3, 1, 1, 5, 2, 5, 4, 0,
1, 5, 3, 4, 2, 2, 4, 3, 0, 4, 3, 5, 2, 1, 5, 5, 2, 1, 3, 1, 3, 5,
2, 2, 5, 5, 0, 3, 3, 3, 4, 0, 2, 1])
# 获取标签
kmeans.labels_
array([3, 0, 0, 1, 3, 3, 4, 1, 4, 1, 4, 3, 1, 0, 2, 1, 2, 3, 4, 2, 1, 3,
2, 1, 1, 5, 2, 5, 1, 4, 5, 1, 2, 2, 0, 3, 5, 2, 0, 2, 5, 4, 5, 0,
3, 0, 3, 0, 2, 5, 4, 2, 2, 0, 3, 0, 2, 4, 3, 1, 1, 5, 2, 5, 4, 0,
1, 5, 3, 4, 2, 2, 4, 3, 0, 4, 3, 5, 2, 1, 5, 5, 2, 1, 3, 1, 3, 5,
2, 2, 5, 5, 0, 3, 3, 3, 4, 0, 2, 1])
使用另一个评价指标
from sklearn.metrics import adjusted_rand_score# 调整兰德系数
score = []
for i in range(2,7):
kmeans = KMeans(n_clusters=i)
kmeans.fit(X)
y_ = kmeans.predict(X)# 预测类别 == 标签
score.append(adjusted_rand_score(y,y_))
plt.plot(range(2,7),score)
plt.xlabel('K值')
plt.ylabel('调整兰德系数',c = 'red')
# 结论:,当k值是3的时候,轮廓系数最大,这个时候,说明划分效果最好!
Text(0, 0.5, '调整兰德系数')
output_8_1.png
(2)兰德系数(Rand index)
image.png
image.png
image.png
DBSCAN--聚类
基于密度的划分
DBSCAN算法步骤大致描述如下:对于给定的邻域距离e和邻域最小样本个数MinPts:
遍历所有样本,找出所有满足邻域距离e的核心对象的集合;
任意选择一个核心对象,找出其所有密度可达的样本并生成聚类簇;
从剩余的核心对象中移除2中找到的密度可达的样本;从更新后的核心对象集合重复执行2-3步直到核心对象都被遍历或移除。
import warnings
warnings.filterwarnings('ignore')
import numpy as np
from sklearn import datasets
from sklearn.cluster import KMeans,DBSCAN
import matplotlib.pyplot as plt
给一个密度的数据
# y中是两类:0,1
X,y = datasets.make_circles(n_samples=1000,noise=0.05,factor = 0.5)
# centers = [(1.5,1.5)] 元组,代表着,中心点的坐标值
# y1一类:0 + 2
X1,y1 = datasets.make_blobs(n_samples=500,n_features=2,centers=[(1.5,1.5)],cluster_std=0.2)
# 将circle和散点进行了数据合并
X = np.concatenate([X,X1])
y = np.concatenate([y,y1 + 2])
plt.scatter(X[:,0],X[:,1],c = y)
<matplotlib.collections.PathCollection at 0x1e09d3e7188>
output_2_1.png
# 根据距离,划分‘势力范围’
kmeans = KMeans(3)
kmeans.fit(X)
y_ = kmeans.labels_
plt.scatter(X[:,0],X[:,1],c = y_)
<matplotlib.collections.PathCollection at 0x1e09e8d3d08>
output_3_1.png
dbscan = DBSCAN(eps = 0.2,min_samples=5)
dbscan.fit(X)
y_ = dbscan.labels_
plt.scatter(X[:,0],X[:,1],c = y_)
<matplotlib.collections.PathCollection at 0x1e09ead7a48>
output_4_1.png
·