用K近鄰算法建立一個超簡單的預測模型=====python數學建模實例

這篇文章主要講兩個事:

  1. 給大家介紹一下機器學習中的一個簡單算法-K近鄰算法
  2. 科普一個冷門專業——選礦

今天借助一些選礦的數據來講一下這個算法。

選礦是干什么的?選礦就是研究如何從礦石中把有用的礦物提取出來的一門學科。選礦之前要先把礦石弄成粉末,讓礦石中的有用礦物和其他雜質分開,然后再利用有用礦物和其他雜志之間的物理化學性質差異將它們分開。
我們今天使用的這些數據是關于磁鐵礦的,在這個磁鐵礦山中,開采出來的原礦石里面有很多雜質,黃鐵礦、赤鐵礦、石英、云母、綠泥石、伊利石……偶爾還能發現價值連城的天然綠松石……

下面簡單介紹一下數據含義:

  1. BallMillAbility:球磨機臺時能力,可以理解為每臺機器每小時磨出來的礦粉的量;
  2. OreGrade:原礦品位,也就是原礦中的鐵元素含量;
  3. RateofMagnet:磁鐵率,即在所有鐵礦物(磁鐵礦、黃鐵礦、赤鐵礦、褐鐵礦等)中磁鐵礦所占的比例;
  4. TailGrade:尾礦品位,尾礦就是選礦之后產生的渣渣;
  5. ConcentrateGrade:精礦品位,就是選礦的最終產品,這個指標在選礦廠是嚴格控制的,一般波動只有1%。64%品位的磁鐵精礦意味著磁鐵礦含量已經達到了88%。

我們今天做的預測模型就是要通過這前面4個指標來預測第5個指標能否達標

讀取csv文件:

In [1]:import pandas as pd
In [2]:df = pd.read_csv('D://Practice/Data.csv')
In [3]:df
Out[3]: 
     BallMillAbility  OreGrade  RateofMagnet  TailGrade  ConcentrateGrade
0             297.76     18.98         71.65       8.30             64.35
1             280.15     18.68         73.39       8.59             64.87
2             302.81     18.23         72.13       8.69             64.76
3             173.41     19.55         74.42       9.00             64.57
4             345.66     18.57         75.93       9.28             64.62
5             312.65     18.34         72.19       9.19             64.38
6             306.85     17.80         71.80       9.35             64.50
..               ...       ...           ...        ...               ...
預測指標處理

將最后一列提取出來,作為每一列的分類標簽(其中64.5以上為合格(1),64.5以下為不合格(0))

for i in range(149):
    if df['ConcentrateGrade'][i] >= 64.5:
        df['ConcentrateGrade'][i] = 1
    else:
        df['ConcentrateGrade'][i] = 0
Out[13]: 
     BallMillAbility  OreGrade  RateofMagnet  TailGrade  ConcentrateGrade
0             297.76     18.98         71.65       8.30               0.0
1             280.15     18.68         73.39       8.59               1.0
2             302.81     18.23         72.13       8.69               1.0
3             173.41     19.55         74.42       9.00               1.0
4             345.66     18.57         75.93       9.28               1.0
5             312.65     18.34         72.19       9.19               0.0
6             306.85     17.80         71.80       9.35               1.0
..               ...       ...           ...        ...               ...
預留的預測樣本(這里只留了一個,實際使用的時候需要較多數據):
BallMillAbility  OreGrade  RateofMagnet  TailGrade  ConcentrateGrade
  340.22     17.08         66.66       9.30           --
計算距離并按距離排序

求這一點到數據集中各點的距離,并將這個距離值作為一列新的數據加入到df中。

df['Distance'] = 0
from numpy import *
for i in range(149):
    distance = sqrt((df['BallMillAbility'][i]-350.22)**2+(df['OreGrade'][i]-17.08)**2+(df['RateofMagnet'][i]-65.65)**2+(df['TailGrade'][i]-10.30)**2)
    df['Distance'][i] = distance

排序

a = df.sort(columns = 'Distance')#這里記住對調用df的sort方法不會對df做出改變。

       BallMillAbility  OreGrade  RateofMagnet  TailGrade  ConcentrateGrade   Distance  
99            349.90     17.44         68.06       8.50               0.0           3  
         
40            349.49     17.03         69.76       8.49               0.0           4  
        
10            352.13     17.41         70.53       8.82               1.0           5  
         
100           351.63     18.48         71.81       8.46               1.0           6  
           
65            355.82     16.92         70.51       7.52               0.0           7  
      
104           347.20     18.76         71.59       8.75               0.0           7  
         
113           350.17     18.75         73.23       9.04               0.0           7  
         
46            352.35     18.13         71.98       8.18               0.0           7
 ..               ...       ...           ...        ...               ...
預測

然后取前k個值(我們取20),統計前k個值中1占多少。

b = a.reset_index(drop = True)#這里要重新建立索引,以便后續操作。另:使用a的reset_index方法不會改變a的值
m = 0
for i in range(20):
    if b['ConcentrateGrade'][i] == 1:
        m += 1
In[46]:m
Out[46]: 9

可見前20組數據中,ConcentrateGrade小于64.5的占多數,我們繼續加大k的值試試:

k  20 30 40 50
m  3  6 10 12

通過測試結果我們可以判定,這趟指標應該不會合格。

在做預測模型的時候,為了避免數據量綱對模型的影響,我們會對數據進行歸一化處理

數據歸一化處理

這里采用最簡單的現象函數歸一化(Min-Max Scaling)

p = min(df['BallMillAbility'])
o = max(df['BallMillAbility'])
for i in range(149):
    df['BallMillAbility'][i] = (df['BallMillAbility'][i]-p)/(o-p)

就這樣依次把4列數據都歸一化

Out[33]: 
     BallMillAbility  OreGrade  RateofMagnet  TailGrade  ConcentrateGrade
0           0.508755  0.526555      0.418244   0.325203               0.0
1           0.436707  0.481032      0.567986   0.443089               1.0
2           0.529417  0.412747      0.459552   0.483740               1.0
3           0.000000  0.613050      0.656627   0.609756               1.0
4           0.704730  0.464340      0.786575   0.723577               1.0
5           0.569675  0.429439      0.464716   0.686992               0.0
6           0.545946  0.347496      0.431153   0.752033               1.0
7           0.305294  0.391502      0.555077   0.609756               0.0
8           0.594509  0.335357      0.444062   0.776423               1.0
9           0.506505  0.074355      0.302926   0.691057               1.0
..               ...       ...           ...        ...               ...

歸一化處理完了之后別忘記保存一下

df.to_csv('D://Practice/data1.csv')

然后我們再用k近鄰算法計算一遍得到如下結果:

k 20 30 40 50
m 3 9 19 31

這樣又出現了不同的結果,理論上來講,歸一化之后的預測模型應該更加準確一點。

ps:對選礦有興趣的可以私信我

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容