class

予測モデリング
Published

March 31, 2026

パッケージの概要

classパッケージでは、k近傍法(knn法)を用いたクラスタリングを行うことができます。k近傍法とは分類問題に対する教師あり学習のアルゴリズムの一種で、予測したいデータに対しそのデータに”近い”上位k個の学習データを取得し、その学習データの分類の多数決を予測したいデータの分類とするものです。データ間の”近さ”、すなわち距離は適宜定義できますが、classパッケージのknn関数で使用される距離は標準的なユークリッド距離となります。

使用例:Glassデータの分類

mlbenchパッケージに含まれるGlassデータを用いて、ガラスの屈折率やガラスに含まれる各元素の含有割合からガラスの種類を分類する問題にk近傍法を適用します。

データの確認

Glassデータを読み込みます。

library(mlbench)
data(Glass)
df <- Glass

データの中身の確認です。(head)

head(df)
       RI    Na   Mg   Al    Si    K   Ca Ba   Fe Type
1 1.52101 13.64 4.49 1.10 71.78 0.06 8.75  0 0.00    1
2 1.51761 13.89 3.60 1.36 72.73 0.48 7.83  0 0.00    1
3 1.51618 13.53 3.55 1.54 72.99 0.39 7.78  0 0.00    1
4 1.51766 13.21 3.69 1.29 72.61 0.57 8.22  0 0.00    1
5 1.51742 13.27 3.62 1.24 73.08 0.55 8.07  0 0.00    1
6 1.51596 12.79 3.61 1.62 72.97 0.64 8.07  0 0.26    1

データの中身の確認です。(str)

str(df)
'data.frame':   214 obs. of  10 variables:
 $ RI  : num  1.52 1.52 1.52 1.52 1.52 ...
 $ Na  : num  13.6 13.9 13.5 13.2 13.3 ...
 $ Mg  : num  4.49 3.6 3.55 3.69 3.62 3.61 3.6 3.61 3.58 3.6 ...
 $ Al  : num  1.1 1.36 1.54 1.29 1.24 1.62 1.14 1.05 1.37 1.36 ...
 $ Si  : num  71.8 72.7 73 72.6 73.1 ...
 $ K   : num  0.06 0.48 0.39 0.57 0.55 0.64 0.58 0.57 0.56 0.57 ...
 $ Ca  : num  8.75 7.83 7.78 8.22 8.07 8.07 8.17 8.24 8.3 8.4 ...
 $ Ba  : num  0 0 0 0 0 0 0 0 0 0 ...
 $ Fe  : num  0 0 0 0 0 0.26 0 0 0 0.11 ...
 $ Type: Factor w/ 6 levels "1","2","3","5",..: 1 1 1 1 1 1 1 1 1 1 ...

各変数の意味は以下の通りです。

変数名 データ型 概要
RI    num 屈折率    
Na num ナトリウム含有量(%)
Mg num マグネシウム含有量(%)
Al num アルミニウム含有量(%)
Si num ケイ素含有量(%)
K num カリウム含有量(%)
Ca num カルシウム含有量(%)
Ba num バリウム含有量(%)
Fe num 鉄含有量(%)    
Type Factor 目的変数(ガラスの種類)

目的変数であるガラスの種類は以下となっています。 https://archive.ics.uci.edu/dataset/42/glass%2Bidentification

Type値 ガラスの種類
1 建築用窓ガラス(フロート加工)
2 建築用窓ガラス(非フロート加工)
3 自動車用窓ガラス(フロート加工)
4 自動車用窓ガラス(非フロート加工)※データには含まれない
5 容器用ガラス
6 食器用ガラス
7 照明用ガラス(ヘッドランプ)

summaryを表示します。

summary(df)
       RI              Na              Mg              Al       
 Min.   :1.511   Min.   :10.73   Min.   :0.000   Min.   :0.290  
 1st Qu.:1.517   1st Qu.:12.91   1st Qu.:2.115   1st Qu.:1.190  
 Median :1.518   Median :13.30   Median :3.480   Median :1.360  
 Mean   :1.518   Mean   :13.41   Mean   :2.685   Mean   :1.445  
 3rd Qu.:1.519   3rd Qu.:13.82   3rd Qu.:3.600   3rd Qu.:1.630  
 Max.   :1.534   Max.   :17.38   Max.   :4.490   Max.   :3.500  
       Si              K                Ca               Ba       
 Min.   :69.81   Min.   :0.0000   Min.   : 5.430   Min.   :0.000  
 1st Qu.:72.28   1st Qu.:0.1225   1st Qu.: 8.240   1st Qu.:0.000  
 Median :72.79   Median :0.5550   Median : 8.600   Median :0.000  
 Mean   :72.65   Mean   :0.4971   Mean   : 8.957   Mean   :0.175  
 3rd Qu.:73.09   3rd Qu.:0.6100   3rd Qu.: 9.172   3rd Qu.:0.000  
 Max.   :75.41   Max.   :6.2100   Max.   :16.190   Max.   :3.150  
       Fe          Type  
 Min.   :0.00000   1:70  
 1st Qu.:0.00000   2:76  
 Median :0.00000   3:17  
 Mean   :0.05701   5:13  
 3rd Qu.:0.10000   6: 9  
 Max.   :0.51000   7:29  

