Lainsäädäntö on yhteiskuntamme lähdekoodi, mutta se on usein kirjoitettu tavalla, joka on esteetöntä niille ihmisille, joita se hallitsee. Lainsäädäntö voi olla kymmeniä sivuja pitkä, täynnä tiheää lainsäädäntöä ja ristiviittauksia, jotka tekevät niistä lähes mahdottomia lukea satunnaisesti. Kehittäjänä uskon teknologian käyttämiseen hallituksen avoimempaan ja saatavilla olevaan. Katsoin Texasin lainsäätäjän verkkosivustoa ja näin haasteen. Entä jos voisin käyttää tietoja kouluttamaan AI: ta lukemaan minkä tahansa laskun ja kirjoittamaan oman yhteenvedon?Tämä on tarina siitä, miten rakensin lopullisen putken tekemään juuri sitä: tietojen kaavimisesta sotkun puhdistamiseen ja tehokkaan kielimallin hienosäätöön. Ensimmäinen askel oli saada URL-osoitteet jokaiselle hyväksytylle laskulle sekä sen täydellinen teksti ja virallinen yhteenveto. Perustyökalupakki: BeautifulSoup Yksinkertaisille HTML-sivuille ja Pythonin urllib ovat täydelliset työkalut. Aloitin kirjoittamalla käsikirjoituksen (all_house_texas.py) navigoidaksesi laskutusasiakirjojen sivuilla, etsimällä kaikki linkit yksittäisiin laskutushistorioihin ja poimimalla perustiedot, kuten kirjoittaja ja otsikko. Osa 1: 20th-luvun hallituksen verkkosivuston kaavinta # From: leg_module_test.py # A simple function to turn a URL into a BeautifulSoup object import urllib.request from bs4 import BeautifulSoup def make_soup(url): thepage = urllib.request.urlopen(url) soupdata = BeautifulSoup(thepage, "lxml") return soupdata website ='https://capitol.texas.gov/BillLookup/History.aspx?LegSess=89R&Bill=SB1' soup = make_soup(website) # Find the author's name by its specific HTML ID for data in soup.findAll('td', id = 'cellAuthors'): print(data.text) Tämä toimi hyvin alkuperäisissä tiedoissa, mutta löysin nopeasti seinän. Käytä Selenium for JavaScript -ohjelmaa Arvokkain tieto ei ollut vakio linkki.Se oli piilotettu JavaScript-napsautustapahtuman taakse, joka avasi uuden ponnahdusikkunan. BeautifulSoup ei pysty suorittamaan JavaScriptia, joten se ei voinut nähdä linkkiä. Tämä on yleinen haaste nykyaikaisessa web-kaavinta. ratkaisu? , työkalu, joka automatisoi todellisen web-selaimen. Käyttämällä Seleniumia, käsikirjoitukseni voisi ladata sivun, odottaa, että JavaScript renderoi, ja sitten vuorovaikutuksessa painikkeen kanssa aivan kuten ihminen tekisi. Selenium Minun skripti texas_leg_txt_from_list.py käytti tätä lähestymistapaa vihdoin saada yhteenveto URL. # From: texas_leg_txt_from_list.py # Using Selenium to find an element and extract its JavaScript-based URL from selenium import webdriver from selenium.webdriver.common.by import By import time # ... (driver setup code) ... driver.get('https://capitol.texas.gov/BillLookup/Text.aspx?LegSess=75R&Bill=HB1') time.sleep(1.5) # Wait for the page to load # Find the summary link by its ID bill_summary_link = driver.find_element(By.ID, 'lnkBillSumm') # Get the 'onclick' attribute, which contains the JavaScript function call onclick_attribute = bill_summary_link.get_attribute('onclick') # A bit of string manipulation to extract the URL from the JavaScript start_index = onclick_attribute.find("('") + 2 end_index = onclick_attribute.find("'", start_index) bill_summary_url = 'https://capitol.texas.gov/BillLookup/' + onclick_attribute[start_index:end_index] print(f"Successfully extracted summary URL: {bill_summary_url}") driver.quit() Tämän avulla voisin luotettavasti kerätä kolme keskeistä tietojani tuhansille laskuille: pääsivun URL-osoite, koko kirjoitettu teksti ja virallinen yhteenveto. Osa 2: Puhdistamomiehistö - HTML-kaosin muuttaminen puhtaiksi tiedoiksi Web-tiedot ovat sotkuisia. Kaivettu teksti oli täynnä ylimääräistä valkoista tilaa, ei-rikkomattomia avaruusmerkkejä (\xa0), ja muita HTML-esineitä. Ennen kuin voisin syöttää tämän mallille, se tarvitsi vakavaa puhdistusta. Minun start_analysis_0.py skripti oli omistettu tähän ratkaisevaan vaiheeseen. Ensinnäkin kirjoitin yksinkertaisen puhdistustoiminnon, jossa käytettiin regexia standardoimaan valkoista tilaa ja poistamaan roskapostimerkkejä. # From: start_analysis_0.py # A function to clean raw text scraped from the web import re def clean_text(text): if not isinstance(text, str): return "" # Handle cases where data might not be a string text = re.sub(r'\s+', ' ', text) # Collapse all whitespace into single spaces text = text.replace('\xa0', ' ') # Remove non-breaking spaces text = text.replace('__','') # ... other replacements ... return text.strip() Seuraavaksi tein kriittisen laadunvalvonnan. Hyvän yhteenvedon pitäisi olla huomattavasti lyhyempi kuin alkuperäinen teksti, mutta ei niin lyhyt, että se olisi hyödytön. Päätin pitää vain pareja, joissa yhteenvedon pituus oli välillä 10% ja 100% koko laskun pituudesta. Tämä visualisointi vahvisti, että suurin osa tiedoistani putosi terveeseen jakeluun, mikä vahvisti suodatuslogiikkani. Osa 3: T5 -mallin hienosäätö Nyt on hauskaa, päätin käyttää sitä. tehokas ja monipuolinen tekstinsiirto-muunnin. T5 on loistava ohjeita seuraavia tehtäviä varten. Minun koulutusputkeni on rakennettu start_analysis_1.py ja start_analysis_2.py käyttämällä Hugging Face -muuntajia ja TensorFlow-kirjastoja. T5 pienikokoinen malli Opettele mallia Ydinprosessi näyttää tältä: Tokenisointi: Tämä vaihe muuntaa tekstin numeerisiksi tunnuksiksi, jotka malli voi ymmärtää. Olen luonut esikäsittelytoiminnon käsittelemään tätä sekä laskun tekstin (tulostus) että yhteenvedon (kohteenmerkki). # From: start_analysis_1.py # This function tokenizes the text and prepares it for the model from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained('t5-small') prefix = "summarize: " def preprocess_function(examples): # Prepare the input text with the "summarize: " prefix inputs = [prefix + doc for doc in examples["source_text"]] model_inputs = tokenizer(inputs, max_length=512, truncation=True) # Tokenize the target summaries with tokenizer.as_target_tokenizer(): labels = tokenizer(examples["target_text"], max_length=128, truncation=True) model_inputs["labels"] = labels["input_ids"] return model_inputs Data Loading: Laitoin puhdistetun JSON: n Hugging Face Dataset -objektiin ja käytin tokenisointia. Koulutus: Lopuksi olen määrittänyt mallin, asentanut optimoinnin ja käynnistänyt koulutusprosessin model.fit(). Tässä tapahtuu taikuus. Malli toistaa tiedot, tekee ennusteita, vertailee niitä virallisiin yhteenvetoihin ja säätää sisäisiä painojaan paremmaksi ja paremmaksi. # From: start_analysis_1.py # The final training call in TensorFlow import tensorflow as tf from transformers import TFAutoModelForSeq2SeqLM, AdamWeightDecay # ... (dataset and data_collator setup) ... optimizer = AdamWeightDecay(learning_rate=2e-5, weight_decay_rate=0.01) model = TFAutoModelForSeq2SeqLM.from_pretrained("t5-small") model.compile(optimizer=optimizer) # Let's train! model.fit( x=tf_train_set, validation_data=tf_test_set, epochs=3 ) # Save the fine-tuned model for later use model.save_pretrained("./t5_small_texas_bills") Osa 4: Tuomio - Onko se toiminut? Tuntien harjoittelun jälkeen totuuden hetki tuli. annoin mallille laskun, jota se ei ollut koskaan ennen nähnyt nähdäkseni, mitä se tuottaisi. Tässä on esimerkki: **Alkuperäinen lakiehdotus (Snippet): \ "...laki, joka koskee sellaisten arvonlisäverojen kokonaismäärän rajoituksen säätämistä, jotka koulupiiri voi määrätä ikääntyneiden tai vammaisten asuinpaikoille, jotta voidaan ottaa huomioon koulupiirin verokannan väheneminen ja suojella koulupiiriä paikallisten tulojen menetyksiltä..." **Alkuperäinen lakiehdotus (Snippet): \ "...laki, joka koskee sellaisten arvonlisäverojen kokonaismäärän rajoituksen säätämistä, jotka koulupiiri voi määrätä ikääntyneiden tai vammaisten asuinpaikoille, jotta voidaan ottaa huomioon koulupiirin verokannan väheneminen ja suojella koulupiiriä paikallisten tulojen menetyksiltä..." ** Virallinen yhteenveto (Totuus): \ "Tämä laki vähentää ikääntyneiden tai vammaisten asunnonomistajien koulupiirien arvonlisäverojen rajoitusta verokannan alennusten heijastamiseksi. se varmistaa, että koulupiirit korvataan tulonmenetyksestä. ** Virallinen yhteenveto (Totuus): \ "Tämä laki vähentää ikääntyneiden tai vammaisten asunnonomistajien koulupiirien arvonlisäverojen rajoitusta verokannan alennusten heijastamiseksi. se varmistaa, että koulupiirit korvataan tulonmenetyksestä. **AI-Generated Summary: \ "Lainsäädäntö koskee vähentämistä rajoitusta arvonlisäverojen kokonaismäärästä, jonka koulupiiri voi määrätä ikääntyneiden tai vammaisten asuinpaikoille. **AI-Generated Summary: \ "Lainsäädäntö koskee vähentämistä rajoitusta arvonlisäverojen kokonaismäärästä, jonka koulupiiri voi määrätä ikääntyneiden tai vammaisten asuinpaikoille. Analyysi: Malli tunnisti oikein pääaiheet (ad valorem verot, koulupiirit, ikääntyneet / vammaiset kotitaloudet) ja ydintoimenpiteet (verorajoituksen vähentäminen). Vaikka se ei ole yhtä eloisa kuin inhimillinen yhteenveto, se on tarkka ja kaappaa laskun olemuksen täydellisesti. Malli tunnisti oikein tärkeimmät aiheet (ad valorem verot, koulupiirit, ikääntyneet / vammaiset kotitaloudet) ja ydintoimenpiteet (verorajoituksen vähentäminen). Vaikka se ei ole yhtä eloisa kuin ihmisen yhteenveto, se on tarkka ja kaappaa laskun olemuksen täydellisesti. Analysis: Johtopäätös Tämä hanke oli voimakas muistutus siitä, että vaikutusvaltaisimmat AI-sovellukset luottavat usein perusteelliseen datatekniikkaan. Mallin rakentaminen oli työn lopullinen 20%; ensimmäinen 80% oli vaivalloinen prosessi tietojen hankkimiseksi ja puhdistamiseksi. Lopullinen malli ei ole täydellinen, mutta se on voimakas todiste käsitteestä.Se osoittaa, että voimme käyttää nykyaikaista tekoälyä tekemään monimutkaisista kansalaistiedoista kaikkien saatavilla. What's next? Käyttöliittymänä: Muunna tämä julkiseksi palveluksi, jossa kuka tahansa voi lähettää laskun tekstin ja saada yhteenvedon. Botin luominen: Lähettää yhteenvetoja äskettäin toimitetuista laskuista. Laajentuminen muihin valtioihin: Jokaisella lainsäädäntöelimellä on sama ongelma. Jos olet kehittäjä, kannustan sinua tarkastelemaan omia paikallishallinnon tietoja. Saatat löytää samanlaisen mahdollisuuden rakentaa jotain, joka paitsi teroittaa taitojasi myös palvelee yhteisöäsi.