web-dev-qa-db-fra.com

Définir et appliquer des bacs personnalisés sur une trame de données

En utilisant python j'ai créé le bloc de données suivant qui contient des valeurs de similitude:

  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture    jaccard
1       0.770     0.489        0.388  0.57500000 0.5845137    0.3920000 0.00000000
2       0.067     0.496        0.912  0.13865546 0.6147309    0.6984127 0.00000000
3       0.514     0.426        0.692  0.36440678 0.4787535    0.5198413 0.05882353
4       0.102     0.430        0.739  0.11297071 0.5288008    0.5436508 0.00000000
5       0.560     0.735        0.554  0.48148148 0.8168083    0.4603175 0.00000000
6       0.029     0.302        0.558  0.08547009 0.3928234    0.4603175 0.00000000

J'essaie d'écrire un script R pour générer une autre trame de données qui reflète les bacs, mais ma condition de regroupement s'applique si la valeur est supérieure à 0,5 de telle sorte que

Pseudocode:

if (cosinFcolor > 0.5 & cosinFcolor <= 0.6)
   bin = 1
if (cosinFcolor > 0.6 & cosinFcolor <= 0.7)
   bin = 2
if (cosinFcolor > 0.7 & cosinFcolor =< 0.8)
   bin = 3
if (cosinFcolor > 0.8 & cosinFcolor <=0.9)
   bin = 4
if (cosinFcolor > 0.9 & cosinFcolor <= 1.0)
   bin = 5
else
   bin = 0

Sur la base de la logique ci-dessus, je veux construire un bloc de données

  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture    jaccard
1       3         0         0            1           1        0               0

Comment puis-je démarrer cela en tant que script, ou dois-je le faire en python? J'essaie de me familiariser avec R après avoir découvert sa puissance/le nombre de packages d'apprentissage automatique dont il dispose. Mon objectif est de construire un classificateur mais je dois d'abord me familiariser avec R :)

30
add-semi-colons

Une autre réponse tranchée qui prend en compte les extrema:

dat <- read.table("clipboard", header=TRUE)

cuts <- apply(dat, 2, cut, c(-Inf,seq(0.5, 1, 0.1), Inf), labels=0:6)
cuts[cuts=="6"] <- "0"
cuts <- as.data.frame(cuts)

  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
1           3         0            0           1         1            0       0
2           0         0            5           0         2            2       0
3           1         0            2           0         0            1       0
4           0         0            3           0         1            1       0
5           1         3            1           0         4            0       0
6           0         0            1           0         0            0       0

Explication

La fonction de découpe se divise en compartiments en fonction des découpes que vous spécifiez. Prenons donc 1:10 et divisons-le en 3, 5 et 7.

cut(1:10, c(3, 5, 7))
 [1] <NA>  <NA>  <NA>  (3,5] (3,5] (5,7] (5,7] <NA>  <NA>  <NA> 
Levels: (3,5] (5,7]

Vous pouvez voir comment cela a fait un facteur où les niveaux sont ceux entre les pauses. Notez également qu'il ne comprend pas 3 (il y a un include.lowest argument qui l'inclura). Mais ce sont des noms terribles pour les groupes, appelons-les groupes 1 et 2.

cut(1:10, c(3, 5, 7), labels=1:2)
 [1] <NA> <NA> <NA> 1    1    2    2    <NA> <NA> <NA>

Mieux, mais qu'est-ce qui se passe avec les NA? Ils sont en dehors de nos frontières et ne sont pas comptés. Pour les compter, dans ma solution, j'ai ajouté -infini et infini, donc tous les points seraient inclus. Notez que comme nous avons plus de pauses, nous aurons besoin de plus d'étiquettes:

x <- cut(1:10, c(-Inf, 3, 5, 7, Inf), labels=1:4)
 [1] 1 1 1 2 2 3 3 4 4 4
Levels: 1 2 3 4

D'accord, mais nous ne voulions pas 4 (selon votre problème). Nous voulions que tous les 4 soient dans le groupe 1. Alors débarrassons-nous des entrées qui sont étiquetées "4".

x[x=="4"] <- "1"
 [1] 1 1 1 2 2 3 3 1 1 1
Levels: 1 2 3 4

Ceci est légèrement différent de ce que je faisais auparavant, notez que j'ai enlevé toutes les dernières étiquettes à la fin avant, mais je l'ai fait de cette façon ici afin que vous puissiez mieux voir comment cut fonctionne.

