Saya mencoba mendapatkan frekuensi kata pada teks tweet dari file csv menggunakan jumlah nilai pandas

Ini kode saya:

import nltk
from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer
from nltk.stem import WordNetLemmatizer
import pandas as pd
import numpy as np
import openpyxl
import string

tokenizer = RegexpTokenizer(r'\w+')
lemmatizer = WordNetLemmatizer()


def remove_stopwords(df_text):
    words = [w for w in df_text if w not in stopwords.words('english')]
    return words

def word_lemmatizer(df_text):
    lem_text = [lemmatizer.lemmatize(i) for i in df_text]
    return lem_text

#works fine from here
df = pd.read_csv('amazonfresh-test.csv', encoding='utf-8', converters={'text': str})


df['text'].apply(lambda x: tokenizer.tokenize(x.lower()))
df['text'].apply(lambda x: remove_stopwords(x))
df['text'].apply(lambda x: word_lemmatizer(x))

#to here

#this is where I have issues
data_count = df['test'].apply(pd.value_counts())

data_count.to_excel("amazonfresh-test.xlsx")

Dibutuhkan waktu lama untuk menjalankannya dan saya hanya mencoba menghapus dan membagi string di setiap baris kolom teks dan kemudian menghitung jumlah kata keseluruhan untuk menunjukkan frekuensi kata.

Berikut tampilan csvnya:

Ini csv baru dengan kata-kata di selnya sendiri, masih berjuang untuk mendapatkan value_count ini.


person Tom    schedule 22.06.2020    source sumber
comment
Bisakah Anda memberikan contoh 'amazonfresh-test.csv'?   -  person Phillyclause89    schedule 23.06.2020
comment
Ya, baru saja melakukan @ Phillyclause89   -  person Tom    schedule 23.06.2020
comment
Terima kasih untuk tangkapan layar csvnya. Dari mana Anda mendapatkan kolom 'test' di data_count = df['test'].apply(pd.value_counts())? Saya tidak melihatnya sebagai kolom yang ada di csv sumber Anda dan saya tidak melihat Anda membuat kolom seperti itu di mana pun dalam kode Anda sebelum Anda menggunakan metode pandas.Series.apply di dalamnya.   -  person Phillyclause89    schedule 23.06.2020
comment
@ Phillyclause89 itu pasti salah ketik, itu merujuk pada kolom 'teks' di csv   -  person Tom    schedule 23.06.2020
comment
Apakah kesalahan ketik itu yang menyebabkan masalah Anda, atau apakah perilaku yang Anda catat dalam pertanyaan ini terjadi tanpa adanya kesalahan ketik dalam kode?   -  person Phillyclause89    schedule 23.06.2020
comment
@ Phillyclause89 ini terjadi tanpa ada kesalahan ketik. Saya dapat melakukan lemmatisasi, menghapus stopwords, dan melakukan tokenisasi tanpa terlalu banyak masalah. Tapi saya punya masalah saat mencoba menghitung nilai pada teks di kolom   -  person Tom    schedule 23.06.2020
comment
saya juga tidak paham dengan metode pandas.value_counts. Ada pandas.Series.value_counts, tapi saya tidak yakin apakah ini yang ingin Anda gunakan di sini. apakah Anda hanya mencoba menghitung setiap token yang tersisa setelah menghapus kata-kata berhenti? mungkin mencoba: data_count = df['text'].apply(lambda x: len(x))?   -  person Phillyclause89    schedule 23.06.2020
comment
@ Phillyclause89 program ini tampaknya memakan waktu yang sangat lama untuk dijalankan, ada firasat mengapa?   -  person Tom    schedule 23.06.2020
comment
@ Phillyclause89 ya, hanya mencoba menghitung sisa token, skrip yang Anda sarankan hanya menampilkan angka   -  person Tom    schedule 23.06.2020
comment
Saya rasa saya mengerti apa yang Anda cari di sini. Butuh beberapa saat bagi saya untuk menginstal semua paket nltk, tetapi saya sudah siap dan menjalankan skrip Anda sekarang. Dapatkah Anda mengonfirmasi bahwa Anda benar-benar menekan baris #inilah tempat saya mengalami masalah dan apakah baris di bawahnya benar-benar memiliki data_count = df['text'].apply(pd.value_counts()) atau apakah ada kesalahan ketik lain pada baris itu? seperti yang tertulis saya mendapatkan TypeError: value_counts() missing 1 required positional argument: 'values' ketika saya mencoba menjalankannya. Bagaimana Anda mengidentifikasi bahwa garis ini adalah leher botol Anda? Apakah Anda yakin itu bukan salah satu dari .apply panggilan lainnya?   -  person Phillyclause89    schedule 23.06.2020
comment
Jadi dua ide setelah bermain-main dengan ini. 1) perlu diingat bahwa pandas.Series.apply bukan metode inplace secara default. Saya rasa Anda ingin melakukan df['text'] = df['text'].apply(func) di tiga baris yang sepertinya Anda ingin memberi tokenisasi dan memfilter data di kolom teks. 2) Saya rasa Anda ingin menghapus pemanggil dari fungsi pd.value_counts di baris data_count = df['test'].apply(pd.value_counts()). coba lakukan data_count = df['test'].apply(pd.value_counts)?   -  person Phillyclause89    schedule 23.06.2020
comment
@ Phillyclause89 oke jadi saya bisa mengeluarkan csv dengan setiap kata dipecah ke dalam selnya sendiri, lalu bagaimana saya menggunakan jumlah nilai? Saya akan melampirkan csv baru di postingan asli.   -  person Tom    schedule 23.06.2020


