¿Cuál es la mejor manera de calcular la frecuencia de palabras en VB.NET?
-
03-07-2019 - |
Pregunta
Hay algunos buenos ejemplos sobre cómo calcular las frecuencias de palabras en C #, pero ninguna de ellas es exhaustiva y realmente necesito una en VB.NET.
Mi enfoque actual está limitado a una palabra por conteo de frecuencia. ¿Cuál es la mejor manera de cambiar esto para que pueda obtener una lista de frecuencia de palabras completamente precisa?
wordFreq = New Hashtable()
Dim words As String() = Regex.Split(inputText, "(\W)")
For i As Integer = 0 To words.Length - 1
If words(i) <> "" Then
Dim realWord As Boolean = True
For j As Integer = 0 To words(i).Length - 1
If Char.IsLetter(words(i).Chars(j)) = False Then
realWord = False
End If
Next j
If realWord = True Then
If wordFreq.Contains(words(i).ToLower()) Then
wordFreq(words(i).ToLower()) += 1
Else
wordFreq.Add(words(i).ToLower, 1)
End If
End If
End If
Next
Me.wordCount = New SortedList
For Each de As DictionaryEntry In wordFreq
If wordCount.ContainsKey(de.Value) = False Then
wordCount.Add(de.Value, de.Key)
End If
Next
Preferiría un fragmento de código real, pero el genérico 'oh sí ... usa esto y ejecuta' también funcionaría.
Solución
Public Class CountWords
Public Function WordCount(ByVal str As String) As Dictionary(Of String, Integer)
Dim ret As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)
Dim word As String = ""
Dim add As Boolean = True
Dim ch As Char
str = str.ToLower
For index As Integer = 1 To str.Length - 1 Step index + 1
ch = str(index)
If Char.IsLetter(ch) Then
add = True
word += ch
ElseIf add And word.Length Then
If Not ret.ContainsKey(word) Then
ret(word) = 1
Else
ret(word) += 1
End If
word = ""
End If
Next
Return ret
End Function
End Class
Luego, para una aplicación de demostración rápida, cree una aplicación winforms con un cuadro de texto multilínea llamado InputBox, una vista de lista llamada OutputList y un botón llamado CountBtn. En la vista de lista, cree dos columnas: " Palabra " y " Freq. " Seleccione los " detalles " tipo de lista Agregue un controlador de eventos para CountBtn. Luego usa este código:
Imports System.Windows.Forms.ListViewItem
Public Class MainForm
Private WordCounts As CountWords = New CountWords
Private Sub CountBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CountBtn.Click
OutputList.Items.Clear()
Dim ret As Dictionary(Of String, Integer) = Me.WordCounts.WordCount(InputBox.Text)
For Each item As String In ret.Keys
Dim litem As ListViewItem = New ListViewItem
litem.Text = item
Dim csitem As ListViewSubItem = New ListViewSubItem(litem, ret.Item(item).ToString())
litem.SubItems.Add(csitem)
OutputList.Items.Add(litem)
Word.Width = -1
Freq.Width = -1
Next
End Sub
End Class
Hiciste una cosa terrible para hacerme escribir esto en VB y nunca te lo perdonaré.
: p
¡Buena suerte!
EDIT
Error de cadena en blanco y error de caso corregidos
Otros consejos
Esto podría ser lo que buscas:
Dim Words = "Hello World ))))) This is a test Hello World"
Dim CountTheWords = From str In Words.Split(" ") _
Where Char.IsLetter(str) _
Group By str Into Count()
Acabo de probarlo y funciona
EDITAR! He añadido código para asegurarme de que solo cuente con letras y no con símbolos.
Para tu información: encontré un artículo sobre cómo usar LINQ y target 2.0, es un poco sucio, pero podría ayudar a alguien http://weblogs.asp.net/fmarguerie/archive/2007/09/05/linq-support-on- net-2-0.aspx
Muy cerca, pero \ w + es una buena expresión regular para coincidir con (solo caracteres de palabras).
Public Function CountWords(ByVal inputText as String) As Dictionary(Of String, Integer)
Dim frequency As New Dictionary(Of String, Integer)
For Each wordMatch as Match in Regex.Match(inputText, "\w+")
If frequency.ContainsKey(wordMatch.Value.ToLower()) Then
frequency(wordMatch.Value.ToLower()) += 1
Else
frequency.Add(wordMatch.Value.ToLower(), 1)
End If
Next
Return frequency
End Function
Esto podría ser útil:
Algoritmo de frecuencia de palabras para el procesamiento del lenguaje natural