Ok, la fonction apply. Jusqu'à présent, nous avons utilisé la découpe sur un seul vecteur. Mais vous voulez qu'il soit utilisé sur une collection de vecteurs: chaque colonne de votre bloc de données. C'est ce que fait le deuxième argument de apply. 1 applique la fonction à toutes les lignes, 2 s'applique à toutes les colonnes. Appliquez la fonction cut à chaque colonne de votre bloc de données. Tout ce qui se trouve après cut dans la fonction apply n'est qu'un argument de cut, dont nous avons discuté ci-dessus.

J'espère que ça t'as aidé.

54
sebastian-c

Vous pouvez également utiliser findInterval:

findInterval(seq(0, 1, l=20), seq(0.5, 1, by=0.1))

## [1] 0 0 0 0 0 0 0 0 0 1 1 2 2 3 4 4 5 5
24
mnel

Avec la coupe, c'est facile comme tarte

dtf <- read.table(
textConnection(
"cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
1 0.770 0.489 0.388 0.57500000 0.5845137 0.3920000 0.00000000
2 0.067 0.496 0.912 0.13865546 0.6147309 0.6984127 0.00000000
3 0.514 0.426 0.692 0.36440678 0.4787535 0.5198413 0.05882353
4 0.102 0.430 0.739 0.11297071 0.5288008 0.5436508 0.00000000
5 0.560 0.735 0.554 0.48148148 0.8168083 0.4603175 0.00000000
6 0.029 0.302 0.558 0.08547009 0.3928234 0.4603175 0.00000000"), sep = " ", 
           header = TRUE)

dtf$bin <- cut(dtf$cosinFcolor, breaks = c(0, seq(0.5, 1, by = .1)), labels = 0:5)
dtf
  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture    jaccard bin
1       0.770     0.489        0.388  0.57500000 0.5845137    0.3920000 0.00000000   3
2       0.067     0.496        0.912  0.13865546 0.6147309    0.6984127 0.00000000   0
3       0.514     0.426        0.692  0.36440678 0.4787535    0.5198413 0.05882353   1
4       0.102     0.430        0.739  0.11297071 0.5288008    0.5436508 0.00000000   0
5       0.560     0.735        0.554  0.48148148 0.8168083    0.4603175 0.00000000   1
6       0.029     0.302        0.558  0.08547009 0.3928234    0.4603175 0.00000000   0
14
Luciano Selzer

Voici une autre solution utilisant la fonction bin_data() du package mltools .

Regroupement d'un vecteur

library(mltools)

cosinFcolor <- c(0.77, 0.067, 0.514, 0.102, 0.56, 0.029)
binned <- bin_data(cosinFcolor, bins=c(0, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), boundaryType = "[lorc")

binned
[1] (0.7, 0.8] [0, 0.5]   (0.5, 0.6] [0, 0.5]   (0.5, 0.6] [0, 0.5]  
Levels: [0, 0.5] < (0.5, 0.6] < (0.6, 0.7] < (0.7, 0.8] < (0.8, 0.9] < (0.9, 1]

# Convert to numbers 0, 1, ...
as.integer(binned) - 1L

Regroupement de chaque colonne dans le data.frame

df <- read.table(textConnection(
  "cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
0.770 0.489 0.388 0.57500000 0.5845137 0.3920000 0.00000000
0.067 0.496 0.912 0.13865546 0.6147309 0.6984127 0.00000000
0.514 0.426 0.692 0.36440678 0.4787535 0.5198413 0.05882353
0.102 0.430 0.739 0.11297071 0.5288008 0.5436508 0.00000000
0.560 0.735 0.554 0.48148148 0.8168083 0.4603175 0.00000000
0.029 0.302 0.558 0.08547009 0.3928234 0.4603175 0.00000000"
), sep = " ", header = TRUE)

for(col in colnames(df)) df[[col]] <- as.integer(bin_data(df[[col]], bins=c(0, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0), boundaryType = "[lorc")) - 1L

df
  cosinFcolor cosinEdge cosinTexture histoFcolor histoEdge histoTexture jaccard
1           3         0            0           1         1            0       0
2           0         0            5           0         2            2       0
3           1         0            2           0         0            1       0
4           0         0            3           0         1            1       0
5           1         3            1           0         4            0       0
6           0         0            1           0         0            0       0
2
Ben