データの可視化

データの可視化として、ヒストグラムを確認してゆきます。

library(ggplot2)

屈折率のヒストグラムをガラスの種類別に確認します。

ggplot(df, aes(x = RI)) +
  geom_histogram(bins = 30)+
  facet_wrap(~Type)

各元素の構成割合のヒストグラムをガラスの種類別に確認します(コードはNa(ナトリウム)のみ表示)。

ggplot(df, aes(x = Na)) +
  geom_histogram(bins = 30)  + 
  facet_wrap(~Type)+
  labs(title = "Na")

モデル構築

k近傍法でのクラスタリングを試してみます。まずはデータを訓練用データとテストデータに分割します。

# シードを設定
set.seed(123) 

# データの分割
sample_indices <- sample(1:nrow(df), 0.7 * nrow(df))  
df.train <- df[sample_indices, ]
df.test <- df[-sample_indices, ]

# データサイズの確認
c(nrow(df), nrow(df.train), nrow(df.test))
[1] 214 149  65

RIとそれ以外とでデータの性質が異なるため、まずはRIのみでモデリングを行います。多数決をとるkを変えてモデルの変化を見てみます。モデル性能の確認にはcaretパッケージのconfusionMatrix(混同行列)を使用します。

library(class)
library(caret)
Loading required package: lattice
pred1 <- knn(df.train[1], df.test[1], df.train$Type, k = 2)
cm1 <- confusionMatrix(pred1, df.test$Type)

pred2 <- knn(df.train[1], df.test[1], df.train$Type, k = 4)
cm2 <- confusionMatrix(pred2, df.test$Type)

pred3 <- knn(df.train[1], df.test[1], df.train$Type, k = 6)
cm3 <- confusionMatrix(pred3, df.test$Type)

混同行列と精度を確認します。

print(cm1$table)
          Reference
Prediction  1  2  3  5  6  7
         1 16  2  3  0  2  3
         2  4 14  3  0  2  2
         3  0  0  0  0  0  1
         5  1  2  0  0  0  0
         6  1  0  0  1  0  1
         7  0  4  1  1  0  1
print(cm2$table)
          Reference
Prediction  1  2  3  5  6  7
         1 15  2  3  1  3  2
         2  5 13  2  0  1  3
         3  0  1  0  0  0  1
         5  0  1  0  1  0  0
         6  1  0  1  0  0  1
         7  1  5  1  0  0  1
print(cm3$table)
          Reference
Prediction  1  2  3  5  6  7
         1 15  2  2  1  3  2
         2  4 17  3  0  1  4
         3  1  0  0  0  0  0
         5  0  0  0  0  0  1
         6  1  0  0  0  0  0
         7  1  3  2  1  0  1
print(cm1$overall[1])
 Accuracy 
0.4769231 
print(cm2$overall[1])
 Accuracy 
0.4615385 
print(cm3$overall[1])
 Accuracy 
0.5076923 

RI以外、すなわち各元素の構成割合によるモデリングも確認します。こちらの方が幾分精度がよいです。

pred4 <- knn(df.train[-1], df.test[-1], df.train$Type, k = 2)
cm4 <- confusionMatrix(pred4, df.test$Type)

pred5 <- knn(df.train[-1], df.test[-1], df.train$Type, k = 4)
cm5 <- confusionMatrix(pred5, df.test$Type)

pred6 <- knn(df.train[-1], df.test[-1], df.train$Type, k = 6)
cm6 <- confusionMatrix(pred6, df.test$Type)
print(cm4$table)
          Reference
Prediction  1  2  3  5  6  7
         1 22  0  0  0  0  0
         2  0 22  0  0  0  0
         3  0  0  7  0  0  0
         5  0  0  0  2  1  2
         6  0  0  0  0  3  1
         7  0  0  0  0  0  5
print(cm5$table)
          Reference
Prediction  1  2  3  5  6  7
         1 22  1  0  0  0  0
         2  0 21  0  0  0  0
         3  0  0  7  0  0  0
         5  0  0  0  2  2  1
         6  0  0  0  0  2  1
         7  0  0  0  0  0  6
print(cm6$table)
          Reference
Prediction  1  2  3  5  6  7
         1 22  1  0  0  0  0
         2  0 21  0  0  0  0
         3  0  0  7  0  0  0
         5  0  0  0  2  1  1
         6  0  0  0  0  1  0
         7  0  0  0  0  2  7
print(cm4$overall[1])
 Accuracy 
0.9384615 
print(cm5$overall[1])
 Accuracy 
0.9230769 
print(cm6$overall[1])
 Accuracy 
0.9230769