1647710019
Cupertino Text Button
A button that looks like a Cupertino text button!
A simple text button can be created like this:
CupertinoTextButton(
text: 'Apply',
style: const TextStyle(fontSize: 20),
onTap: () {
// Do your text stuff here.
},
),
For text buttons you can configure the following properties:
Property | Type | Description |
---|---|---|
text | String | Title of the button |
style | TextStyle | Text style of the title |
textAlign | TextAlign | Text alignment of the button |
textDirection | TextDirection | The text direction to use for rendering the text |
textOverflow | TextOverflow | The text direction to use for rendering the text |
softWrap | bool | Whether the text should break at soft line breaks |
A simple material icon button can be created like this:
CupertinoTextButton.icon(
icon: Icons.chevron_left,
size: 30,
onTap: () {
// Do your icon stuff here.
},
),
For material icon buttons you can configure the following properties:
Property | Type | Description |
---|---|---|
icon | IconData | Icon to display |
size | double | Size of the icon |
textDirection | TextDirection | The text direction to use for rendering the icon |
Either you creating a text or an icon button, you can specify these properties:
Property | Type | Description |
---|---|---|
onTap | Function | On tap handler of the button |
onLongPress | Function | On long press handler of the button |
color | Color | Foreground color of the button in normal state, e.g. not pressed |
pressedColor | Color | Foreground color of the button in pressed state |
forwardDuration | Duration | Duration of the animation from color to pressedColor |
backwardDuration | Duration | Duration of the animation back from pressedColor to color |
curve | Curve | The animation curve. |
All these shared properties, except for the onTap
and onLongPress
ones, can be configured via the CupertinoTextButtonTheme
. Just wrap it around your app or any other parent widget above CupertinoTextButton
s in the tree like this:
CupertinoTextButtonTheme(
color: Colors.white,
pressedColor: Colors.orange,
/* forwardDuration, backwardDuration and curve can also be configured here. */
child: Row(
children: [
CupertinoTextButton(
text: 'First Option',
style: const TextStyle(fontSize: 20),
onTap: () {
// Do your first stuff here.
},
),
CupertinoTextButton(
text: 'Second Option',
style: const TextStyle(fontSize: 20),
onTap: () {
// Do your second stuff here.
},
),
],
),
)
And both of these text button will have the same colors!
If these properties are not specified in the button and no theme is provided, fallback values are used:
Property | Fallback Value |
---|---|
color | Colors.black |
pressedColor | Theme*.primaryColor |
forwardDuration | const Duration(milliseconds: 20) |
backwardDuration | const Duration(milliseconds: 200) |
curve | Curves.fastOutSlowIn |
* Theme — the default Flutter Theme.
Run this command:
With Flutter:
$ flutter pub add cupertino_text_button
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
cupertino_text_button: ^0.0.5
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:cupertino_text_button/cupertino_text_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cupertino_text_button/cupertino_text_button.dart';
void main() {
runApp(const MyApp());
}
const title = 'Cupertino Text Button Example';
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _noConfigurationCounter = 0;
int _withoutThemeCounter = 0;
int _withThemeCounter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Button without any configuration:',
style: const TextStyle(fontSize: 17),
),
CupertinoTextButton(
text: 'You pressed this button $_noConfigurationCounter times',
style: const TextStyle(fontSize: 20),
onTap: () {
setState(() {
_noConfigurationCounter++;
});
},
),
const SizedBox(height: 40),
Text(
'Button without theme:',
style: const TextStyle(fontSize: 17),
),
CupertinoTextButton(
color: Colors.purple,
pressedColor: Colors.orange,
text: 'You pressed this button $_withoutThemeCounter times',
style: const TextStyle(fontSize: 20),
onTap: () {
setState(() {
_withoutThemeCounter++;
});
},
),
const SizedBox(height: 40),
Text(
'Button with theme:',
style: const TextStyle(fontSize: 17),
),
CupertinoTextButtonTheme(
color: Colors.red,
pressedColor: Colors.lime,
forwardDuration: Duration(seconds: 1),
child: CupertinoTextButton(
text: 'You pressed this button $_withThemeCounter times',
style: const TextStyle(fontSize: 20),
onTap: () {
setState(() {
_withThemeCounter++;
});
},
),
),
const SizedBox(height: 40),
Text(
'Icon buttons:',
style: const TextStyle(fontSize: 17),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CupertinoTextButton.icon(
icon: Icons.add,
size: 50,
onTap: () {
debugPrint('First Icon button tapped!');
},
),
const SizedBox(width: 20),
CupertinoTextButton.icon(
icon: CupertinoIcons.add_circled,
size: 50,
onTap: () {
debugPrint('Second Icon button tapped!');
},
),
],
),
],
),
),
),
);
}
}
Download Details:
Author: nivisi
Source Code: https://github.com/nivisi/cupertino_text_button
1650870267
In the previous chapters you've learnt how to select individual elements on a web page. But there are many occasions where you need to access a child, parent or ancestor element. See the JavaScript DOM nodes chapter to understand the logical relationships between the nodes in a DOM tree.
DOM node provides several properties and methods that allow you to navigate or traverse through the tree structure of the DOM and make changes very easily. In the following section we will learn how to navigate up, down, and sideways in the DOM tree using JavaScript.
You can use the firstChild
and lastChild
properties of the DOM node to access the first and last direct child node of a node, respectively. If the node doesn't have any child element, it returns null
.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Prints: #text
var hint = document.getElementById("hint");
console.log(hint.firstChild.nodeName); // Prints: SPAN
</script>
Note: The
nodeName
is a read-only property that returns the name of the current node as a string. For example, it returns the tag name for element node,#text
for text node,#comment
for comment node,#document
for document node, and so on.
If you notice the above example, the nodeName
of the first-child node of the main DIV element returns #text instead of H1. Because, whitespace such as spaces, tabs, newlines, etc. are valid characters and they form #text nodes and become a part of the DOM tree. Therefore, since the <div>
tag contains a newline before the <h1>
tag, so it will create a #text node.
To avoid the issue with firstChild
and lastChild
returning #text or #comment nodes, you could alternatively use the firstElementChild
and lastElementChild
properties to return only the first and last element node, respectively. But, it will not work in IE 9 and earlier.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
alert(main.firstElementChild.nodeName); // Outputs: H1
main.firstElementChild.style.color = "red";
var hint = document.getElementById("hint");
alert(hint.firstElementChild.nodeName); // Outputs: SPAN
hint.firstElementChild.style.color = "blue";
</script>
Similarly, you can use the childNodes
property to access all child nodes of a given element, where the first child node is assigned index 0. Here's an example:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
// First check that the element has child nodes
if(main.hasChildNodes()) {
var nodes = main.childNodes;
// Loop through node list and display node name
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
The childNodes
returns all child nodes, including non-element nodes like text and comment nodes. To get a collection of only elements, use children
property instead.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
// First check that the element has child nodes
if(main.hasChildNodes()) {
var nodes = main.children;
// Loop through node list and display node name
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
1595494844
Are you leading an organization that has a large campus, e.g., a large university? You are probably thinking of introducing an electric scooter/bicycle fleet on the campus, and why wouldn’t you?
Introducing micro-mobility in your campus with the help of such a fleet would help the people on the campus significantly. People would save money since they don’t need to use a car for a short distance. Your campus will see a drastic reduction in congestion, moreover, its carbon footprint will reduce.
Micro-mobility is relatively new though and you would need help. You would need to select an appropriate fleet of vehicles. The people on your campus would need to find electric scooters or electric bikes for commuting, and you need to provide a solution for this.
To be more specific, you need a short-term electric bike rental app. With such an app, you will be able to easily offer micro-mobility to the people on the campus. We at Devathon have built Autorent exactly for this.
What does Autorent do and how can it help you? How does it enable you to introduce micro-mobility on your campus? We explain these in this article, however, we will touch upon a few basics first.
You are probably thinking about micro-mobility relatively recently, aren’t you? A few relevant insights about it could help you to better appreciate its importance.
Micro-mobility is a new trend in transportation, and it uses vehicles that are considerably smaller than cars. Electric scooters (e-scooters) and electric bikes (e-bikes) are the most popular forms of micro-mobility, however, there are also e-unicycles and e-skateboards.
You might have already seen e-scooters, which are kick scooters that come with a motor. Thanks to its motor, an e-scooter can achieve a speed of up to 20 km/h. On the other hand, e-bikes are popular in China and Japan, and they come with a motor, and you can reach a speed of 40 km/h.
You obviously can’t use these vehicles for very long commutes, however, what if you need to travel a short distance? Even if you have a reasonable public transport facility in the city, it might not cover the route you need to take. Take the example of a large university campus. Such a campus is often at a considerable distance from the central business district of the city where it’s located. While public transport facilities may serve the central business district, they wouldn’t serve this large campus. Currently, many people drive their cars even for short distances.
As you know, that brings its own set of challenges. Vehicular traffic adds significantly to pollution, moreover, finding a parking spot can be hard in crowded urban districts.
Well, you can reduce your carbon footprint if you use an electric car. However, electric cars are still new, and many countries are still building the necessary infrastructure for them. Your large campus might not have the necessary infrastructure for them either. Presently, electric cars don’t represent a viable option in most geographies.
As a result, you need to buy and maintain a car even if your commute is short. In addition to dealing with parking problems, you need to spend significantly on your car.
All of these factors have combined to make people sit up and think seriously about cars. Many people are now seriously considering whether a car is really the best option even if they have to commute only a short distance.
This is where micro-mobility enters the picture. When you commute a short distance regularly, e-scooters or e-bikes are viable options. You limit your carbon footprints and you cut costs!
Businesses have seen this shift in thinking, and e-scooter companies like Lime and Bird have entered this field in a big way. They let you rent e-scooters by the minute. On the other hand, start-ups like Jump and Lyft have entered the e-bike market.
Think of your campus now! The people there might need to travel short distances within the campus, and e-scooters can really help them.
What advantages can you get from micro-mobility? Let’s take a deeper look into this question.
Micro-mobility can offer several advantages to the people on your campus, e.g.:
#android app #autorent #ios app #mobile app development #app like bird #app like bounce #app like lime #autorent #bird scooter business model #bird scooter rental #bird scooter rental cost #bird scooter rental price #clone app like bird #clone app like bounce #clone app like lime #electric rental scooters #electric scooter company #electric scooter rental business #how do you start a moped #how to start a moped #how to start a scooter rental business #how to start an electric company #how to start electric scooterrental business #lime scooter business model #scooter franchise #scooter rental business #scooter rental business for sale #scooter rental business insurance #scooters franchise cost #white label app like bird #white label app like bounce #white label app like lime
1595491178
The electric scooter revolution has caught on super-fast taking many cities across the globe by storm. eScooters, a renovated version of old-school scooters now turned into electric vehicles are an environmentally friendly solution to current on-demand commute problems. They work on engines, like cars, enabling short traveling distances without hassle. The result is that these groundbreaking electric machines can now provide faster transport for less — cheaper than Uber and faster than Metro.
Since they are durable, fast, easy to operate and maintain, and are more convenient to park compared to four-wheelers, the eScooters trend has and continues to spike interest as a promising growth area. Several companies and universities are increasingly setting up shop to provide eScooter services realizing a would-be profitable business model and a ready customer base that is university students or residents in need of faster and cheap travel going about their business in school, town, and other surrounding areas.
In many countries including the U.S., Canada, Mexico, U.K., Germany, France, China, Japan, India, Brazil and Mexico and more, a growing number of eScooter users both locals and tourists can now be seen effortlessly passing lines of drivers stuck in the endless and unmoving traffic.
A recent report by McKinsey revealed that the E-Scooter industry will be worth― $200 billion to $300 billion in the United States, $100 billion to $150 billion in Europe, and $30 billion to $50 billion in China in 2030. The e-Scooter revenue model will also spike and is projected to rise by more than 20% amounting to approximately $5 billion.
And, with a necessity to move people away from high carbon prints, traffic and congestion issues brought about by car-centric transport systems in cities, more and more city planners are developing more bike/scooter lanes and adopting zero-emission plans. This is the force behind the booming electric scooter market and the numbers will only go higher and higher.
Companies that have taken advantage of the growing eScooter trend develop an appthat allows them to provide efficient eScooter services. Such an app enables them to be able to locate bike pick-up and drop points through fully integrated google maps.
It’s clear that e scooters will increasingly become more common and the e-scooter business model will continue to grab the attention of manufacturers, investors, entrepreneurs. All this should go ahead with a quest to know what are some of the best electric bikes in the market especially for anyone who would want to get started in the electric bikes/scooters rental business.
We have done a comprehensive list of the best electric bikes! Each bike has been reviewed in depth and includes a full list of specs and a photo.
https://www.kickstarter.com/projects/enkicycles/billy-were-redefining-joyrides
To start us off is the Billy eBike, a powerful go-anywhere urban electric bike that’s specially designed to offer an exciting ride like no other whether you want to ride to the grocery store, cafe, work or school. The Billy eBike comes in 4 color options – Billy Blue, Polished aluminium, Artic white, and Stealth black.
Price: $2490
Available countries
Available in the USA, Europe, Asia, South Africa and Australia.This item ships from the USA. Buyers are therefore responsible for any taxes and/or customs duties incurred once it arrives in your country.
Features
Specifications
Why Should You Buy This?
**Who Should Ride Billy? **
Both new and experienced riders
**Where to Buy? **Local distributors or ships from the USA.
Featuring a sleek and lightweight aluminum frame design, the 200-Series ebike takes your riding experience to greater heights. Available in both black and white this ebike comes with a connected app, which allows you to plan activities, map distances and routes while also allowing connections with fellow riders.
Price: $2099.00
Available countries
The Genze 200 series e-Bike is available at GenZe retail locations across the U.S or online via GenZe.com website. Customers from outside the US can ship the product while incurring the relevant charges.
Features
Specifications
https://ebikestore.com/shop/norco-vlt-s2/
The Norco VLT S2 is a front suspension e-Bike with solid components alongside the reliable Bosch Performance Line Power systems that offer precise pedal assistance during any riding situation.
Price: $2,699.00
Available countries
This item is available via the various Norco bikes international distributors.
Features
Specifications
http://www.bodoevs.com/bodoev/products_show.asp?product_id=13
Manufactured by Bodo Vehicle Group Limited, the Bodo EV is specially designed for strong power and extraordinary long service to facilitate super amazing rides. The Bodo Vehicle Company is a striking top in electric vehicles brand field in China and across the globe. Their Bodo EV will no doubt provide your riders with high-level riding satisfaction owing to its high-quality design, strength, breaking stability and speed.
Price: $799
Available countries
This item ships from China with buyers bearing the shipping costs and other variables prior to delivery.
Features
Specifications
#android app #autorent #entrepreneurship #ios app #minimum viable product (mvp) #mobile app development #news #app like bird #app like bounce #app like lime #autorent #best electric bikes 2020 #best electric bikes for rental business #best electric kick scooters 2020 #best electric kickscooters for rental business #best electric scooters 2020 #best electric scooters for rental business #bird scooter business model #bird scooter rental #bird scooter rental cost #bird scooter rental price #clone app like bird #clone app like bounce #clone app like lime #electric rental scooters #electric scooter company #electric scooter rental business #how do you start a moped #how to start a moped #how to start a scooter rental business #how to start an electric company #how to start electric scooterrental business #lime scooter business model #scooter franchise #scooter rental business #scooter rental business for sale #scooter rental business insurance #scooters franchise cost #white label app like bird #white label app like bounce #white label app like lime
1647710019
Cupertino Text Button
A button that looks like a Cupertino text button!
A simple text button can be created like this:
CupertinoTextButton(
text: 'Apply',
style: const TextStyle(fontSize: 20),
onTap: () {
// Do your text stuff here.
},
),
For text buttons you can configure the following properties:
Property | Type | Description |
---|---|---|
text | String | Title of the button |
style | TextStyle | Text style of the title |
textAlign | TextAlign | Text alignment of the button |
textDirection | TextDirection | The text direction to use for rendering the text |
textOverflow | TextOverflow | The text direction to use for rendering the text |
softWrap | bool | Whether the text should break at soft line breaks |
A simple material icon button can be created like this:
CupertinoTextButton.icon(
icon: Icons.chevron_left,
size: 30,
onTap: () {
// Do your icon stuff here.
},
),
For material icon buttons you can configure the following properties:
Property | Type | Description |
---|---|---|
icon | IconData | Icon to display |
size | double | Size of the icon |
textDirection | TextDirection | The text direction to use for rendering the icon |
Either you creating a text or an icon button, you can specify these properties:
Property | Type | Description |
---|---|---|
onTap | Function | On tap handler of the button |
onLongPress | Function | On long press handler of the button |
color | Color | Foreground color of the button in normal state, e.g. not pressed |
pressedColor | Color | Foreground color of the button in pressed state |
forwardDuration | Duration | Duration of the animation from color to pressedColor |
backwardDuration | Duration | Duration of the animation back from pressedColor to color |
curve | Curve | The animation curve. |
All these shared properties, except for the onTap
and onLongPress
ones, can be configured via the CupertinoTextButtonTheme
. Just wrap it around your app or any other parent widget above CupertinoTextButton
s in the tree like this:
CupertinoTextButtonTheme(
color: Colors.white,
pressedColor: Colors.orange,
/* forwardDuration, backwardDuration and curve can also be configured here. */
child: Row(
children: [
CupertinoTextButton(
text: 'First Option',
style: const TextStyle(fontSize: 20),
onTap: () {
// Do your first stuff here.
},
),
CupertinoTextButton(
text: 'Second Option',
style: const TextStyle(fontSize: 20),
onTap: () {
// Do your second stuff here.
},
),
],
),
)
And both of these text button will have the same colors!
If these properties are not specified in the button and no theme is provided, fallback values are used:
Property | Fallback Value |
---|---|
color | Colors.black |
pressedColor | Theme*.primaryColor |
forwardDuration | const Duration(milliseconds: 20) |
backwardDuration | const Duration(milliseconds: 200) |
curve | Curves.fastOutSlowIn |
* Theme — the default Flutter Theme.
Run this command:
With Flutter:
$ flutter pub add cupertino_text_button
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
cupertino_text_button: ^0.0.5
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:cupertino_text_button/cupertino_text_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cupertino_text_button/cupertino_text_button.dart';
void main() {
runApp(const MyApp());
}
const title = 'Cupertino Text Button Example';
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _noConfigurationCounter = 0;
int _withoutThemeCounter = 0;
int _withThemeCounter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Button without any configuration:',
style: const TextStyle(fontSize: 17),
),
CupertinoTextButton(
text: 'You pressed this button $_noConfigurationCounter times',
style: const TextStyle(fontSize: 20),
onTap: () {
setState(() {
_noConfigurationCounter++;
});
},
),
const SizedBox(height: 40),
Text(
'Button without theme:',
style: const TextStyle(fontSize: 17),
),
CupertinoTextButton(
color: Colors.purple,
pressedColor: Colors.orange,
text: 'You pressed this button $_withoutThemeCounter times',
style: const TextStyle(fontSize: 20),
onTap: () {
setState(() {
_withoutThemeCounter++;
});
},
),
const SizedBox(height: 40),
Text(
'Button with theme:',
style: const TextStyle(fontSize: 17),
),
CupertinoTextButtonTheme(
color: Colors.red,
pressedColor: Colors.lime,
forwardDuration: Duration(seconds: 1),
child: CupertinoTextButton(
text: 'You pressed this button $_withThemeCounter times',
style: const TextStyle(fontSize: 20),
onTap: () {
setState(() {
_withThemeCounter++;
});
},
),
),
const SizedBox(height: 40),
Text(
'Icon buttons:',
style: const TextStyle(fontSize: 17),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CupertinoTextButton.icon(
icon: Icons.add,
size: 50,
onTap: () {
debugPrint('First Icon button tapped!');
},
),
const SizedBox(width: 20),
CupertinoTextButton.icon(
icon: CupertinoIcons.add_circled,
size: 50,
onTap: () {
debugPrint('Second Icon button tapped!');
},
),
],
),
],
),
),
),
);
}
}
Download Details:
Author: nivisi
Source Code: https://github.com/nivisi/cupertino_text_button
1646025910
Khám phá tập dữ liệu tin tức giả, thực hiện phân tích dữ liệu chẳng hạn như đám mây từ và ngram, đồng thời tinh chỉnh máy biến áp BERT để xây dựng bộ phát hiện tin tức giả bằng Python bằng cách sử dụng thư viện máy biến áp.
Tin tức giả là việc cố ý phát đi các tuyên bố sai sự thật hoặc gây hiểu lầm như một tin tức, trong đó các tuyên bố là cố ý lừa dối.
Báo chí, báo lá cải và tạp chí đã được thay thế bởi các nền tảng tin tức kỹ thuật số, blog, nguồn cấp dữ liệu truyền thông xã hội và rất nhiều ứng dụng tin tức di động. Các tổ chức tin tức được hưởng lợi từ việc tăng cường sử dụng mạng xã hội và các nền tảng di động bằng cách cung cấp cho người đăng ký thông tin cập nhật từng phút.
Người tiêu dùng hiện có thể truy cập ngay vào những tin tức mới nhất. Các nền tảng truyền thông kỹ thuật số này ngày càng nổi tiếng do khả năng kết nối dễ dàng với phần còn lại của thế giới và cho phép người dùng thảo luận, chia sẻ ý tưởng và tranh luận về các chủ đề như dân chủ, giáo dục, y tế, nghiên cứu và lịch sử. Các mục tin tức giả mạo trên các nền tảng kỹ thuật số ngày càng phổ biến và được sử dụng để thu lợi nhuận, chẳng hạn như lợi ích chính trị và tài chính.
Bởi vì Internet, phương tiện truyền thông xã hội và các nền tảng kỹ thuật số được sử dụng rộng rãi, bất kỳ ai cũng có thể tuyên truyền thông tin không chính xác và thiên vị. Gần như không thể ngăn chặn sự lan truyền của tin tức giả mạo. Có một sự gia tăng đáng kể trong việc phát tán tin tức sai lệch, không chỉ giới hạn trong một lĩnh vực như chính trị mà bao gồm thể thao, sức khỏe, lịch sử, giải trí, khoa học và nghiên cứu.
Điều quan trọng là phải nhận biết và phân biệt giữa tin tức sai và tin tức chính xác. Một phương pháp là nhờ một chuyên gia quyết định và kiểm tra thực tế mọi thông tin, nhưng điều này cần thời gian và cần chuyên môn không thể chia sẻ được. Thứ hai, chúng ta có thể sử dụng các công cụ học máy và trí tuệ nhân tạo để tự động hóa việc xác định tin tức giả mạo.
Thông tin tin tức trực tuyến bao gồm nhiều dữ liệu định dạng phi cấu trúc khác nhau (chẳng hạn như tài liệu, video và âm thanh), nhưng chúng tôi sẽ tập trung vào tin tức định dạng văn bản ở đây. Với tiến bộ của học máy và xử lý ngôn ngữ tự nhiên , giờ đây chúng ta có thể nhận ra đặc điểm gây hiểu lầm và sai của một bài báo hoặc câu lệnh.
Một số nghiên cứu và thử nghiệm đang được tiến hành để phát hiện tin tức giả trên tất cả các phương tiện.
Mục tiêu chính của chúng tôi trong hướng dẫn này là:
Đây là bảng nội dung:
Trong công việc này, chúng tôi đã sử dụng tập dữ liệu tin tức giả từ Kaggle để phân loại các bài báo không đáng tin cậy là tin giả. Chúng tôi có một tập dữ liệu đào tạo hoàn chỉnh chứa các đặc điểm sau:
id
: id duy nhất cho một bài báotitle
: tiêu đề của một bài báoauthor
: tác giả của bài báotext
: văn bản của bài báo; có thể không đầy đủlabel
: nhãn đánh dấu bài viết có khả năng không đáng tin cậy được ký hiệu bằng 1 (không đáng tin cậy hoặc giả mạo) hoặc 0 (đáng tin cậy).Đó là một bài toán phân loại nhị phân, trong đó chúng ta phải dự đoán xem một câu chuyện tin tức cụ thể có đáng tin cậy hay không.
Nếu bạn có tài khoản Kaggle, bạn có thể chỉ cần tải xuống bộ dữ liệu từ trang web ở đó và giải nén tệp ZIP.
Tôi cũng đã tải tập dữ liệu lên Google Drive và bạn có thể tải tập dữ liệu đó tại đây hoặc sử dụng gdown
thư viện để tự động tải xuống tập dữ liệu trong sổ ghi chép Google Colab hoặc Jupyter:
$ pip install gdown
# download from Google Drive
$ gdown "https://drive.google.com/uc?id=178f_VkNxccNidap-5-uffXUW475pAuPy&confirm=t"
Downloading...
From: https://drive.google.com/uc?id=178f_VkNxccNidap-5-uffXUW475pAuPy&confirm=t
To: /content/fake-news.zip
100% 48.7M/48.7M [00:00<00:00, 74.6MB/s]
Giải nén các tệp:
$ unzip fake-news.zip
Ba tệp sẽ xuất hiện trong thư mục làm việc hiện tại:, và train.csv
, chúng tôi sẽ sử dụng trong hầu hết các hướng dẫn.test.csvsubmit.csvtrain.csv
Cài đặt các phụ thuộc bắt buộc:
$ pip install transformers nltk pandas numpy matplotlib seaborn wordcloud
Lưu ý: Nếu bạn đang ở trong môi trường cục bộ, hãy đảm bảo rằng bạn cài đặt PyTorch cho GPU, hãy truy cập trang này để cài đặt đúng cách.
Hãy nhập các thư viện cần thiết để phân tích:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
Kho tập tin NLTK và mô-đun phải được cài đặt bằng trình tải xuống NLTK tiêu chuẩn:
import nltk
nltk.download('stopwords')
nltk.download('wordnet')
Tập dữ liệu tin tức giả bao gồm các tiêu đề và văn bản bài báo gốc và hư cấu của nhiều tác giả khác nhau. Hãy nhập tập dữ liệu của chúng tôi:
# load the dataset
news_d = pd.read_csv("train.csv")
print("Shape of News data:", news_d.shape)
print("News data columns", news_d.columns)
Đầu ra:
Shape of News data: (20800, 5)
News data columns Index(['id', 'title', 'author', 'text', 'label'], dtype='object')
Đây là giao diện của tập dữ liệu:
# by using df.head(), we can immediately familiarize ourselves with the dataset.
news_d.head()
Đầu ra:
id title author text label
0 0 House Dem Aide: We Didn’t Even See Comey’s Let... Darrell Lucus House Dem Aide: We Didn’t Even See Comey’s Let... 1
1 1 FLYNN: Hillary Clinton, Big Woman on Campus - ... Daniel J. Flynn Ever get the feeling your life circles the rou... 0
2 2 Why the Truth Might Get You Fired Consortiumnews.com Why the Truth Might Get You Fired October 29, ... 1
3 3 15 Civilians Killed In Single US Airstrike Hav... Jessica Purkiss Videos 15 Civilians Killed In Single US Airstr... 1
4 4 Iranian woman jailed for fictional unpublished... Howard Portnoy Print \nAn Iranian woman has been sentenced to... 1
Chúng tôi có 20.800 hàng, có năm cột. Hãy cùng xem một số thống kê của chuyên text
mục:
#Text Word startistics: min.mean, max and interquartile range
txt_length = news_d.text.str.split().str.len()
txt_length.describe()
Đầu ra:
count 20761.000000
mean 760.308126
std 869.525988
min 0.000000
25% 269.000000
50% 556.000000
75% 1052.000000
max 24234.000000
Name: text, dtype: float64
Số liệu thống kê cho title
cột:
#Title statistics
title_length = news_d.title.str.split().str.len()
title_length.describe()
Đầu ra:
count 20242.000000
mean 12.420709
std 4.098735
min 1.000000
25% 10.000000
50% 13.000000
75% 15.000000
max 72.000000
Name: title, dtype: float64
Số liệu thống kê cho các tập huấn luyện và kiểm tra như sau:
text
tính có số từ cao hơn với trung bình 760 từ và 75% có hơn 1000 từ.title
tính là một câu lệnh ngắn với trung bình 12 từ và 75% trong số đó là khoảng 15 từ.Thử nghiệm của chúng tôi sẽ kết hợp cả văn bản và tiêu đề.
Đếm các ô cho cả hai nhãn:
sns.countplot(x="label", data=news_d);
print("1: Unreliable")
print("0: Reliable")
print("Distribution of labels:")
print(news_d.label.value_counts());
Đầu ra:
1: Unreliable
0: Reliable
Distribution of labels:
1 10413
0 10387
Name: label, dtype: int64
print(round(news_d.label.value_counts(normalize=True),2)*100);
Đầu ra:
1 50.0
0 50.0
Name: label, dtype: float64
Số lượng bài báo không đáng tin cậy (giả mạo hoặc 1) là 10413, trong khi số bài báo đáng tin cậy (đáng tin cậy hoặc 0) là 10387. Gần 50% số bài báo là giả mạo. Do đó, chỉ số độ chính xác sẽ đo lường mức độ hoạt động của mô hình của chúng tôi khi xây dựng bộ phân loại.
Trong phần này, chúng tôi sẽ làm sạch tập dữ liệu của mình để thực hiện một số phân tích:
# Constants that are used to sanitize the datasets
column_n = ['id', 'title', 'author', 'text', 'label']
remove_c = ['id','author']
categorical_features = []
target_col = ['label']
text_f = ['title', 'text']
# Clean Datasets
import nltk
from nltk.corpus import stopwords
import re
from nltk.stem.porter import PorterStemmer
from collections import Counter
ps = PorterStemmer()
wnl = nltk.stem.WordNetLemmatizer()
stop_words = stopwords.words('english')
stopwords_dict = Counter(stop_words)
# Removed unused clumns
def remove_unused_c(df,column_n=remove_c):
df = df.drop(column_n,axis=1)
return df
# Impute null values with None
def null_process(feature_df):
for col in text_f:
feature_df.loc[feature_df[col].isnull(), col] = "None"
return feature_df
def clean_dataset(df):
# remove unused column
df = remove_unused_c(df)
#impute null values
df = null_process(df)
return df
# Cleaning text from unused characters
def clean_text(text):
text = str(text).replace(r'http[\w:/\.]+', ' ') # removing urls
text = str(text).replace(r'[^\.\w\s]', ' ') # remove everything but characters and punctuation
text = str(text).replace('[^a-zA-Z]', ' ')
text = str(text).replace(r'\s\s+', ' ')
text = text.lower().strip()
#text = ' '.join(text)
return text
## Nltk Preprocessing include:
# Stop words, Stemming and Lemmetization
# For our project we use only Stop word removal
def nltk_preprocess(text):
text = clean_text(text)
wordlist = re.sub(r'[^\w\s]', '', text).split()
#text = ' '.join([word for word in wordlist if word not in stopwords_dict])
#text = [ps.stem(word) for word in wordlist if not word in stopwords_dict]
text = ' '.join([wnl.lemmatize(word) for word in wordlist if word not in stopwords_dict])
return text
Trong khối mã trên:
re
cho regex.nltk.corpus
. Khi làm việc với các từ, đặc biệt là khi xem xét ngữ nghĩa, đôi khi chúng ta cần loại bỏ các từ phổ biến không bổ sung bất kỳ ý nghĩa quan trọng nào cho một câu lệnh, chẳng hạn như "but"
,, v.v."can""we"
PorterStemmer
được sử dụng để thực hiện các từ gốc với NLTK. Các gốc từ loại bỏ các phụ tố hình thái của các từ, chỉ để lại phần gốc của từ.WordNetLemmatizer()
từ thư viện NLTK để lemmatization. Lemmatization hiệu quả hơn nhiều so với việc chiết cành . Nó vượt ra ngoài việc rút gọn từ và đánh giá toàn bộ từ vựng của một ngôn ngữ để áp dụng phân tích hình thái học cho các từ, với mục tiêu chỉ loại bỏ các kết thúc không theo chiều hướng và trả lại dạng cơ sở hoặc dạng từ điển của một từ, được gọi là bổ đề.stopwords.words('english')
cho phép chúng tôi xem danh sách tất cả các từ dừng tiếng Anh được NLTK hỗ trợ.remove_unused_c()
được sử dụng để loại bỏ các cột không sử dụng.None
cách sử dụng null_process()
hàm.clean_dataset()
, chúng ta gọi remove_unused_c()
và null_process()
hàm. Chức năng này có nhiệm vụ làm sạch dữ liệu.clean_text()
hàm.nltk_preprocess()
chức năng cho mục đích đó.Tiền xử lý text
và title
:
# Perform data cleaning on train and test dataset by calling clean_dataset function
df = clean_dataset(news_d)
# apply preprocessing on text through apply method by calling the function nltk_preprocess
df["text"] = df.text.apply(nltk_preprocess)
# apply preprocessing on title through apply method by calling the function nltk_preprocess
df["title"] = df.title.apply(nltk_preprocess)
# Dataset after cleaning and preprocessing step
df.head()
Đầu ra:
title text label
0 house dem aide didnt even see comeys letter ja... house dem aide didnt even see comeys letter ja... 1
1 flynn hillary clinton big woman campus breitbart ever get feeling life circle roundabout rather... 0
2 truth might get fired truth might get fired october 29 2016 tension ... 1
3 15 civilian killed single u airstrike identified video 15 civilian killed single u airstrike id... 1
4 iranian woman jailed fictional unpublished sto... print iranian woman sentenced six year prison ... 1
Trong phần này, chúng tôi sẽ thực hiện:
Các từ phổ biến nhất xuất hiện ở phông chữ đậm và lớn hơn trong đám mây từ. Phần này sẽ thực hiện một đám mây từ cho tất cả các từ trong tập dữ liệu.
Chức năng của thư viện WordCloudwordcloud()
sẽ được sử dụng và generate()
được sử dụng để tạo hình ảnh đám mây từ:
from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
# initialize the word cloud
wordcloud = WordCloud( background_color='black', width=800, height=600)
# generate the word cloud by passing the corpus
text_cloud = wordcloud.generate(' '.join(df['text']))
# plotting the word cloud
plt.figure(figsize=(20,30))
plt.imshow(text_cloud)
plt.axis('off')
plt.show()
Đầu ra:
Đám mây từ chỉ dành cho tin tức đáng tin cậy:
true_n = ' '.join(df[df['label']==0]['text'])
wc = wordcloud.generate(true_n)
plt.figure(figsize=(20,30))
plt.imshow(wc)
plt.axis('off')
plt.show()
Đầu ra:
Word cloud chỉ dành cho tin tức giả mạo:
fake_n = ' '.join(df[df['label']==1]['text'])
wc= wordcloud.generate(fake_n)
plt.figure(figsize=(20,30))
plt.imshow(wc)
plt.axis('off')
plt.show()
Đầu ra:
N-gram là một chuỗi các chữ cái hoặc từ. Một ký tự unigram được tạo thành từ một ký tự duy nhất, trong khi một bigram bao gồm một chuỗi hai ký tự. Tương tự, từ N-gram được tạo thành từ một chuỗi n từ. Từ "thống nhất" là 1 gam (unigram). Sự kết hợp của các từ "bang thống nhất" là 2 gam (bigram), "thành phố new york" là 3 gam.
Hãy vẽ biểu đồ phổ biến nhất trên tin tức đáng tin cậy:
def plot_top_ngrams(corpus, title, ylabel, xlabel="Number of Occurences", n=2):
"""Utility function to plot top n-grams"""
true_b = (pd.Series(nltk.ngrams(corpus.split(), n)).value_counts())[:20]
true_b.sort_values().plot.barh(color='blue', width=.9, figsize=(12, 8))
plt.title(title)
plt.ylabel(ylabel)
plt.xlabel(xlabel)
plt.show()
plot_top_ngrams(true_n, 'Top 20 Frequently Occuring True news Bigrams', "Bigram", n=2)
Biểu đồ phổ biến nhất về tin tức giả:
plot_top_ngrams(fake_n, 'Top 20 Frequently Occuring Fake news Bigrams', "Bigram", n=2)
Hình bát quái phổ biến nhất trên các tin tức đáng tin cậy:
plot_top_ngrams(true_n, 'Top 20 Frequently Occuring True news Trigrams', "Trigrams", n=3)
Đối với tin tức giả mạo bây giờ:
plot_top_ngrams(fake_n, 'Top 20 Frequently Occuring Fake news Trigrams', "Trigrams", n=3)
Các biểu đồ trên cho chúng ta một số ý tưởng về giao diện của cả hai lớp. Trong phần tiếp theo, chúng ta sẽ sử dụng thư viện máy biến áp để xây dựng công cụ phát hiện tin tức giả.
Phần này sẽ lấy mã rộng rãi từ hướng dẫn tinh chỉnh BERT để tạo bộ phân loại tin tức giả bằng cách sử dụng thư viện máy biến áp. Vì vậy, để biết thêm thông tin chi tiết, bạn có thể xem hướng dẫn ban đầu .
Nếu bạn không cài đặt máy biến áp, bạn phải:
$ pip install transformers
Hãy nhập các thư viện cần thiết:
import torch
from transformers.file_utils import is_tf_available, is_torch_available, is_torch_tpu_available
from transformers import BertTokenizerFast, BertForSequenceClassification
from transformers import Trainer, TrainingArguments
import numpy as np
from sklearn.model_selection import train_test_split
import random
Chúng tôi muốn làm cho kết quả của chúng tôi có thể tái tạo ngay cả khi chúng tôi khởi động lại môi trường của mình:
def set_seed(seed: int):
"""
Helper function for reproducible behavior to set the seed in ``random``, ``numpy``, ``torch`` and/or ``tf`` (if
installed).
Args:
seed (:obj:`int`): The seed to set.
"""
random.seed(seed)
np.random.seed(seed)
if is_torch_available():
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
# ^^ safe to call this function even if cuda is not available
if is_tf_available():
import tensorflow as tf
tf.random.set_seed(seed)
set_seed(1)
Mô hình chúng tôi sẽ sử dụng là bert-base-uncased
:
# the model we gonna train, base uncased BERT
# check text classification models here: https://huggingface.co/models?filter=text-classification
model_name = "bert-base-uncased"
# max sequence length for each document/sentence sample
max_length = 512
Đang tải tokenizer:
# load the tokenizer
tokenizer = BertTokenizerFast.from_pretrained(model_name, do_lower_case=True)
Bây giờ chúng ta hãy làm sạch NaN
các giá trị khỏi text
và author
các title
cột:
news_df = news_d[news_d['text'].notna()]
news_df = news_df[news_df["author"].notna()]
news_df = news_df[news_df["title"].notna()]
Tiếp theo, tạo một hàm lấy tập dữ liệu làm khung dữ liệu Pandas và trả về phần tách dòng / xác thực của văn bản và nhãn dưới dạng danh sách:
def prepare_data(df, test_size=0.2, include_title=True, include_author=True):
texts = []
labels = []
for i in range(len(df)):
text = df["text"].iloc[i]
label = df["label"].iloc[i]
if include_title:
text = df["title"].iloc[i] + " - " + text
if include_author:
text = df["author"].iloc[i] + " : " + text
if text and label in [0, 1]:
texts.append(text)
labels.append(label)
return train_test_split(texts, labels, test_size=test_size)
train_texts, valid_texts, train_labels, valid_labels = prepare_data(news_df)
Hàm trên nhận tập dữ liệu trong một kiểu khung dữ liệu và trả về chúng dưới dạng danh sách được chia thành các tập hợp lệ và huấn luyện. Đặt include_title
thành True
có nghĩa là chúng tôi thêm title
cột vào mục text
chúng tôi sẽ sử dụng để đào tạo, đặt include_author
thành True
có nghĩa là chúng tôi cũng thêm author
vào văn bản.
Hãy đảm bảo rằng các nhãn và văn bản có cùng độ dài:
print(len(train_texts), len(train_labels))
print(len(valid_texts), len(valid_labels))
Đầu ra:
14628 14628
3657 3657
Hãy sử dụng trình mã hóa BERT để mã hóa tập dữ liệu của chúng ta:
# tokenize the dataset, truncate when passed `max_length`,
# and pad with 0's when less than `max_length`
train_encodings = tokenizer(train_texts, truncation=True, padding=True, max_length=max_length)
valid_encodings = tokenizer(valid_texts, truncation=True, padding=True, max_length=max_length)
Chuyển đổi các mã hóa thành tập dữ liệu PyTorch:
class NewsGroupsDataset(torch.utils.data.Dataset):
def __init__(self, encodings, labels):
self.encodings = encodings
self.labels = labels
def __getitem__(self, idx):
item = {k: torch.tensor(v[idx]) for k, v in self.encodings.items()}
item["labels"] = torch.tensor([self.labels[idx]])
return item
def __len__(self):
return len(self.labels)
# convert our tokenized data into a torch Dataset
train_dataset = NewsGroupsDataset(train_encodings, train_labels)
valid_dataset = NewsGroupsDataset(valid_encodings, valid_labels)
Chúng tôi sẽ sử dụng BertForSequenceClassification
để tải mô hình máy biến áp BERT của chúng tôi:
# load the model
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=2)
Chúng tôi đặt num_labels
thành 2 vì đó là phân loại nhị phân. Hàm dưới đây là một lệnh gọi lại để tính độ chính xác trên mỗi bước xác thực:
from sklearn.metrics import accuracy_score
def compute_metrics(pred):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
# calculate accuracy using sklearn's function
acc = accuracy_score(labels, preds)
return {
'accuracy': acc,
}
Hãy khởi tạo các tham số huấn luyện:
training_args = TrainingArguments(
output_dir='./results', # output directory
num_train_epochs=1, # total number of training epochs
per_device_train_batch_size=10, # batch size per device during training
per_device_eval_batch_size=20, # batch size for evaluation
warmup_steps=100, # number of warmup steps for learning rate scheduler
logging_dir='./logs', # directory for storing logs
load_best_model_at_end=True, # load the best model when finished training (default metric is loss)
# but you can specify `metric_for_best_model` argument to change to accuracy or other metric
logging_steps=200, # log & save weights each logging_steps
save_steps=200,
evaluation_strategy="steps", # evaluate each `logging_steps`
)
Tôi đã đặt thành per_device_train_batch_size
10, nhưng bạn nên đặt nó cao nhất có thể phù hợp với GPU của bạn. Đặt logging_steps
và save_steps
thành 200, nghĩa là chúng ta sẽ thực hiện đánh giá và lưu trọng số của mô hình trên mỗi 200 bước huấn luyện.
Bạn có thể kiểm tra trang này để biết thêm thông tin chi tiết về các thông số đào tạo có sẵn.
Hãy khởi tạo trình huấn luyện:
trainer = Trainer(
model=model, # the instantiated Transformers model to be trained
args=training_args, # training arguments, defined above
train_dataset=train_dataset, # training dataset
eval_dataset=valid_dataset, # evaluation dataset
compute_metrics=compute_metrics, # the callback that computes metrics of interest
)
Đào tạo người mẫu:
# train the model
trainer.train()
Quá trình đào tạo mất vài giờ để kết thúc, tùy thuộc vào GPU của bạn. Nếu bạn đang sử dụng phiên bản Colab miễn phí, sẽ mất một giờ với NVIDIA Tesla K80. Đây là kết quả:
***** Running training *****
Num examples = 14628
Num Epochs = 1
Instantaneous batch size per device = 10
Total train batch size (w. parallel, distributed & accumulation) = 10
Gradient Accumulation steps = 1
Total optimization steps = 1463
[1463/1463 41:07, Epoch 1/1]
Step Training Loss Validation Loss Accuracy
200 0.250800 0.100533 0.983867
400 0.027600 0.043009 0.993437
600 0.023400 0.017812 0.997539
800 0.014900 0.030269 0.994258
1000 0.022400 0.012961 0.998086
1200 0.009800 0.010561 0.998633
1400 0.007700 0.010300 0.998633
***** Running Evaluation *****
Num examples = 3657
Batch size = 20
Saving model checkpoint to ./results/checkpoint-200
Configuration saved in ./results/checkpoint-200/config.json
Model weights saved in ./results/checkpoint-200/pytorch_model.bin
<SNIPPED>
***** Running Evaluation *****
Num examples = 3657
Batch size = 20
Saving model checkpoint to ./results/checkpoint-1400
Configuration saved in ./results/checkpoint-1400/config.json
Model weights saved in ./results/checkpoint-1400/pytorch_model.bin
Training completed. Do not forget to share your model on huggingface.co/models =)
Loading best model from ./results/checkpoint-1400 (score: 0.010299865156412125).
TrainOutput(global_step=1463, training_loss=0.04888018785440506, metrics={'train_runtime': 2469.1722, 'train_samples_per_second': 5.924, 'train_steps_per_second': 0.593, 'total_flos': 3848788517806080.0, 'train_loss': 0.04888018785440506, 'epoch': 1.0})
Vì load_best_model_at_end
được đặt thành True
, mức tạ tốt nhất sẽ được tải khi quá trình tập luyện hoàn thành. Hãy đánh giá nó với bộ xác thực của chúng tôi:
# evaluate the current model after training
trainer.evaluate()
Đầu ra:
***** Running Evaluation *****
Num examples = 3657
Batch size = 20
[183/183 02:11]
{'epoch': 1.0,
'eval_accuracy': 0.998632759092152,
'eval_loss': 0.010299865156412125,
'eval_runtime': 132.0374,
'eval_samples_per_second': 27.697,
'eval_steps_per_second': 1.386}
Lưu mô hình và tokenizer:
# saving the fine tuned model & tokenizer
model_path = "fake-news-bert-base-uncased"
model.save_pretrained(model_path)
tokenizer.save_pretrained(model_path)
Một thư mục mới chứa cấu hình mô hình và trọng số sẽ xuất hiện sau khi chạy ô trên. Nếu bạn muốn thực hiện dự đoán, bạn chỉ cần sử dụng from_pretrained()
phương pháp chúng tôi đã sử dụng khi tải mô hình và bạn đã sẵn sàng.
Tiếp theo, hãy tạo một hàm chấp nhận văn bản bài viết làm đối số và trả về cho dù nó là giả mạo hay không:
def get_prediction(text, convert_to_label=False):
# prepare our text into tokenized sequence
inputs = tokenizer(text, padding=True, truncation=True, max_length=max_length, return_tensors="pt").to("cuda")
# perform inference to our model
outputs = model(**inputs)
# get output probabilities by doing softmax
probs = outputs[0].softmax(1)
# executing argmax function to get the candidate label
d = {
0: "reliable",
1: "fake"
}
if convert_to_label:
return d[int(probs.argmax())]
else:
return int(probs.argmax())
Tôi đã lấy một ví dụ từ test.csv
mô hình chưa từng thấy để thực hiện suy luận, tôi đã kiểm tra nó và đó là một bài báo thực tế từ The New York Times:
real_news = """
Tim Tebow Will Attempt Another Comeback, This Time in Baseball - The New York Times",Daniel Victor,"If at first you don’t succeed, try a different sport. Tim Tebow, who was a Heisman quarterback at the University of Florida but was unable to hold an N. F. L. job, is pursuing a career in Major League Baseball. <SNIPPED>
"""
Văn bản gốc nằm trong môi trường Colab nếu bạn muốn sao chép nó, vì nó là một bài báo hoàn chỉnh. Hãy chuyển nó cho mô hình và xem kết quả:
get_prediction(real_news, convert_to_label=True)
Đầu ra:
reliable
Trong phần này, chúng tôi sẽ dự đoán tất cả các bài trong phần test.csv
để tạo hồ sơ gửi để xem độ chính xác của chúng tôi trong bộ bài kiểm tra của cuộc thi Kaggle :
# read the test set
test_df = pd.read_csv("test.csv")
# make a copy of the testing set
new_df = test_df.copy()
# add a new column that contains the author, title and article content
new_df["new_text"] = new_df["author"].astype(str) + " : " + new_df["title"].astype(str) + " - " + new_df["text"].astype(str)
# get the prediction of all the test set
new_df["label"] = new_df["new_text"].apply(get_prediction)
# make the submission file
final_df = new_df[["id", "label"]]
final_df.to_csv("submit_final.csv", index=False)
Sau khi chúng tôi nối tác giả, tiêu đề và văn bản bài viết với nhau, chúng tôi truyền get_prediction()
hàm vào cột mới để lấp đầy label
cột, sau đó chúng tôi sử dụng to_csv()
phương thức để tạo tệp gửi cho Kaggle. Đây là điểm nộp bài của tôi:
Chúng tôi nhận được độ chính xác 99,78% và 100% trên bảng xếp hạng riêng tư và công khai. Thật tuyệt vời!
Được rồi, chúng ta đã hoàn thành phần hướng dẫn. Bạn có thể kiểm tra trang này để xem các thông số đào tạo khác nhau mà bạn có thể điều chỉnh.
Nếu bạn có tập dữ liệu tin tức giả tùy chỉnh để tinh chỉnh, bạn chỉ cần chuyển danh sách các mẫu cho trình mã hóa như chúng tôi đã làm, bạn sẽ không thay đổi bất kỳ mã nào khác sau đó.
Kiểm tra mã hoàn chỉnh tại đây hoặc môi trường Colab tại đây .