PythonStudy4

一、前言

无论怎么选择数据特征都难以得到一个高的分类率. 最后在看方差和标准差的时候, 发现数据不同特征的这两个值不在一个数量级上.

这都是自己没有做归一化导致的结果, 所以这里尝试归一化之后再来进行训练.

二、归一化

1. 概念

在机器学习领域中, 不同评价指标 (即特征向量中的不同特征就是所述的不同评价指标) 往往具有不同的量纲和量纲单位, 这样的情况会影响到数据分析的结果, 为了消除指标之间的量纲影响, 需要进行数据标准化处理, 以解决数据指标之间的可比性.

原始数据经过数据标准化处理后, 各指标处于同一数量级, 适合进行综合对比评价. 其中, 最典型的就是数据的归一化处理.

2. 方法

  1. 最大最小标准化 (Min-Max Normalization)

    \[ x' = \frac{x - \min(x)}{\max(x) - \min(x)} \]

    线性函数将原始数据线性化的方法转换到 [0 1] 的范围, 计算结果为归一化后的数据, x 为原始数据

    本归一化方法比较适用在数值比较集中的情况

  2. z—score 标准化

    \[ x^* = \frac{x - \mu}{\sigma} \]

    其中, \(\mu\)\(\sigma\) 分别是原始数据集的均值和方差.

    将原始数据集归一化为均值为0、方差1的数据集

    该种归一化方式要求原始数据的分布可以近似为高斯分布, 否则归一化的效果会变得很糟糕

3. 归一化代码

我还是选择最简单的最大最小标准化, 使用 sklearn 库的 preprocessing 就能够很好完成.

1
2
3
4
5
6
7
from sklearn import preprocessing

min_max_scaler = preprocessing.MinMaxScaler()
#标准化训练集数据
data_train_nomal = min_max_scaler.fit_transform([[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7]])

print(data_train_nomal)

输入 : 一个矩阵

1
2
3
[[1. 2. 3. 4. 5. ]
[2. 3. 4. 5. 6. ]
[3. 4. 5. 6. 7. ]]

输出 : 归一化后的矩阵

1
2
3
[[0.  0.  0.  0.  0. ]
[0.5 0.5 0.5 0.5 0.5]
[1. 1. 1. 1. 1. ]]

三、训练

由于是在 Jupyter Notebook 里面写的, 所以代码就分段展示

读取数据的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os

files = []

def Getfile(path):
files_list = os.listdir(path)

for file_name in files_list:
file_absolute_path = os.path.join(path,file_name)
if os.path.isdir(file_absolute_path):
Getfile(file_absolute_path)
else:
if file_absolute_path.rsplit('.')[-1] == 'xlsx':
files.append(file_absolute_path)

Getfile(r"D:\Work\Data\welldata")

处理数据的代码

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
31
32
33
import pandas as pd

feature = []
label = []

for file in files:
useful_file = False

if pd.read_excel(file).shape[1] == 28:
useful_file = True
else:
useful_file = False

if useful_file:
# Get column 5-24 and add column 27
columns = list(range(5,25))
columns.append(27)
data = pd.read_excel(file, usecols=columns,names=None)
df = data.values.tolist()

for i in range(len(df)):
feature.append(df[i][:-1])

if df[i][-1] == "差气层":
label.append(0)
elif df[i][-1] == "干层":
label.append(1)
elif df[i][-1] == "气层":
label.append(2)
else:
feature.pop()
else:
continue

归一化的代码

1
2
3
4
5
from sklearn import preprocessing

min_max_scaler = preprocessing.MinMaxScaler()

feature = min_max_scaler.fit_transform(feature)

分割数据集的代码

1
2
3
from sklearn.model_selection import train_test_split

feature_train_set,feature_test_set,label_train_set,label_test_set = train_test_split(feature,label)

训练的代码

1
2
3
4
5
6
7
from sklearn.neighbors import KNeighborsClassifier

sklearn_knn_clf = KNeighborsClassifier(n_neighbors=7)

sklearn_knn_clf.fit(feature_train_set,label_train_set)

sklearn_knn_clf.score(feature_test_set,label_test_set)

分类准确率

这是调整了 KNN 对邻居要求的个数并且选择的是多次训练结果中最高的识别率.

四、其他算法

尝试了贝叶斯分类器, 结果更差

决策树相比 KNN 的效果要好些, 但是还是达不到高识别率

五、总结

相比之前有了很大提升, 但是始终无法使正确率到达 85% 甚至是 90% 以上. 修改归一化规则对结果也是大差不差.

那么对我来说, 要么是对数据把握不到位, 要么就要尝试使用神经网络之类的算法来处理这个问题.