pengelompokan data kategorikal sklearn

Saya menggunakan fungsi pengelompokan sklearn dan aglomeratif. Saya memiliki data campuran yang mencakup kolom data numerik dan nominal. Kolom nominal saya memiliki nilai seperti "Pagi", "Siang", "Malam", "Malam". Jika saya mengubah data nominal saya menjadi numerik dengan menetapkan nilai integer seperti 0,1,2,3; jarak euclidean akan dihitung sebagai 3 antara "Malam" dan "Pagi", namun, 1 harus menjadi nilai kembalian sebagai jarak.

X = pd.read_csv("mydata.csv", sep=",", header=0, encoding="utf-8")
X = StandardScaler().fit_transform(X)
print("n_samples: %d, n_features: %d" % X.shape)

km = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='average')
km.fit(X)

print("k = %d,  Silhouette Coefficient: %0.3f" % (x,
   metrics.silhouette_score(X, km.labels_, sample_size=None)))

Ini kode saya.

Bagaimana cara menyesuaikan fungsi jarak di sklearn atau mengubah data nominal saya menjadi numerik?


person eaytan    schedule 13.11.2018    source sumber
comment
Bisakah Anda menggunakan labelencoder sklearn bawaan?   -  person G. Anderson    schedule 14.11.2018
comment
Anda sebenarnya ingin menggunakan OneHotEncoder.   -  person Andreas Mueller    schedule 14.11.2018


Jawaban (2)


Saya rasa Anda memiliki 3 opsi cara mengonversi fitur kategorikal menjadi numerik:

  1. Gunakan OneHotEncoder. Anda akan mengubah fitur kategoris menjadi empat kolom baru, yang hanya akan berisi satu 1 dan lainnya 0. Masalahnya di sini adalah perbedaan antara "pagi" dan "siang" sama dengan "pagi" dan "sore".
  2. Gunakan OrdinalEncoder. Anda mengubah fitur kategorikal menjadi hanya satu kolom. "pagi" ke jam 1, "siang" ke jam 2 dst. Perbedaan antara "pagi" dan "siang" akan lebih kecil dari "pagi" dan "sore" yang merupakan hal yang baik, namun perbedaan antara "pagi" dan "malam" akan lebih kecil. menjadi yang terhebat yang mungkin bukan yang Anda inginkan.
  3. Gunakan transformasi yang saya sebut two_hot_encoder. Mirip dengan OneHotEncoder, hanya ada dua angka 1 di barisnya. Selisih Selisih antara "pagi" dan "siang" akan sama dengan selisih antara "pagi" dan "malam" dan akan lebih kecil dibandingkan selisih antara "pagi" dan "sore". Saya pikir ini adalah solusi terbaik. Periksa kodenya.

Kode:

def two_hot(x):
    return np.concatenate([
        (x == "morning") | (x == "afternoon"),
        (x == "afternoon") | (x == "evening"),
        (x == "evening") | (x == "night"),
        (x == "night") | (x == "morning"),
    ], axis=1).astype(int)

x = np.array([["morning", "afternoon", "evening", "night"]]).T
print(x)
x = two_hot(x)
print(x)

Keluaran:

[['morning']
 ['afternoon']
 ['evening']
 ['night']]
[[1 0 0 1]
 [1 1 0 0]
 [0 1 1 0]
 [0 0 1 1]]

Kemudian kita dapat mengukur jaraknya:

from sklearn.metrics.pairwise import euclidean_distances
euclidean_distances(x)

Keluaran:

array([[0.        , 1.41421356, 2.        , 1.41421356],
       [1.41421356, 0.        , 1.41421356, 2.        ],
       [2.        , 1.41421356, 0.        , 1.41421356],
       [1.41421356, 2.        , 1.41421356, 0.        ]])
person Tomáš Přinda    schedule 14.11.2018
comment
Meskipun secara kronologis pagi hari seharusnya lebih dekat dengan sore hari dibandingkan dengan malam hari, misalnya, secara kualitatif dalam data mungkin tidak ada alasan untuk berasumsi bahwa hal tersebut adalah masalahnya. Satu pengkodean panas menyerahkannya kepada mesin untuk menghitung kategori mana yang paling mirip. Saya menyukai ide di balik dua metode pengkodean panas Anda, tetapi ini mungkin memaksakan asumsi sendiri pada data. - person jwil; 14.11.2018
comment
Anda benar bahwa itu tergantung pada tugasnya. Untuk beberapa tugas, mungkin lebih baik mempertimbangkan setiap hari secara berbeda. Namun pernyataan One hot coding menyerahkan kepada mesin untuk menghitung kategori mana yang paling mirip tidak berlaku untuk pengelompokan. Clustering menghitung cluster berdasarkan jarak contoh, yang didasarkan pada fitur. Jadi kita harus mendesain fitur agar contoh serupa harus memiliki vektor fitur dengan jarak pendek. - person Tomáš Přinda; 15.11.2018

Masalah ini umum terjadi pada aplikasi pembelajaran mesin. Anda perlu mendefinisikan satu kategori sebagai kategori dasar (tidak peduli yang mana) lalu menentukan variabel indikator (0 atau 1) untuk setiap kategori lainnya. Dengan kata lain, buatlah 3 variabel baru bernama "Pagi", "Siang", dan "Malam", dan tetapkan satu variabel ke kategori mana pun yang dimiliki setiap observasi. Jika ini adalah observasi malam hari, biarkan masing-masing variabel baru ini sebagai 0.

person jwil    schedule 13.11.2018