基于KNN模型的分类算法研究 (3)

图2-1 文本数据表格转化

[ ['40920 8.326976 0.953952 3'], ['14488 7.153469 1.673904 2'], ['26052 1.441871 0.805124 1'], ['75136 13.147394 0.428964 1'], ['38344 1.669788 0.134296 1'], ['72993 10.141740 1.032955 1'], ... ['35948 6.830792 1.213192 3'], ['42666 13.276369 0.543880 3'], ['67497 8.631577 0.749278 1'], ['35483 12.273169 1.508053 3'], ['50242 3.723498 0.831917 1'], ['63275 8.385879 1.669485 1'], ['5569 4.875435 0.728658 2'], ['15669 0.000000 1.250185 2'], ['28488 10.528555 1.304844 3'], ['6487 3.540265 0.822483 2'], ['37708 2.991551 0.833920 1'] ] 2.3 数据归一化

数据归一化

机器学习、数据挖掘、自然语言处理等数据科学工作中,数据前期准备、数据预处理过程、特征提取等几个步骤比较花费时间。同时,数据预处理的效果也直接影响了后续模型能否有效的工作。然而,目前的很多研究主要集中在模型的构建、优化等方面,对数据预处理的理论研究甚少,很多数据预处理工作仍然是靠工程师的经验进行的。也不是所有数据都需要归一化,诸如

1. 数据类型一致且分布均匀。 2. 概率模型可以不做归一化,如决策树。

数据归一化优点

1. 归一化后加快了梯度下降求最优解的速度; 2. 归一化有可能提高精度;

归一化方法

1 sklearn线性归一化

# 线性函数将原始数据线性化的方法转换到[0, 1]的范围 min_max_scaler = preprocessing.MinMaxScaler() X_train_minmax = min_max_scaler.fit_transform(X_train) X_test_minmax = min_max_scaler.transform(X_test)

2 标准差标准化

# 经过处理的数据符合标准正态分布,即均值为0,标准差为1,其转化函数为: scaler = preprocessing.StandardScaler().fit(X_train) scaler.transform(X_test)

3 非线性归一化

经常用在数据分化比较大的场景,有些数值很大,有些很小。通过一些数学函数,将原始值进行映射。该方法包括 log、指数,正切等。需要根据数据分布的情况,决定非线性函数的曲线,比如log(V, 2)还是log(V, 10)等。

线性归一化方法代码实现

'''数值归一化:特征值转化为0-1之间:newValue = (oldValue-min)/(max-min)''' def norm_dataset(dataset): minVals = dataset.min(0) # 参数0是取得列表中的最小值,而不是行中最小值 maxVals = dataset.max(0) ranges = maxVals - minVals normdataset = zeros(shape(dataset)) # 生成原矩阵一样大小的0矩阵 m = dataset.shape[0] # tile:复制同样大小的矩阵 molecular = dataset - tile(minVals,(m,1)) # 分子: (oldValue-min) Denominator = tile(ranges,(m,1)) # 分母:(max-min) normdataset = molecular/Denominator # 归一化结果。 return normdataset,ranges,minVals

数据归一化前:

归一化的数据结果: [[4.0920000e+04 8.3269760e+00 9.5395200e-01] [1.4488000e+04 7.1534690e+00 1.6739040e+00] [2.6052000e+04 1.4418710e+00 8.0512400e-01] ... [2.6575000e+04 1.0650102e+01 8.6662700e-01] [4.8111000e+04 9.1345280e+00 7.2804500e-01] [4.3757000e+04 7.8826010e+00 1.3324460e+00]]

展开第一条信息“40920 8.326976 0.953952 3”,其中里程40000多,而公升数才0.9.两者根本不在同一个数量级上面,也就是说,如果特征属性相同的情况下,公升数即使变动100倍对里程数的影响也微乎其微。而里程数轻微变化就直接影响公升数的结果。所以我们将其放在同一尺度下进行处理,也就是本文采用的线性缩放方,数据归一化后结果如下:

归一化的数据结果: [[0.44832535 0.39805139 0.56233353] [0.15873259 0.34195467 0.98724416] [0.28542943 0.06892523 0.47449629] ... [0.29115949 0.50910294 0.51079493] [0.52711097 0.43665451 0.4290048 ] [0.47940793 0.3768091 0.78571804]]

分析:

经过上述归一化处理后,各个特征指标都是0-1这样一个范畴中进行比较。当然实际工作中不同特征的权重不同,这个可以通过增加权重方法处理即可,本文不在进行深入讨论。

2.4 数据分析

基于matplotlib的可视化分析

我们对数据处理后,很不容易进行数据分析。毕竟密密麻麻的数字略显冰冷无趣。我们可以将其可视化展示出来,进而查看数据稀疏程度,离散程度等等。我们查看'玩游戏所耗时间百分比','每周消耗在冰淇淋的公升数'两个属性的散点图,实现代码如下:

''' 散列表分析数据: dataset:数据集 datingLabels:标签集 Title:列表,标题、横坐标标题、纵坐标标题。 ''' def analyze_data_plot(dataset,datingLabels,Title): fig = plt.figure() # 将画布划分为1行1列1块 ax = fig.add_subplot(111) ax.scatter(dataset[:,1],dataset[:,2],15.0*array(datingLabels),15.0*array(datingLabels)) # 设置散点图标题和横纵坐标标题 plt.title(Title[0],fontsize=25,fontname='宋体',fontproperties=myfont) plt.xlabel(Title[1],fontsize=15,fontname='宋体',fontproperties=myfont) plt.ylabel(Title[2],fontsize=15,fontname='宋体',fontproperties=myfont) # 设置刻度标记大小,axis='both'参数影响横纵坐标,labelsize刻度大小 plt.tick_params(axis='both',which='major',labelsize=10) # 设置每个坐标轴取值范围 # plt.axis([-1,25,-1,2.0]) # 截图保存图片 # plt.savefig('datasets_plot.png',bbox_inches='tight') # 显示图形 plt.show()

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydjwf.html