Jawaban (1)


Setelah cukup banyak berkomentar dengan OP, saya memutuskan akan lebih baik untuk merangkum saran saya di sini.

Masalah pertama adalah ada dua kesalahan ketik di data_count = df['test'].apply(pd.value_counts()).

Baris itu seharusnya data_count = df['text'].apply(pd.value_counts).

df['test'] akan memunculkan KeyError karena tidak ada kolom 'test' di pandas.DataFrame OP. Kesalahan ketik lainnya adalah pemanggilan pandas.value_counts tanpa argumen ke pemanggil metode pandas.Series.apply. Ini akan memunculkan TypeError karena fakta bahwa fungsi pandas.value_counts memerlukan setidaknya satu argumen. Namun hal ini mudah diperbaiki dengan menghapus pemanggil karena tujuan dari metode pandas.Series.apply adalah agar metode tersebut memanggil fungsi agar kita menggunakan setiap nilai dalam rangkaian sebagai argumen.

Masalah berikutnya yang saya perhatikan adalah tiga panggilan lainnya dari metode pandas.Series.apply:

df['text'].apply(lambda x: tokenizer.tokenize(x.lower()))
df['text'].apply(lambda x: remove_stopwords(x))
df['text'].apply(lambda x: word_lemmatizer(x))

Ketiga baris ini ditulis seolah-olah pandas.Series.apply adalah metode inplace, padahal sebenarnya bukan. Untuk benar-benar mengubah objek pandas.DataFrame yang ditetapkan ke df, kita harus benar-benar menggunakan penugasan di sini:

df['text'] = df['text'].apply(lambda x: tokenizer.tokenize(x.lower()))
df['text'] = df['text'].apply(remove_stopwords)
df['text'] = df['text'].apply(word_lemmatizer)

Selain itu, ekspresi lambda hanya diperlukan pada panggilan pertama untuk melakukan bagian x.lower(), karena remove_stopwords dan word_lemmatizer keduanya mengambil nilai apa adanya, kita tidak memerlukan lambda tambahan. Terakhir, ketiga baris dapat diringkas menjadi satu panggilan pandas.Series.apply karena fungsi-fungsi ini diterapkan pada nilai yang sama:

df['text'] = df['text'].apply(
    lambda x: word_lemmatizer(
        remove_stopwords(
            tokenizer.tokenize(x.lower())
        )
    )
)

Kode lengkap yang saya harap OP dapat kumpulkan dari komentar saya akan terlihat seperti ini:

from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer
from nltk.stem import WordNetLemmatizer
import pandas as pd

tokenizer = RegexpTokenizer(r'\w+')
lemmatizer = WordNetLemmatizer()


def remove_stopwords(df_text):
    words = [w for w in df_text if w not in stopwords.words('english')]
    return words


def word_lemmatizer(df_text):
    lem_text = [lemmatizer.lemmatize(i) for i in df_text]
    return lem_text


df = pd.read_csv('test.csv', encoding='utf-8', converters={'text': str}, sep="\t")

df['text'] = df['text'].apply(
    lambda x: word_lemmatizer(
        remove_stopwords(
            tokenizer.tokenize(x.lower())
        )
    )
)

data_count = df['text'].apply(pd.value_counts)

data_count.to_excel("test.xlsx")

File excel yang dibuat akan terlihat seperti ini.

masukkan deskripsi gambar di sini Catatan: Output yang ditampilkan di tangkapan layar saya adalah dari menjalankan kode ini pada satu kolom csv yang terdiri dari 100 kalimat pertama buku Dune, saya tidak melakukannya repot-repot membuat ulang csv yang ditampilkan di tangkapan layar OP, karena satu-satunya hal yang penting adalah ada kolom dengan sekumpulan kata bahasa Inggris bernama 'teks'

Dengan semua ini sekarang didokumentasikan dalam jawaban ini, OP masih memiliki satu komentar yang belum diutarakan:

@ Phillyclause89 oke jadi saya bisa mengeluarkan csv dengan setiap kata dipecah ke dalam selnya sendiri, lalu bagaimana saya menggunakan jumlah nilai? Saya akan melampirkan csv baru di postingan asli.

Rekomendasi saya adalah pandas.value_counts digunakan seperti yang saya tunjukkan pada contoh kode di atas (di dalam pandas.Series.Apply dan tanpa memanggilnya.) Dari sana Anda dapat menggunakan berbagai metode agg seperti sum untuk menemukan jumlah kata di semua baris:

agg_data_count = data_count.sum().sort_values(0,ascending=False)
agg_data_count.to_excel("sums.xlsx")

Dengan membuka sums.xlsx kita bisa mendapatkan daftar kata-kata yang bagus dan berapa kali kata-kata itu muncul di seluruh kumpulan data: masukkan deskripsi gambar di sini

person Phillyclause89    schedule 24.06.2020
comment
juga menyadari bahwa df['text'].value_counts() juga berfungsi, terima kasih atas bantuan Anda! - person Tom; 24.06.2020