2021 年高等教育協会カップ モデリングにおける全国学部数学コンテスト、質問 E、漢方薬の同定、質問 1

目次

1. データの前処理 

1.1 基本データ情報の探索

1.2 データの視覚化

1.3 外れ値処理 

2. データ固有値抽出 

2.1 データの標準化 

2.2 固有値を抽出するための PCA 

3. 医薬品の種類を特定するためのデータのクラスタリング

3.1 K 値を決定するためのエルボ線図 

3.2 等高線係数マップから K 値を求める 

3.3 データのクラスタリング 

3.4 クラスタリング結果の可視化 

4.さまざまな種類の医薬品の特性と違いを研究する

4.1 さまざまな種類の医薬品のスペクトル データの平均曲線 

4.2 各種医薬品のスペクトルデータの標準偏差曲線

4.3 各種漢方スペクトルのスペクトル情報発散 SID の計算 


 

1. データの前処理 

1.1 基本データ情報の探索

附属書1 のいくつかの医薬品の中赤外スペクトルデータに従って 、さまざまな種類の医薬品の特性と違いを研究し、医薬品の種類を特定します。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
data = pd.read_excel('附件1.xlsx',index_col = 0) # index_col指定索引
data.head()

data.shape # 数据维度

# (425, 3348)

data.info() # 数据基本信息

data.isnull().any().any() # 空值判断

# False

 データに欠損値がないことを調べて見つける

1.2 データの視覚化

# 数据可视化
def func_1(x):
    plt.plot(#####)

def func_2(data):
    fontsize = 5
    plt.figure(figsize=(8, 6), dpi = 300)
    ########
    plt.yticks(fontsize = fontsize)
    plt.xlabel('波数(cm^-1)')
    plt.ylabel('吸光度(AU)')
    plt.grid(True) # 网格线设置
    data.agg(lambda x: func_1(x), axis = 1)
    plt.show()

func_2(data)

視覚化の結果は、明らかに外れ値である 3 つのスペクトル データがあることを示しています。これらは、外れ値または別のクラスである可能性があります。

1.3 外れ値処理 

 トリプル シグマ ルールを導入して、データに外れ値があるかどうかをチェックし、外れ値インデックスを出力し、外れ値を削除して、次の医薬品の種類の識別に備えます。

#异常值检验3σ
def func_3(x):
    lower = x.mean()-3*x.std() 
    toplimit = x.mean()+3*x.std()
    return (x<lower)|(x>toplimit)

ycz = data.agg(lambda x:func_3(x))
ycz_index = data[(*******)].index
ycz_index

# Int64Index([64, 136, 201], dtype='int64', name='No')


data.drop(****,axis=0,inplace = True)


func_2(data)

data.to_excel('data_ycl.xlsx')

2. データ固有値抽出 

データ抽出の特徴量は、次の医薬品の種類の識別のために準備されます

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False

data = pd.read_excel('data_ycl.xlsx', index_col = 0)

2.1 データの標準化 

# 0-1标准化
arr_max = np.max(data)
arr_min = np.min(data)
data_bzh = (data-arr_min)/(arr_max-arr_min)
data_bzh

 

2.2 固有値を抽出するための PCA 

主成分分析による固有値の抽出

pca = PCA()
pca.fit(data_bzh)
pca.explained_####### # 贡献率

lg = np.cumsum(#####) #累计贡献率

a = [0.59843097, 0.88309499, 0.93970633, 0.97403493, 0.9853352 ,0.98891337, 0.99174341]
plt.figure(figsize=(8, 6), dpi = 300)
plt.plot(a)
plt.title('前七个主成分累计贡献率')
plt.xlabel('主成分')
plt.ylabel('累计贡献率')
plt.grid(True)
plt.savefig('前七个主成分累计贡献率.png')
plt.show()

 

 砂利プロットからの主成分の決定

pca = PCA(3) # 选取累计贡献率大于90%的主成分(3个主成分)
pca.fit(data_bzh)
data_jw = pca.transform(data_bzh)
data_jw

3. 医薬品の種類を特定するためのデータのクラスタリング

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from collections import Counter
from sklearn import metrics
from mpl_toolkits.mplot3d import Axes3D 
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False

data = pd.read_excel('data_jw.xlsx',index_col = 0)

3.1 K 値を決定するためのエルボ線図 

SSE = []
for k in ####:
    ############
    km.fit(####)
    SSE.append(#####)
    
X = range(1, 11)
plt.figure(figsize=(8, 6), dpi = 300)
plt.xlabel('k')
plt.ylabel('SSE')
plt.title('肘部图')
plt.plot(X, SSE, 'o-')
plt.grid(True)
plt.savefig('肘部图.png')
plt.show()

 

エルボ プロット、シルエット係数プロットを使用した k 値の決定

3.2 等高線係数マップから K 値を求める 

 

scores = []
for k in #####:
    ######
    score = metrics.######
    scores.#######

X = range(3, 11)
plt.figure(figsize=(8, 6), dpi = 300)
plt.xlabel('k')
plt.ylabel('轮廓系数')
plt.title('轮廓系数图')
plt.plot(X, scores, 'o-')
plt.grid(True)
plt.savefig('轮廓系数图.png')
plt.show()

 

エルボー図によると、シルエット係数図は最終的にk値が3であると判断します

 

3.3 データのクラスタリング 

km = KMeans(n_clusters = 3) 
km.fit(data) 
print(Counter(km.labels_))  # 打印每个类多少个
print(km.cluster_centers_)  # 中心点
data_1 = data.reset_index() # 把索引转为列
r = pd.concat([data_1['NO'], pd.Series(km.labels_)], axis = 1) 
r.columns = ['NO', '聚类类别']
print(r)

3.4 クラスタリング結果の可視化 

data_lei0 = data[data['类别']==0]
data_lei1 = data[data['类别']==1]
data_lei2 = data[data['类别']==2]

x0 = data_lei0[0]
y0 = data_lei0[1]
z0 = data_lei0[2]
x1 = data_lei1[0]
y1 = data_lei1[1]
z1 = data_lei1[2]
x2 = data_lei2[0]
y2 = data_lei2[1]
z2 = data_lei2[2]
x3 = [-8.68761271, 10.22622717, -7.66566209]
y3 = [-6.26880974, -0.22269714, 7.70126935]
z3 = [0.04950984, 0.21554457, -0.43296869]
plt.figure(figsize=(8, 6), dpi = 300)
colors=['k', 'b', 'y', 'r']
ax = plt.subplot(111, projection='3d')
ax.plot(x0, y0, z0, 'o', color=colors[0], label='第一类')
ax.plot(x1, y1, z1, 'o', color=colors[1], label='第二类')
ax.plot(x2, y2, z2, 'o', color=colors[2], label='第三类')
ax.plot(x3, y3, z3, '*', color=colors[3], label='中心点')
plt.legend(loc='upper left', numpoints=1, ncol=3, fontsize=8, bbox_to_anchor=(0, 0))
plt.title('聚类效果图')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.savefig('聚类效果图.png')
plt.show()

 

 これにより、医薬品の種類の識別が終了します

4. さまざまな種類の医薬品の特性と違いを研究する

さまざまな種類の医薬品の特性と違いを研究する
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False

data = pd.read_excel('聚类.xlsx',index_col = 1)

data_1 = data[data['类别']=='第一类']
data_2 = data[data['类别']=='第二类']
data_3 = data[data['类别']=='第三类']

異なる種類の医薬品のスペクトルデータの平均曲線と標準偏差曲線の予備分析によると、尖度やピーク数などの特性にいくつかの違いがあることがわかります。

4.1 さまざまな種類の医薬品のスペクトル データの平均曲線 

plt.figure(figsize=(8, 6), dpi = 300)
plt.xticks(range(652, 4000, 500))
plt.plot(np.mean(data_1), c = 'r', label = '第一类')
plt.plot(np.mean(data_2), c = 'b', label = '第二类')
plt.plot(np.mean(data_3), c = 'k', label = '第三类')
plt.grid(True)
plt.legend()
plt.xlabel('波数(cm^-1)')
plt.ylabel('吸光度(AU)')
plt.title('不同种类药材光谱数据均值曲线')
plt.savefig('不同种类药材光谱数据均值曲线.png')
plt.show()

 

4.2 各種医薬品のスペクトルデータの標準偏差曲線

plt.figure(figsize=(8, 6), dpi = 300)
plt.xticks(range(652, 4000, 500))
plt.plot(np.std(data_1), c = 'r', label = '第一类')
plt.plot(np.std(data_2), c = 'b', label = '第二类')
plt.plot(np.std(data_3), c = 'k', label = '第三类')
plt.grid(True)
plt.legend()
plt.xlabel('波数(cm^-1)')
plt.ylabel('吸光度(AU)')
plt.title('不同种类药材光谱数据标准差曲线')
plt.savefig('不同种类药材光谱数据标准差曲线.png')
plt.show()

 

4.3 各種漢方スペクトルのスペクトル情報発散 SID の計算 

指標「スペクトル情報発散 SID」を導入して、 さまざまな種類の医薬品の特性と違いをさらに調査します

スペクトル情報発散 (SID) は、ハイパースペクトル イメージ内の 2 つの異なるピクセル間の類似性を測定するために使用されます。ユークリッド距離では、スペクトル自体の変動性が考慮されるため、スペクトル データをより適切に評価できます。

df_1 = pd.DataFrame(np.mean(data_1))
df_2 = pd.DataFrame(np.mean(data_2))
df_3 = pd.DataFrame(np.mean(data_3))
index_0 = range(652, 4000)

def SID(x, y):
    p = np.zeros_like(x, dtype=np.float)
    q = np.zeros_like(y, dtype=np.float)
    Sid = 0
    for i in range(len(x)):
        p[i] = x[i]/np.sum(x)
        ##############
    for j in range(len(x)):
        #############
    return Sid

# 第一类和第二类光谱信息散度(SID)
SID((pd.DataFrame(df_1.values.T, columns = index_0)).values, (pd.DataFrame(df_2.values.T, columns = index_0)).values)

# 0.024393900155562476

# 第一类和第三类光谱信息散度(SID)
SID((pd.DataFrame(df_1.values.T, columns = index_0)).values, (pd.DataFrame(df_3.values.T, columns = index_0)).values)

# 0.06295196780155943

# 第二类和第三类光谱信息散度(SID)
SID((pd.DataFrame(df_2.values.T, columns = index_0)).values, (pd.DataFrame(df_3.values.T, columns = index_0)).values)

# 0.1474926576547535

 

おすすめ

転載: blog.csdn.net/FUYUJIAN1/article/details/130144043